InstCombine: move hasOneUse check to the top of foldICmpAddConstant

There were two combines not covered by the check before now, neither of which
actually differed from normal in the benefit analysis.

The most recent seems to be because it was just added at the top of the
function (naturally). The older is from way back in 2008 (r46687) when we just
didn't put those checks in so routinely, and has been diligently maintained
since.

llvm-svn: 341831
This commit is contained in:
Tim Northover 2018-09-10 14:26:44 +00:00
parent 0b77d03d80
commit 12c1f7675f
6 changed files with 26 additions and 9 deletions

View File

@ -2337,6 +2337,9 @@ Instruction *InstCombiner::foldICmpAddConstant(ICmpInst &Cmp,
Type *Ty = Add->getType(); Type *Ty = Add->getType();
CmpInst::Predicate Pred = Cmp.getPredicate(); CmpInst::Predicate Pred = Cmp.getPredicate();
if (!Add->hasOneUse())
return nullptr;
// If the add does not wrap, we can always adjust the compare by subtracting // If the add does not wrap, we can always adjust the compare by subtracting
// the constants. Equality comparisons are handled elsewhere. SGE/SLE/UGE/ULE // the constants. Equality comparisons are handled elsewhere. SGE/SLE/UGE/ULE
// are canonicalized to SGT/SLT/UGT/ULT. // are canonicalized to SGT/SLT/UGT/ULT.
@ -2370,9 +2373,6 @@ Instruction *InstCombiner::foldICmpAddConstant(ICmpInst &Cmp,
return new ICmpInst(ICmpInst::ICMP_UGE, X, ConstantInt::get(Ty, Lower)); return new ICmpInst(ICmpInst::ICMP_UGE, X, ConstantInt::get(Ty, Lower));
} }
if (!Add->hasOneUse())
return nullptr;
// X+C <u C2 -> (X & -C2) == C // X+C <u C2 -> (X & -C2) == C
// iff C & (C2-1) == 0 // iff C & (C2-1) == 0
// C2 is a power of 2 // C2 is a power of 2

View File

@ -8,7 +8,7 @@ define void @test() #0 {
; CHECK: for.body: ; CHECK: for.body:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ult i64 [[INDVARS_IV]], 39 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], 40
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
; CHECK: for.end: ; CHECK: for.end:
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void

View File

@ -73,6 +73,23 @@ define i1 @test4(i32 %a) {
ret i1 %c ret i1 %c
} }
define { i32, i1 } @test4multiuse(i32 %a) {
; CHECK-LABEL: @test4multiuse(
; CHECK: [[B:%.*]] = add i32 %a, -2147483644
; CHECK: [[C:%.*]] = icmp slt i32 %b, -4
; CHECK: [[TMP:%.*]] = insertvalue { i32, i1 } undef, i32 [[B]], 0
; CHECK: [[RES:%.*]] = insertvalue { i32, i1 } [[TMP]], i1 [[C]], 1
; CHECK: ret { i32, i1 } [[RES]]
%b = add i32 %a, -2147483644
%c = icmp slt i32 %b, -4
%tmp = insertvalue { i32, i1 } undef, i32 %b, 0
%res = insertvalue { i32, i1 } %tmp, i1 %c, 1
ret { i32, i1 } %res
}
define <2 x i1> @test4vec(<2 x i32> %a) { define <2 x i1> @test4vec(<2 x i32> %a) {
; CHECK-LABEL: @test4vec( ; CHECK-LABEL: @test4vec(
; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> %a, <i32 -4, i32 -4> ; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> %a, <i32 -4, i32 -4>

View File

@ -1878,7 +1878,7 @@ define void @foo4(double* %A, double* %B, i32* %trigger) {
; AVX1-NEXT: br label [[FOR_INC]] ; AVX1-NEXT: br label [[FOR_INC]]
; AVX1: for.inc: ; AVX1: for.inc:
; AVX1-NEXT: [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 16 ; AVX1-NEXT: [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 16
; AVX1-NEXT: [[CMP:%.*]] = icmp ult i64 [[INDVARS_IV]], 9984 ; AVX1-NEXT: [[CMP:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], 10000
; AVX1-NEXT: br i1 [[CMP]], label [[FOR_BODY_1:%.*]], label [[FOR_END:%.*]] ; AVX1-NEXT: br i1 [[CMP]], label [[FOR_BODY_1:%.*]], label [[FOR_END:%.*]]
; AVX1: for.end: ; AVX1: for.end:
; AVX1-NEXT: ret void ; AVX1-NEXT: ret void
@ -1920,7 +1920,7 @@ define void @foo4(double* %A, double* %B, i32* %trigger) {
; AVX2-NEXT: br label [[FOR_INC]] ; AVX2-NEXT: br label [[FOR_INC]]
; AVX2: for.inc: ; AVX2: for.inc:
; AVX2-NEXT: [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 16 ; AVX2-NEXT: [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 16
; AVX2-NEXT: [[CMP:%.*]] = icmp ult i64 [[INDVARS_IV]], 9984 ; AVX2-NEXT: [[CMP:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT]], 10000
; AVX2-NEXT: br i1 [[CMP]], label [[FOR_BODY_1:%.*]], label [[FOR_END:%.*]] ; AVX2-NEXT: br i1 [[CMP]], label [[FOR_BODY_1:%.*]], label [[FOR_END:%.*]]
; AVX2: for.end: ; AVX2: for.end:
; AVX2-NEXT: ret void ; AVX2-NEXT: ret void
@ -2119,7 +2119,7 @@ define void @foo4(double* %A, double* %B, i32* %trigger) {
; AVX512-NEXT: br label [[FOR_INC_3]] ; AVX512-NEXT: br label [[FOR_INC_3]]
; AVX512: for.inc.3: ; AVX512: for.inc.3:
; AVX512-NEXT: [[INDVARS_IV_NEXT_3]] = add nsw i64 [[INDVARS_IV]], 64 ; AVX512-NEXT: [[INDVARS_IV_NEXT_3]] = add nsw i64 [[INDVARS_IV]], 64
; AVX512-NEXT: [[CMP_3:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT_2]], 9984 ; AVX512-NEXT: [[CMP_3:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT_3]], 10000
; AVX512-NEXT: br i1 [[CMP_3]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop !52 ; AVX512-NEXT: br i1 [[CMP_3]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop !52
; ;
entry: entry:

View File

@ -12,7 +12,7 @@ define i32 @foo(i32* nocapture %A, i32* nocapture %B, i32 %n) {
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64 ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1 ; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP0]], 3 ; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 4
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]]
; CHECK: vector.memcheck: ; CHECK: vector.memcheck:
; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[N]], -1 ; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[N]], -1

View File

@ -18,7 +18,7 @@ define i32 @foo(float* nocapture %a, float* nocapture %b, i32 %n) nounwind uwtab
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1, !dbg !9 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1, !dbg !9
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !dbg !9 ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !dbg !9
; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1, !dbg !9 ; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1, !dbg !9
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP0]], 3, !dbg !9 ; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 4, !dbg !9
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]], !dbg !9 ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]], !dbg !9
; CHECK: vector.memcheck: ; CHECK: vector.memcheck:
; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[N]], -1, !dbg !9 ; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[N]], -1, !dbg !9