forked from OSchip/llvm-project
[SimplifyIndVars] Ignore dead users
IndVarSimplify sometimes makes transforms basing on users that are trivially dead. In particular, if DCE wasn't run before it, there may be a dead `sext/zext` in loop that will trigger widening transforms, however it makes no sense to do it. This patch teaches IndVarsSimplify ignore the mist trivial cases of that. Differential Revision: https://reviews.llvm.org/D47974 Reviewed By: sanjoy llvm-svn: 334567
This commit is contained in:
parent
8472ec9663
commit
0ed79620c6
|
@ -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 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) {
|
|||
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;
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
;
|
||||
; PR12929: cast<Ty>() 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 @@ for.cond: ; preds = %for.cond.loopexit,
|
|||
%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 @@ for.body: ; preds = %for.body, %for.cond
|
|||
%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
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ target datalayout = "n8:16:32:64"
|
|||
|
||||
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 @@ loop:
|
|||
%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"() ]
|
||||
|
|
|
@ -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 @@ for.body170: ; preds = %for.body170, %for.b
|
|||
|
||||
%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
|
||||
|
|
|
@ -7,10 +7,12 @@ target datalayout = "n8:16:32:64"
|
|||
|
||||
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
|
||||
|
@ -21,6 +23,37 @@ define void @loop_0(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
|
||||
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
|
||||
|
|
|
@ -6,6 +6,8 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
|
|||
|
||||
; 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 @@ loop:
|
|||
%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 @@ entry:
|
|||
; CHECK-NOT: add
|
||||
; CHECK: loop:
|
||||
; CHECK: phi i64
|
||||
; CHECK: phi i64
|
||||
; CHECK-NOT: phi
|
||||
; CHECK: icmp slt
|
||||
; CHECK: br i1
|
||||
|
|
|
@ -293,6 +293,8 @@ for.end: ; preds = %if.end, %entry
|
|||
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 @@ latch:
|
|||
br i1 true, label %exit, label %loop
|
||||
|
||||
exit:
|
||||
call void @use(i1 %cmp)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
|
|
@ -357,6 +357,9 @@ exit:
|
|||
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.else:
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -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 @@ L1_header:
|
|||
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:
|
||||
|
|
Loading…
Reference in New Issue