From 65dc78d63ee2eb20fbed54401091f08a685ef8c1 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 22 Feb 2022 17:53:14 +0100 Subject: [PATCH] [InstCombine] Remove one-use limitation from X-Y==0 fold This one-use limitation is artificial, we do not increase instruction count if we perform the fold with multiple uses. The motivating case is shown in @sub_eq_zero_select, where the one-use limitation causes us to miss a subsequent select fold. I believe the backend is pretty good about reusing flag-producing subs for cmps with same operands, so I think doing this is fine. Differential Revision: https://reviews.llvm.org/D120337 --- .../InstCombine/InstCombineCompares.cpp | 10 ++-- llvm/test/Transforms/InstCombine/icmp-sub.ll | 8 +-- .../InstCombine/prevent-cmp-merge.ll | 6 +- ...ult-of-usub-is-non-zero-and-no-overflow.ll | 56 +++++++++---------- 4 files changed, 39 insertions(+), 41 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 13540a77b511..eab4aa93df48 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2593,6 +2593,11 @@ Instruction *InstCombinerImpl::foldICmpSubConstant(ICmpInst &Cmp, !subWithOverflow(SubResult, *C2, C, Cmp.isSigned())) return new ICmpInst(SwappedPred, Y, ConstantInt::get(Ty, SubResult)); + // X - Y == 0 --> X == Y. + // X - Y != 0 --> X != Y. + if (Cmp.isEquality() && C.isZero()) + return new ICmpInst(Pred, X, Y); + // The following transforms are only worth it if the only user of the subtract // is the icmp. // TODO: This is an artificial restriction for all of the transforms below @@ -2600,11 +2605,6 @@ Instruction *InstCombinerImpl::foldICmpSubConstant(ICmpInst &Cmp, if (!Sub->hasOneUse()) return nullptr; - // X - Y == 0 --> X == Y. - // X - Y != 0 --> X != Y. - if (Cmp.isEquality() && C.isZero()) - return new ICmpInst(Pred, X, Y); - if (Sub->hasNoSignedWrap()) { // (icmp sgt (sub nsw X, Y), -1) -> (icmp sge X, Y) if (Pred == ICmpInst::ICMP_SGT && C.isAllOnes()) diff --git a/llvm/test/Transforms/InstCombine/icmp-sub.ll b/llvm/test/Transforms/InstCombine/icmp-sub.ll index 2efa2bbe269a..0541f2f0f136 100644 --- a/llvm/test/Transforms/InstCombine/icmp-sub.ll +++ b/llvm/test/Transforms/InstCombine/icmp-sub.ll @@ -467,7 +467,7 @@ define i1 @sub_eq_zero_use(i32 %x, i32 %y) { ; CHECK-LABEL: @sub_eq_zero_use( ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: call void @use(i32 [[SUB]]) -; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[SUB]], 0 +; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X]], [[Y]] ; CHECK-NEXT: ret i1 [[R]] ; %sub = sub i32 %x, %y @@ -480,7 +480,7 @@ define <2 x i1> @sub_ne_zero_use(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @sub_ne_zero_use( ; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x i8> [[SUB]]) -; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[SUB]], zeroinitializer +; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[X]], [[Y]] ; CHECK-NEXT: ret <2 x i1> [[R]] ; %sub = sub <2 x i8> %x, %y @@ -493,9 +493,7 @@ define i32 @sub_eq_zero_select(i32 %a, i32 %b, i32* %p) { ; CHECK-LABEL: @sub_eq_zero_select( ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: store i32 [[SUB]], i32* [[P:%.*]], align 4 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SUB]], 0 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]] -; CHECK-NEXT: ret i32 [[SEL]] +; CHECK-NEXT: ret i32 [[B]] ; %sub = sub i32 %a, %b store i32 %sub, i32* %p diff --git a/llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll b/llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll index 23dfb956263c..cd05022b0d35 100644 --- a/llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll +++ b/llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll @@ -56,7 +56,7 @@ define zeroext i1 @test2(i32 %lhs, i32 %rhs) { define zeroext i1 @test3(i32 %lhs, i32 %rhs) { ; CHECK-LABEL: @test3( ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[LHS:%.*]], [[RHS:%.*]] -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[SUB]], 0 +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[LHS]], [[RHS]] ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SUB]], 31 ; CHECK-NEXT: [[SEL:%.*]] = or i1 [[CMP1]], [[CMP2]] ; CHECK-NEXT: ret i1 [[SEL]] @@ -72,9 +72,9 @@ define zeroext i1 @test3(i32 %lhs, i32 %rhs) { define zeroext i1 @test3_logical(i32 %lhs, i32 %rhs) { ; CHECK-LABEL: @test3_logical( ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[LHS:%.*]], [[RHS:%.*]] -; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[SUB]], 0 +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[LHS]], [[RHS]] ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SUB]], 31 -; CHECK-NEXT: [[SEL:%.*]] = or i1 [[CMP1]], [[CMP2]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]] ; CHECK-NEXT: ret i1 [[SEL]] ; diff --git a/llvm/test/Transforms/InstCombine/result-of-usub-is-non-zero-and-no-overflow.ll b/llvm/test/Transforms/InstCombine/result-of-usub-is-non-zero-and-no-overflow.ll index d81d26c25a52..300fa0c49c88 100644 --- a/llvm/test/Transforms/InstCombine/result-of-usub-is-non-zero-and-no-overflow.ll +++ b/llvm/test/Transforms/InstCombine/result-of-usub-is-non-zero-and-no-overflow.ll @@ -22,7 +22,7 @@ define i1 @t0_noncanonical_ignoreme(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -43,7 +43,7 @@ define i1 @t0_noncanonical_ignoreme_logical(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -64,7 +64,7 @@ define i1 @t1(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -85,7 +85,7 @@ define i1 @t1_logical(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -105,7 +105,7 @@ define i1 @t1_strict(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: ret i1 [[NO_UNDERFLOW]] ; @@ -125,7 +125,7 @@ define i1 @t1_strict_logical(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: ret i1 [[NO_UNDERFLOW]] ; @@ -201,7 +201,7 @@ define i1 @t3_commutability0(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -222,7 +222,7 @@ define i1 @t3_commutability0_logical(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -242,7 +242,7 @@ define i1 @t4_commutability1(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -263,7 +263,7 @@ define i1 @t4_commutability1_logical(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -283,7 +283,7 @@ define i1 @t5_commutability2(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -304,7 +304,7 @@ define i1 @t5_commutability2_logical(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -382,7 +382,7 @@ define i1 @t7(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[UNDERFLOW:%.*]] = icmp ult i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[UNDERFLOW]]) -; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -403,7 +403,7 @@ define i1 @t7_logical(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[UNDERFLOW:%.*]] = icmp ult i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[UNDERFLOW]]) -; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -423,7 +423,7 @@ define i1 @t7_nonstrict(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[UNDERFLOW:%.*]] = icmp ule i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[UNDERFLOW]]) -; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NULL]]) ; CHECK-NEXT: ret i1 [[UNDERFLOW]] ; @@ -443,7 +443,7 @@ define i1 @t7_nonstrict_logical(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[UNDERFLOW:%.*]] = icmp ule i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[UNDERFLOW]]) -; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NULL]]) ; CHECK-NEXT: ret i1 [[UNDERFLOW]] ; @@ -511,7 +511,7 @@ define i1 @t9_commutative(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[UNDERFLOW:%.*]] = icmp ult i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[UNDERFLOW]]) -; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -532,7 +532,7 @@ define i1 @t9_commutative_logical(i8 %base, i8 %offset) { ; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]]) ; CHECK-NEXT: [[UNDERFLOW:%.*]] = icmp ult i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[UNDERFLOW]]) -; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NULL:%.*]] = icmp eq i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i8 [[BASE]], [[OFFSET]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -556,7 +556,7 @@ define i1 @t10(i64 %base, i64* nonnull %offsetptr) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ule i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -580,7 +580,7 @@ define i1 @t10_logical(i64 %base, i64* nonnull %offsetptr) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ule i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -603,7 +603,7 @@ define i1 @t11_commutative(i64 %base, i64* nonnull %offsetptr) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ule i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -627,7 +627,7 @@ define i1 @t11_commutative_logical(i64 %base, i64* nonnull %offsetptr) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ule i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -651,7 +651,7 @@ define i1 @t12(i64 %base, i64* nonnull %offsetptr) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ugt i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp eq i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp eq i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -675,7 +675,7 @@ define i1 @t12_logical(i64 %base, i64* nonnull %offsetptr) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ugt i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp eq i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp eq i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -698,7 +698,7 @@ define i1 @t13(i64 %base, i64* nonnull %offsetptr) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ugt i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp eq i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp eq i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -722,7 +722,7 @@ define i1 @t13_logical(i64 %base, i64* nonnull %offsetptr) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ugt i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp eq i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp eq i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i64 [[OFFSET]], [[BASE]] ; CHECK-NEXT: ret i1 [[TMP1]] @@ -745,7 +745,7 @@ define i1 @t14_bad(i64 %base, i64 %offset) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ult i64 [[ADJUSTED]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]] ; CHECK-NEXT: ret i1 [[R]] @@ -766,7 +766,7 @@ define i1 @t14_bad_logical(i64 %base, i64 %offset) { ; CHECK-NEXT: call void @use64(i64 [[ADJUSTED]]) ; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ult i64 [[ADJUSTED]], [[BASE]] ; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]]) -; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[ADJUSTED]], 0 +; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i64 [[BASE]], [[OFFSET]] ; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]]) ; CHECK-NEXT: [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]] ; CHECK-NEXT: ret i1 [[R]]