Index: llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp +++ llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -26,6 +26,7 @@ #include "llvm/IR/PatternMatch.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Utils/Local.h" using namespace llvm; @@ -772,6 +773,15 @@ SimpleIVUsers.pop_back_val(); Instruction *UseInst = UseOper.first; + // If a user of the IndVar is trivially dead, we prefer just to mark it dead + // rather than try to do some complex analysis or transformation (such as + // widening) basing on it. + // TODO: Propagate TLI and pass it here to handle more cases. + if (isInstructionTriviallyDead(UseInst, /* TLI */ nullptr)) { + DeadInsts.emplace_back(UseInst); + continue; + } + // Bypass back edges to avoid extra work. if (UseInst == CurrIV) continue; Index: llvm/trunk/test/Analysis/ScalarEvolution/2012-05-29-MulAddRec.ll =================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/2012-05-29-MulAddRec.ll +++ llvm/trunk/test/Analysis/ScalarEvolution/2012-05-29-MulAddRec.ll @@ -8,6 +8,8 @@ ; ; PR12929: cast() argument of incompatible type +declare void @use(i8 %x) + ; CHECK: @func ; CHECK: for.cond: ; CHECK: %inc1 = phi i8 [ 0, %entry ], [ %0, %for.body ] @@ -33,6 +35,7 @@ %indvars.iv = phi i8 [ %indvars.iv.next, %for.cond.loopexit ], [ 10, %entry ] %mul3 = phi i8 [ undef, %entry ], [ %mul.lcssa, %for.cond.loopexit ] %inc1 = phi i8 [ 0, %entry ], [ %0, %for.cond.loopexit ] + call void @use(i8 %inc1) br label %for.body for.body: ; preds = %for.body, %for.cond @@ -40,6 +43,7 @@ %mul45 = phi i8 [ %mul3, %for.cond ], [ %mul, %for.body ] %inc = add i8 %inc26, 1 %mul = mul i8 %inc26, %mul45 + call void @use(i8 %inc) %exitcond = icmp ne i8 %inc, %indvars.iv br i1 %exitcond, label %for.body, label %for.cond.loopexit } Index: llvm/trunk/test/Analysis/ScalarEvolution/guards.ll =================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/guards.ll +++ llvm/trunk/test/Analysis/ScalarEvolution/guards.ll @@ -10,6 +10,8 @@ declare void @llvm.experimental.guard(i1, ...) +declare void @use(i64 %x) + define void @test_1(i1* %cond_buf, i32* %len_buf) { ; CHECK-LABEL: @test_1( entry: @@ -60,6 +62,7 @@ %iv.inc = add i32 %iv, 1 %iv.sext = sext i32 %iv to i64 + call void @use(i64 %iv.sext) %iv.inc.cmp = icmp slt i32 %iv.inc, %len call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] Index: llvm/trunk/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll =================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll +++ llvm/trunk/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll @@ -5,6 +5,8 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +declare void @use(i64 %x) + define void @test() nounwind { entry: br i1 undef, label %for.body11, label %for.end285 @@ -26,15 +28,19 @@ %add = add nsw i32 %i2.19, 1 %add.idxprom = sext i32 %add to i64 + call void @use(i64 %add.idxprom) %sub = sub nsw i32 %i2.19, 2 %sub.idxprom = sext i32 %sub to i64 + call void @use(i64 %sub.idxprom) %sub.neg = sub nsw i32 4, %i2.19 %sub.neg.idxprom = sext i32 %sub.neg to i64 + call void @use(i64 %sub.neg.idxprom) %mul = mul nsw i32 %i2.19, 8 %mul.idxprom = sext i32 %mul to i64 + call void @use(i64 %mul.idxprom) %add249 = add nsw i32 %i2.19, %shl132 br label %for.body170 Index: llvm/trunk/test/Transforms/IndVarSimplify/iv-widen.ll =================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/iv-widen.ll +++ llvm/trunk/test/Transforms/IndVarSimplify/iv-widen.ll @@ -7,10 +7,12 @@ target triple = "x86_64-apple-darwin" +declare void @use(i64 %x) + ; CHECK-LABEL: @loop_0 ; CHECK-LABEL: B18: ; Only one phi now. -; CHECK: phi +; CHECK: phi i64 ; CHECK-NOT: phi ; One trunc for the gep. ; CHECK: trunc i64 %indvars.iv to i32 @@ -24,6 +26,37 @@ B18: ; preds = %B24, %Prologue %.02 = phi i32 [ 0, %Prologue ], [ %tmp33, %B24 ] %tmp23 = zext i32 %.02 to i64 + call void @use(i64 %tmp23) + %tmp33 = add i32 %.02, 1 + %o = getelementptr i32, i32* %a, i32 %.02 + %v = load i32, i32* %o + %t = icmp eq i32 %v, 0 + br i1 %t, label %exit24, label %B24 + +B24: ; preds = %B18 + %t2 = icmp eq i32 %tmp33, 20 + br i1 %t2, label %B6, label %B18 + +B6: ; preds = %Prologue + ret void + +exit24: ; preds = %B18 + call void @dummy(i32 %.02) + unreachable +} + +; Make sure that dead zext is removed and no widening happens. +; CHECK-LABEL: @loop_0.dead +; CHECK: phi i32 +; CHECK-NOT: zext +; CHECK-NOT: trunc +define void @loop_0.dead(i32* %a) { +Prologue: + br i1 undef, label %B18, label %B6 + +B18: ; preds = %B24, %Prologue + %.02 = phi i32 [ 0, %Prologue ], [ %tmp33, %B24 ] + %tmp23 = zext i32 %.02 to i64 %tmp33 = add i32 %.02, 1 %o = getelementptr i32, i32* %a, i32 %.02 %v = load i32, i32* %o Index: llvm/trunk/test/Transforms/IndVarSimplify/lftr-reuse.ll =================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/lftr-reuse.ll +++ llvm/trunk/test/Transforms/IndVarSimplify/lftr-reuse.ll @@ -6,6 +6,8 @@ ; Perform LFTR using the original pointer-type IV. +declare void @use(double %x) + ; for(char* p = base; p < base + n; ++p) { ; *p = p-base; ; } @@ -102,9 +104,11 @@ %diagidxw = sext i32 %diagidx to i64 %matrixp = getelementptr inbounds [0 x double], [0 x double]* %matrix, i32 0, i64 %diagidxw %v1 = load double, double* %matrixp + call void @use(double %v1) %iw = sext i32 %i to i64 %vectorp = getelementptr inbounds [0 x double], [0 x double]* %vector, i32 0, i64 %iw %v2 = load double, double* %vectorp + call void @use(double %v2) %row.inc = add nsw i32 %rowidx, %ilead %i.inc = add nsw i32 %i, 1 %cmp196 = icmp slt i32 %i.inc, %irow @@ -125,7 +129,6 @@ ; CHECK-NOT: add ; CHECK: loop: ; CHECK: phi i64 -; CHECK: phi i64 ; CHECK-NOT: phi ; CHECK: icmp slt ; CHECK: br i1 Index: llvm/trunk/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll =================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll +++ llvm/trunk/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll @@ -293,6 +293,8 @@ ret void } +declare void @use(i1 %x) + ; check that we handle conditions with loop invariant operands which ; *aren't* in the header - this is a very rare and fragile case where ; we have a "loop" which is known to run exactly one iteration but @@ -320,6 +322,7 @@ br i1 true, label %exit, label %loop exit: + call void @use(i1 %cmp) ret void } Index: llvm/trunk/test/Transforms/IndVarSimplify/no-iv-rewrite.ll =================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/no-iv-rewrite.ll +++ llvm/trunk/test/Transforms/IndVarSimplify/no-iv-rewrite.ll @@ -357,6 +357,9 @@ ret void } +declare void @use32(i32 %x) +declare void @use64(i64 %x) + ; Test a widened IV that is used by a phi on different paths within the loop. ; ; CHECK: for.body: @@ -385,10 +388,12 @@ if.then97: %idxprom100 = sext i32 %iv to i64 + call void @use64(i64 %idxprom100) br label %for.inc for.inc: %kmin.1 = phi i32 [ %iv, %if.then33 ], [ 0, %if.then ], [ %iv, %if.then97 ], [ 0, %if.else ] + call void @use32(i32 %kmin.1) %inc = add nsw i32 %iv, 1 br i1 undef, label %for.body, label %for.end Index: llvm/trunk/test/Transforms/IndVarSimplify/pr25578.ll =================================================================== --- llvm/trunk/test/Transforms/IndVarSimplify/pr25578.ll +++ llvm/trunk/test/Transforms/IndVarSimplify/pr25578.ll @@ -1,6 +1,8 @@ ; RUN: opt < %s -indvars -S | FileCheck %s target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +declare void @use(i64 %x) + ; CHECK-LABEL: @foo define void @foo() { entry: @@ -15,6 +17,7 @@ L2_header: %i = phi i32 [ 0, %L1_header ], [ %i_next, %L2_latch ] %i_prom = sext i32 %i to i64 + call void @use(i64 %i_prom) br label %L3_header L3_header: