diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2748,6 +2748,14 @@ return new ICmpInst(ICmpInst::ICMP_NE, Builder.CreateAnd(X, ~C), ConstantExpr::getNeg(cast(Y))); + // The range test idiom can use either ult or ugt. Arbitrarily canonicalize + // to the ult form. + // X+C2 >u C -> X+(C2-C-1) (Sel1)) { + Pred0 = ICmpInst::getInversePredicate(Pred0); + std::swap(X, Sel1); + } + + // Canonicalize Cmp0 into ult or uge. // FIXME: we shouldn't care about lanes that are 'undef' in the end? - switch (Cmp0.getPredicate()) { + switch (Pred0) { case ICmpInst::Predicate::ICMP_ULT: + case ICmpInst::Predicate::ICMP_UGE: // Although icmp ult %x, 0 is an unusual thing to try and should generally // have been simplified, it does not verify with undef inputs so ensure we // are not in a strange state. @@ -1316,25 +1324,16 @@ return nullptr; break; // Great! case ICmpInst::Predicate::ICMP_ULE: - // We'd have to increment C0 by one, and for that it must not have all-ones - // element, but then it would have been canonicalized to 'ult' before - // we get here. So we can't do anything useful with 'ule'. - return nullptr; case ICmpInst::Predicate::ICMP_UGT: - // We want to canonicalize it to 'ult', so we'll need to increment C0, - // which again means it must not have any all-ones elements. + // We want to canonicalize it to 'ult' or 'uge', so we'll need to increment + // C0, which again means it must not have any all-ones elements. if (!match(C0, m_SpecificInt_ICMP( ICmpInst::Predicate::ICMP_NE, APInt::getAllOnes(C0->getType()->getScalarSizeInBits())))) return nullptr; // Can't do, have all-ones element[s]. C0 = InstCombiner::AddOne(C0); - std::swap(X, Sel1); break; - case ICmpInst::Predicate::ICMP_UGE: - // The only way we'd get this predicate if this `icmp` has extra uses, - // but then we won't be able to do this fold. - return nullptr; default: return nullptr; // Unknown predicate. } @@ -1407,6 +1406,8 @@ // The thresholds of this clamp-like pattern. auto *ThresholdLowIncl = ConstantExpr::getNeg(C1); auto *ThresholdHighExcl = ConstantExpr::getSub(C0, C1); + if (Pred0 == ICmpInst::Predicate::ICMP_UGE) + std::swap(ThresholdLowIncl, ThresholdHighExcl); // The fold has a precondition 1: C2 s>= ThresholdLow auto *Precond1 = ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_SGE, C2, diff --git a/llvm/test/CodeGen/BPF/adjust-opt-icmp1.ll b/llvm/test/CodeGen/BPF/adjust-opt-icmp1.ll --- a/llvm/test/CodeGen/BPF/adjust-opt-icmp1.ll +++ b/llvm/test/CodeGen/BPF/adjust-opt-icmp1.ll @@ -39,10 +39,11 @@ ; CHECK: if [[REG2]] s> [[REG1]] goto ; CHECK: if [[REG1]] s> 7 goto -; CHECK-DISABLE: [[REG1:r[0-9]+]] += -1 +; CHECK-DISABLE: [[REG1:r[0-9]+]] += -8 ; CHECK-DISABLE: [[REG1]] <<= 32 ; CHECK-DISABLE: [[REG1]] >>= 32 -; CHECK-DISABLE: if [[REG1]] > 6 goto +; CHECK-DISABLE: [[REG2:r[0-9]+]] = 4294967289 +; CHECK-DISABLE: if [[REG2]] > [[REG1]] goto lor.lhs.false: ; preds = %entry %2 = load i32, i32* %ret, align 4, !tbaa !2 diff --git a/llvm/test/CodeGen/BPF/adjust-opt-icmp2.ll b/llvm/test/CodeGen/BPF/adjust-opt-icmp2.ll --- a/llvm/test/CodeGen/BPF/adjust-opt-icmp2.ll +++ b/llvm/test/CodeGen/BPF/adjust-opt-icmp2.ll @@ -37,10 +37,11 @@ ; CHECK: if [[REG2]] s> [[REG1]] goto ; CHECK: if [[REG1]] s> 7 goto -; CHECK-DISABLE: [[REG1:r[0-9]+]] += -1 +; CHECK-DISABLE: [[REG1:r[0-9]+]] += -8 ; CHECK-DISABLE: [[REG1]] <<= 32 ; CHECK-DISABLE: [[REG1]] >>= 32 -; CHECK-DISABLE: if [[REG1]] > 6 goto +; CHECK-DISABLE: [[REG2:r[0-9]+]] = 4294967289 +; CHECK-DISABLE: if [[REG2]] > [[REG1]] goto if.then: ; preds = %entry store i32 0, i32* %retval, align 4 diff --git a/llvm/test/Transforms/InstCombine/2006-12-15-Range-Test.ll b/llvm/test/Transforms/InstCombine/2006-12-15-Range-Test.ll --- a/llvm/test/Transforms/InstCombine/2006-12-15-Range-Test.ll +++ b/llvm/test/Transforms/InstCombine/2006-12-15-Range-Test.ll @@ -18,9 +18,9 @@ ; CHECK: cond_true: ; CHECK-NEXT: [[TMP15:%.*]] = getelementptr [17 x i32], [17 x i32]* @r, i32 0, i32 [[TMP12_RELOAD:%.*]] ; CHECK-NEXT: [[TMP16]] = load i32, i32* [[TMP15]], align 4 -; CHECK-NEXT: [[TMP16_OFF:%.*]] = add i32 [[TMP16]], 31 -; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[TMP16_OFF]], 62 -; CHECK-NEXT: br i1 [[TMP0]], label [[BB27_EXITSTUB:%.*]], label [[COND_NEXT23_EXITSTUB:%.*]] +; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[TMP16]], -32 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], -63 +; CHECK-NEXT: br i1 [[TMP1]], label [[BB27_EXITSTUB:%.*]], label [[COND_NEXT23_EXITSTUB:%.*]] ; newFuncRoot: br label %cond_true @@ -55,9 +55,9 @@ ; CHECK: cond_true: ; CHECK-NEXT: [[TMP15:%.*]] = getelementptr [17 x i32], [17 x i32]* @r, i32 0, i32 [[TMP12_RELOAD:%.*]] ; CHECK-NEXT: [[TMP16]] = load i32, i32* [[TMP15]], align 4 -; CHECK-NEXT: [[TMP16_OFF:%.*]] = add i32 [[TMP16]], 31 -; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[TMP16_OFF]], 62 -; CHECK-NEXT: br i1 [[TMP0]], label [[BB27_EXITSTUB:%.*]], label [[COND_NEXT23_EXITSTUB:%.*]] +; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[TMP16]], -32 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[TMP0]], -63 +; CHECK-NEXT: br i1 [[TMP1]], label [[BB27_EXITSTUB:%.*]], label [[COND_NEXT23_EXITSTUB:%.*]] ; newFuncRoot: br label %cond_true diff --git a/llvm/test/Transforms/InstCombine/2007-03-21-SignedRangeTest.ll b/llvm/test/Transforms/InstCombine/2007-03-21-SignedRangeTest.ll --- a/llvm/test/Transforms/InstCombine/2007-03-21-SignedRangeTest.ll +++ b/llvm/test/Transforms/InstCombine/2007-03-21-SignedRangeTest.ll @@ -5,9 +5,9 @@ define i1 @test(i32 %tmp6) { ; CHECK-LABEL: @test( -; CHECK-NEXT: [[TMP6_OFF:%.*]] = add i32 %tmp6, 83 -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[TMP6_OFF]], 11 -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP6:%.*]], 71 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -12 +; CHECK-NEXT: ret i1 [[TMP2]] ; %tmp7 = sdiv i32 %tmp6, 12 icmp ne i32 %tmp7, -6 @@ -16,9 +16,9 @@ define <2 x i1> @test_vec(<2 x i32> %tmp6) { ; CHECK-LABEL: @test_vec( -; CHECK-NEXT: [[TMP6_OFF:%.*]] = add <2 x i32> %tmp6, -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt <2 x i32> [[TMP6_OFF]], -; CHECK-NEXT: ret <2 x i1> [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[TMP6:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], +; CHECK-NEXT: ret <2 x i1> [[TMP2]] ; %tmp7 = sdiv <2 x i32> %tmp6, icmp ne <2 x i32> %tmp7, diff --git a/llvm/test/Transforms/InstCombine/2008-08-05-And.ll b/llvm/test/Transforms/InstCombine/2008-08-05-And.ll --- a/llvm/test/Transforms/InstCombine/2008-08-05-And.ll +++ b/llvm/test/Transforms/InstCombine/2008-08-05-And.ll @@ -8,10 +8,10 @@ ; CHECK-NEXT: br label [[BB:%.*]] ; CHECK: bb: ; CHECK-NEXT: [[L1:%.*]] = load i8, i8* [[X:%.*]], align 1 -; CHECK-NEXT: [[S1:%.*]] = add i8 [[L1]], -6 -; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[S1]], 2 -; CHECK-NEXT: [[S2:%.*]] = add i8 [[L1]], -10 -; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[S2]], 2 +; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[L1]], -9 +; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[TMP0]], -3 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[L1]], -13 +; CHECK-NEXT: [[C2:%.*]] = icmp ult i8 [[TMP1]], -3 ; CHECK-NEXT: [[A1:%.*]] = and i1 [[C1]], [[C2]] ; CHECK-NEXT: br i1 [[A1]], label [[INCOMPATIBLE:%.*]], label [[OKAY:%.*]] ; CHECK: okay: @@ -45,10 +45,10 @@ ; CHECK-NEXT: br label [[BB:%.*]] ; CHECK: bb: ; CHECK-NEXT: [[L1:%.*]] = load i8, i8* [[X:%.*]], align 1 -; CHECK-NEXT: [[S1:%.*]] = add i8 [[L1]], -6 -; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[S1]], 2 -; CHECK-NEXT: [[S2:%.*]] = add i8 [[L1]], -10 -; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[S2]], 2 +; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[L1]], -9 +; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[TMP0]], -3 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[L1]], -13 +; CHECK-NEXT: [[C2:%.*]] = icmp ult i8 [[TMP1]], -3 ; CHECK-NEXT: [[A1:%.*]] = and i1 [[C1]], [[C2]] ; CHECK-NEXT: br i1 [[A1]], label [[INCOMPATIBLE:%.*]], label [[OKAY:%.*]] ; CHECK: okay: diff --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll --- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll +++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll @@ -257,8 +257,8 @@ define i1 @and_ne_with_diff_one(i32 %x) { ; CHECK-LABEL: @and_ne_with_diff_one( -; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -39 -; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[TMP1]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -41 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -2 ; CHECK-NEXT: ret i1 [[TMP2]] ; %cmp1 = icmp ne i32 %x, 40 @@ -269,8 +269,8 @@ define i1 @and_ne_with_diff_one_logical(i32 %x) { ; CHECK-LABEL: @and_ne_with_diff_one_logical( -; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -39 -; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[TMP1]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -41 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -2 ; CHECK-NEXT: ret i1 [[TMP2]] ; %cmp1 = icmp ne i32 %x, 40 @@ -308,8 +308,8 @@ define i1 @and_ne_with_diff_one_signed(i64 %x) { ; CHECK-LABEL: @and_ne_with_diff_one_signed( -; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], 1 -; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], -1 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], -2 ; CHECK-NEXT: ret i1 [[TMP2]] ; %cmp1 = icmp ne i64 %x, -1 @@ -320,8 +320,8 @@ define i1 @and_ne_with_diff_one_signed_logical(i64 %x) { ; CHECK-LABEL: @and_ne_with_diff_one_signed_logical( -; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], 1 -; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], -1 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], -2 ; CHECK-NEXT: ret i1 [[TMP2]] ; %cmp1 = icmp ne i64 %x, -1 @@ -346,8 +346,8 @@ define <2 x i1> @and_ne_with_diff_one_splatvec(<2 x i32> %x) { ; CHECK-LABEL: @and_ne_with_diff_one_splatvec( -; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt <2 x i32> [[TMP1]], +; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i1> [[TMP2]] ; %cmp1 = icmp ne <2 x i32> %x, @@ -508,9 +508,9 @@ define i1 @PR42691_5(i32 %x) { ; CHECK-LABEL: @PR42691_5( -; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -1 -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645 -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -2147483647 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -2147483646 +; CHECK-NEXT: ret i1 [[TMP2]] ; %c1 = icmp slt i32 %x, 1 %c2 = icmp eq i32 %x, 2147483647 @@ -520,9 +520,9 @@ define i1 @PR42691_5_logical(i32 %x) { ; CHECK-LABEL: @PR42691_5_logical( -; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -1 -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645 -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -2147483647 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -2147483646 +; CHECK-NEXT: ret i1 [[TMP2]] ; %c1 = icmp slt i32 %x, 1 %c2 = icmp eq i32 %x, 2147483647 @@ -532,9 +532,9 @@ define i1 @PR42691_6(i32 %x) { ; CHECK-LABEL: @PR42691_6( -; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647 -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645 -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -2147483646 +; CHECK-NEXT: ret i1 [[TMP2]] ; %c1 = icmp ult i32 %x, 2147483649 %c2 = icmp eq i32 %x, 4294967295 @@ -544,9 +544,9 @@ define i1 @PR42691_6_logical(i32 %x) { ; CHECK-LABEL: @PR42691_6_logical( -; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647 -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645 -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -2147483646 +; CHECK-NEXT: ret i1 [[TMP2]] ; %c1 = icmp ult i32 %x, 2147483649 %c2 = icmp eq i32 %x, 4294967295 diff --git a/llvm/test/Transforms/InstCombine/canonicalize-signed-truncation-check.ll b/llvm/test/Transforms/InstCombine/canonicalize-signed-truncation-check.ll --- a/llvm/test/Transforms/InstCombine/canonicalize-signed-truncation-check.ll +++ b/llvm/test/Transforms/InstCombine/canonicalize-signed-truncation-check.ll @@ -15,8 +15,8 @@ define i1 @p0(i8 %x) { ; CHECK-LABEL: @p0( -; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 4 -; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i8 [[TMP1]], 7 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -4 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[TMP1]], -8 ; CHECK-NEXT: ret i1 [[TMP2]] ; %tmp0 = shl i8 %x, 5 @@ -44,8 +44,8 @@ define <2 x i1> @p1_vec_splat(<2 x i8> %x) { ; CHECK-LABEL: @p1_vec_splat( -; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], -; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt <2 x i8> [[TMP1]], +; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <2 x i8> [[TMP1]], ; CHECK-NEXT: ret <2 x i1> [[TMP2]] ; %tmp0 = shl <2 x i8> %x, @@ -115,8 +115,8 @@ define i1 @c0() { ; CHECK-LABEL: @c0( ; CHECK-NEXT: [[X:%.*]] = call i8 @gen8() -; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], 4 -; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i8 [[TMP1]], 7 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -4 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[TMP1]], -8 ; CHECK-NEXT: ret i1 [[TMP2]] ; %x = call i8 @gen8() @@ -136,8 +136,8 @@ ; CHECK-LABEL: @n_oneuse0( ; CHECK-NEXT: [[TMP0:%.*]] = shl i8 [[X:%.*]], 5 ; CHECK-NEXT: call void @use8(i8 [[TMP0]]) -; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], 4 -; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i8 [[TMP1]], 7 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -4 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[TMP1]], -8 ; CHECK-NEXT: ret i1 [[TMP2]] ; %tmp0 = shl i8 %x, 5 diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll --- a/llvm/test/Transforms/InstCombine/icmp-add.ll +++ b/llvm/test/Transforms/InstCombine/icmp-add.ll @@ -363,8 +363,8 @@ define i1 @uge_add_nonuw(i32 %in) { ; CHECK-LABEL: @uge_add_nonuw( -; CHECK-NEXT: [[A6:%.*]] = add i32 [[IN:%.*]], 3 -; CHECK-NEXT: [[A18:%.*]] = icmp ugt i32 [[A6]], 11 +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[IN:%.*]], -9 +; CHECK-NEXT: [[A18:%.*]] = icmp ult i32 [[TMP1]], -12 ; CHECK-NEXT: ret i1 [[A18]] ; %a6 = add i32 %in, 3 @@ -785,8 +785,8 @@ define i1 @ugt_wrong_offset(i8 %a) { ; CHECK-LABEL: @ugt_wrong_offset( -; CHECK-NEXT: [[T:%.*]] = add i8 [[A:%.*]], 123 -; CHECK-NEXT: [[OV:%.*]] = icmp ugt i8 [[T]], -5 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 127 +; CHECK-NEXT: [[OV:%.*]] = icmp ult i8 [[TMP1]], 4 ; CHECK-NEXT: ret i1 [[OV]] ; %t = add i8 %a, 123 diff --git a/llvm/test/Transforms/InstCombine/icmp-sub.ll b/llvm/test/Transforms/InstCombine/icmp-sub.ll --- a/llvm/test/Transforms/InstCombine/icmp-sub.ll +++ b/llvm/test/Transforms/InstCombine/icmp-sub.ll @@ -57,8 +57,8 @@ define i1 @test_negative_nsw_and_unsigned_pred(i64 %x) { ; CHECK-LABEL: @test_negative_nsw_and_unsigned_pred( -; CHECK-NEXT: [[NOTSUB:%.*]] = add nsw i64 [[X:%.*]], -11 -; CHECK-NEXT: [[Z:%.*]] = icmp ugt i64 [[NOTSUB]], -4 +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], -8 +; CHECK-NEXT: [[Z:%.*]] = icmp ult i64 [[TMP1]], 3 ; CHECK-NEXT: ret i1 [[Z]] ; %y = sub nsw i64 10, %x diff --git a/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll b/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll --- a/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll +++ b/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll @@ -35,8 +35,8 @@ define i1 @testi16i8_ne(i16 %add) { ; CHECK-LABEL: @testi16i8_ne( -; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[ADD:%.*]], 128 -; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ugt i16 [[TMP1]], 255 +; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[ADD:%.*]], -128 +; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i16 [[TMP1]], -256 ; CHECK-NEXT: ret i1 [[CMP_NOT_I]] ; %sh = lshr i16 %add, 8 @@ -49,8 +49,8 @@ define i1 @testi16i8_ne_com(i16 %add) { ; CHECK-LABEL: @testi16i8_ne_com( -; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[ADD:%.*]], 128 -; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ugt i16 [[TMP1]], 255 +; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[ADD:%.*]], -128 +; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i16 [[TMP1]], -256 ; CHECK-NEXT: ret i1 [[CMP_NOT_I]] ; %sh = lshr i16 %add, 8 @@ -77,8 +77,8 @@ define i1 @testi64i32_ne(i64 %add) { ; CHECK-LABEL: @testi64i32_ne( -; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[ADD:%.*]], 2147483648 -; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ugt i64 [[TMP1]], 4294967295 +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[ADD:%.*]], -2147483648 +; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i64 [[TMP1]], -4294967296 ; CHECK-NEXT: ret i1 [[CMP_NOT_I]] ; %sh = lshr i64 %add, 32 diff --git a/llvm/test/Transforms/InstCombine/load-cmp.ll b/llvm/test/Transforms/InstCombine/load-cmp.ll --- a/llvm/test/Transforms/InstCombine/load-cmp.ll +++ b/llvm/test/Transforms/InstCombine/load-cmp.ll @@ -145,8 +145,8 @@ define i1 @test7(i32 %X) { ; CHECK-LABEL: @test7( -; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -1 -; CHECK-NEXT: [[R:%.*]] = icmp ugt i32 [[TMP1]], 2 +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -4 +; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[TMP1]], -3 ; CHECK-NEXT: ret i1 [[R]] ; %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X diff --git a/llvm/test/Transforms/InstCombine/minmax-fold.ll b/llvm/test/Transforms/InstCombine/minmax-fold.ll --- a/llvm/test/Transforms/InstCombine/minmax-fold.ll +++ b/llvm/test/Transforms/InstCombine/minmax-fold.ll @@ -1120,6 +1120,10 @@ ; Negative test +; Without the nuw that would allow pushing the add through the umax, the +; add + icmp ugt combination can be interpreted as a range check, and would +; normally be canonicalized to use ult instead. However, this is not done when +; used as part of a umax to avoid breaking the SPF pattern. define i32 @add_umax_wrong_wrap(i32 %x) { ; CHECK-LABEL: @add_umax_wrong_wrap( ; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll --- a/llvm/test/Transforms/InstCombine/or.ll +++ b/llvm/test/Transforms/InstCombine/or.ll @@ -99,9 +99,9 @@ define i1 @test18(i32 %A) { ; CHECK-LABEL: @test18( -; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -50 -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A_OFF]], 49 -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -50 +; CHECK-NEXT: ret i1 [[TMP2]] ; %B = icmp sge i32 %A, 100 %C = icmp slt i32 %A, 50 @@ -111,9 +111,9 @@ define i1 @test18_logical(i32 %A) { ; CHECK-LABEL: @test18_logical( -; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -50 -; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A_OFF]], 49 -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[A:%.*]], -100 +; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -50 +; CHECK-NEXT: ret i1 [[TMP2]] ; %B = icmp sge i32 %A, 100 %C = icmp slt i32 %A, 50 diff --git a/llvm/test/Transforms/InstCombine/overflow.ll b/llvm/test/Transforms/InstCombine/overflow.ll --- a/llvm/test/Transforms/InstCombine/overflow.ll +++ b/llvm/test/Transforms/InstCombine/overflow.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = extractvalue { i32, i1 } [[SADD]], 1 ; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CHECK: if.then: -; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #2 +; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #[[ATTR2:[0-9]+]] ; CHECK-NEXT: br label [[IF_END]] ; CHECK: if.end: ; CHECK-NEXT: [[SADD_RESULT:%.*]] = extractvalue { i32, i1 } [[SADD]], 0 @@ -49,7 +49,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[ADD_OFF]], 4294967295 ; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CHECK: if.then: -; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #2 +; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #[[ATTR2]] ; CHECK-NEXT: br label [[IF_END]] ; CHECK: if.end: ; CHECK-NEXT: [[CONV9:%.*]] = trunc i64 [[ADD]] to i32 @@ -82,11 +82,11 @@ ; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[A:%.*]] to i64 ; CHECK-NEXT: [[CONV2:%.*]] = sext i32 [[B:%.*]] to i64 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[CONV2]], [[CONV]] -; CHECK-NEXT: [[ADD_OFF:%.*]] = add nsw i64 [[ADD]], 2147483648 -; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[ADD_OFF]], 4294967295 -; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[ADD]], -2147483648 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], -4294967296 +; CHECK-NEXT: br i1 [[TMP1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CHECK: if.then: -; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #2 +; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #[[ATTR2]] ; CHECK-NEXT: br label [[IF_END]] ; CHECK: if.end: ; CHECK-NEXT: ret i64 [[ADD]] @@ -116,7 +116,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = extractvalue { i8, i1 } [[SADD]], 1 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CHECK: if.then: -; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #2 +; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #[[ATTR2]] ; CHECK-NEXT: unreachable ; CHECK: if.end: ; CHECK-NEXT: [[SADD_RESULT:%.*]] = extractvalue { i8, i1 } [[SADD]], 0 @@ -146,11 +146,11 @@ ; CHECK-LABEL: @test8( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[ADD:%.*]] = add i64 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[ADD_OFF:%.*]] = add i64 [[ADD]], 2147483648 -; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[ADD_OFF]], 4294967295 -; CHECK-NEXT: br i1 [[TMP0]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[ADD]], -2147483648 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], -4294967296 +; CHECK-NEXT: br i1 [[TMP1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CHECK: if.then: -; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #2 +; CHECK-NEXT: tail call void @throwAnExceptionOrWhatever() #[[ATTR2]] ; CHECK-NEXT: br label [[IF_END]] ; CHECK: if.end: ; CHECK-NEXT: [[CONV9:%.*]] = trunc i64 [[ADD]] to i32 diff --git a/llvm/test/Transforms/InstCombine/smulo.ll b/llvm/test/Transforms/InstCombine/smulo.ll --- a/llvm/test/Transforms/InstCombine/smulo.ll +++ b/llvm/test/Transforms/InstCombine/smulo.ll @@ -46,8 +46,8 @@ define i1 @test_constant3(i8 %a) { ; CHECK-LABEL: @test_constant3( -; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 42 -; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[TMP1]], 84 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], -43 +; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[TMP1]], -85 ; CHECK-NEXT: ret i1 [[OVERFLOW]] ; %res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 3) @@ -57,8 +57,8 @@ define i1 @test_constant4(i8 %a) { ; CHECK-LABEL: @test_constant4( -; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 32 -; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[TMP1]], 63 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], -32 +; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[TMP1]], -64 ; CHECK-NEXT: ret i1 [[OVERFLOW]] ; %res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 4) @@ -69,8 +69,8 @@ define i1 @test_constant127(i8 %a) { ; CHECK-LABEL: @test_constant127( -; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], 1 -; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ugt i8 [[TMP1]], 2 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A:%.*]], -2 +; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i8 [[TMP1]], -3 ; CHECK-NEXT: ret i1 [[OVERFLOW]] ; %res = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 127)