From b22910daab95be1ebc6ab8a74190e38130b0e6ef Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 7 Sep 2020 10:26:42 -0400 Subject: [PATCH] [InstCombine] erase instructions leading up to unreachable Normal dead code elimination ignores assume intrinsics, so we fail to delete assumes that are not meaningful (and potentially worse if they cause conflicts with other assumptions). The motivating example in https://llvm.org/PR47416 suggests that we might have problems upstream from here (difference between C and C++), but this should be a cheap way to make sure we remove more dead code. Differential Revision: https://reviews.llvm.org/D87149 --- llvm/lib/Transforms/InstCombine/InstCombineInternal.h | 1 + llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 13 +++++++++++++ llvm/test/Transforms/InstCombine/assume.ll | 10 +--------- llvm/test/Transforms/InstCombine/pr33689_same_bitwidth.ll | 2 -- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index a03cb5e..62ee7d0 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -159,6 +159,7 @@ public: Instruction *visitFenceInst(FenceInst &FI); Instruction *visitSwitchInst(SwitchInst &SI); Instruction *visitReturnInst(ReturnInst &RI); + Instruction *visitUnreachableInst(UnreachableInst &I); Instruction * foldAggregateConstructionIntoAggregateReuse(InsertValueInst &OrigIVI); Instruction *visitInsertValueInst(InsertValueInst &IV); diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 178e9a4..0ca2568 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2798,6 +2798,19 @@ Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) { return nullptr; } +Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) { + // Try to remove the previous instruction if it must lead to unreachable. + // This includes instructions like stores and "llvm.assume" that may not get + // removed by simple dead code elimination. + Instruction *Prev = I.getPrevNonDebugInstruction(); + if (Prev && !Prev->isEHPad() && + isGuaranteedToTransferExecutionToSuccessor(Prev)) { + eraseInstFromFunction(*Prev); + return &I; + } + return nullptr; +} + Instruction *InstCombinerImpl::visitUnconditionalBranchInst(BranchInst &BI) { assert(BI.isUnconditional() && "Only for unconditional branches."); diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll index b55b1c2..8ca24ca 100644 --- a/llvm/test/Transforms/InstCombine/assume.ll +++ b/llvm/test/Transforms/InstCombine/assume.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -instcombine -S | FileCheck %s +; RUN: opt < %s -instcombine -S -instcombine-infinite-loop-threshold=2 | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -543,7 +543,6 @@ define i8 @conflicting_assumptions(i8 %x){ define void @PR36270(i32 %b) { ; CHECK-LABEL: @PR36270( -; CHECK-NEXT: tail call void @llvm.assume(i1 false) ; CHECK-NEXT: unreachable ; %B7 = xor i32 -1, 2147483647 @@ -573,8 +572,6 @@ define i32 @unreachable_assume(i32 %x, i32 %y) { ; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP3]]) ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: -; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i32 [[X]], 2 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP4]]) ; CHECK-NEXT: unreachable ; entry: @@ -612,11 +609,6 @@ define i32 @unreachable_assumes_and_store(i32 %x, i32 %y, i32* %p) { ; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP3]]) ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: -; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i32 [[X]], 2 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP4]]) -; CHECK-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[Y]], 42 -; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP5]]) -; CHECK-NEXT: store i32 [[X]], i32* [[P:%.*]], align 4 ; CHECK-NEXT: unreachable ; entry: diff --git a/llvm/test/Transforms/InstCombine/pr33689_same_bitwidth.ll b/llvm/test/Transforms/InstCombine/pr33689_same_bitwidth.ll index 0ffd41d..d533703 100644 --- a/llvm/test/Transforms/InstCombine/pr33689_same_bitwidth.ll +++ b/llvm/test/Transforms/InstCombine/pr33689_same_bitwidth.ll @@ -17,8 +17,6 @@ define void @f(i1 %cond) { ; CHECK-NEXT: [[T12_SUB:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[T12]], i16 0, i16 0 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: -; CHECK-NEXT: [[T8:%.*]] = ptrtoint [2 x i32]* [[T12]] to i16 -; CHECK-NEXT: store i16 [[T8]], i16* @a, align 2 ; CHECK-NEXT: unreachable ; CHECK: bb2: ; CHECK-NEXT: [[T9:%.*]] = load i16*, i16** @b, align 2 -- 2.7.4