diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 079afa992aa510..7dc9ae1d9d064b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2239,9 +2239,10 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp, // those conditions rather than checking them. This is difficult because of // undef/poison (PR34838). if (IsAShr) { - if (Pred == CmpInst::ICMP_SLT || (Pred == CmpInst::ICMP_SGT && IsExact)) { - // icmp slt (ashr X, ShAmtC), C --> icmp slt X, (C << ShAmtC) - // icmp sgt (ashr exact X, ShAmtC), C --> icmp sgt X, (C << ShAmtC) + if (Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_ULT || IsExact) { + // When ShAmtC can be shifted losslessly: + // icmp PRED (ashr exact X, ShAmtC), C --> icmp PRED X, (C << ShAmtC) + // icmp slt/ult (ashr X, ShAmtC), C --> icmp slt/ult X, (C << ShAmtC) APInt ShiftedC = C.shl(ShAmtVal); if (ShiftedC.ashr(ShAmtVal) == C) return new ICmpInst(Pred, X, ConstantInt::get(ShrTy, ShiftedC)); diff --git a/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll b/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll index aae14686b19e1a..f5478f89274814 100644 --- a/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll +++ b/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll @@ -2238,8 +2238,7 @@ define i1 @ashr_00_01_noexact(i8 %x) { define i1 @ashr_00_03_noexact(i8 %x) { ; CHECK-LABEL: @ashr_00_03_noexact( -; CHECK-NEXT: [[S:%.*]] = ashr i8 [[X:%.*]], 3 -; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[S]], 10 +; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X:%.*]], 80 ; CHECK-NEXT: ret i1 [[C]] ; %s = ashr i8 %x, 3 @@ -2289,8 +2288,7 @@ define i1 @ashr_00_03_exact(i8 %x) { define i1 @ashr_00_04_exact(i8 %x) { ; CHECK-LABEL: @ashr_00_04_exact( -; CHECK-NEXT: [[S:%.*]] = ashr exact i8 [[X:%.*]], 3 -; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[S]], 10 +; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[X:%.*]], 80 ; CHECK-NEXT: ret i1 [[C]] ; %s = ashr exact i8 %x, 3 @@ -2300,8 +2298,7 @@ define i1 @ashr_00_04_exact(i8 %x) { define i1 @ashr_00_05_exact(i8 %x) { ; CHECK-LABEL: @ashr_00_05_exact( -; CHECK-NEXT: [[S:%.*]] = ashr exact i8 [[X:%.*]], 3 -; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[S]], 11 +; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X:%.*]], 88 ; CHECK-NEXT: ret i1 [[C]] ; %s = ashr exact i8 %x, 3 @@ -2312,7 +2309,7 @@ define i1 @ashr_00_05_exact(i8 %x) { define i1 @ashr_00_00_ashr_extra_use(i8 %x, i8* %ptr) { ; CHECK-LABEL: @ashr_00_00_ashr_extra_use( ; CHECK-NEXT: [[S:%.*]] = ashr exact i8 [[X:%.*]], 3 -; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[S]], 11 +; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[X]], 88 ; CHECK-NEXT: store i8 [[S]], i8* [[PTR:%.*]], align 1 ; CHECK-NEXT: ret i1 [[C]] ; @@ -2324,8 +2321,7 @@ define i1 @ashr_00_00_ashr_extra_use(i8 %x, i8* %ptr) { define <4 x i1> @ashr_00_00_vec(<4 x i8> %x) { ; CHECK-LABEL: @ashr_00_00_vec( -; CHECK-NEXT: [[S:%.*]] = ashr exact <4 x i8> [[X:%.*]], -; CHECK-NEXT: [[C:%.*]] = icmp ult <4 x i8> [[S]], +; CHECK-NEXT: [[C:%.*]] = icmp ult <4 x i8> [[X:%.*]], ; CHECK-NEXT: ret <4 x i1> [[C]] ; %s = ashr exact <4 x i8> %x, diff --git a/llvm/test/Transforms/InstCombine/icmp-shr.ll b/llvm/test/Transforms/InstCombine/icmp-shr.ll index 45f8eb02b57c97..09732fea5e38fb 100644 --- a/llvm/test/Transforms/InstCombine/icmp-shr.ll +++ b/llvm/test/Transforms/InstCombine/icmp-shr.ll @@ -770,8 +770,7 @@ define i1 @ashr_ult_1(i4 %x) { define i1 @ashr_ult_2(i4 %x) { ; CHECK-LABEL: @ashr_ult_2( -; CHECK-NEXT: [[S:%.*]] = ashr i4 [[X:%.*]], 1 -; CHECK-NEXT: [[R:%.*]] = icmp ult i4 [[S]], 2 +; CHECK-NEXT: [[R:%.*]] = icmp ult i4 [[X:%.*]], 4 ; CHECK-NEXT: ret i1 [[R]] ; %s = ashr i4 %x, 1 @@ -783,8 +782,7 @@ define i1 @ashr_ult_2(i4 %x) { define i1 @ashr_ult_3(i4 %x) { ; CHECK-LABEL: @ashr_ult_3( -; CHECK-NEXT: [[S:%.*]] = ashr i4 [[X:%.*]], 1 -; CHECK-NEXT: [[R:%.*]] = icmp ult i4 [[S]], 3 +; CHECK-NEXT: [[R:%.*]] = icmp ult i4 [[X:%.*]], 6 ; CHECK-NEXT: ret i1 [[R]] ; %s = ashr i4 %x, 1 @@ -877,8 +875,7 @@ define i1 @ashr_ult_11(i4 %x) { define i1 @ashr_ult_12(i4 %x) { ; CHECK-LABEL: @ashr_ult_12( -; CHECK-NEXT: [[S:%.*]] = ashr i4 [[X:%.*]], 1 -; CHECK-NEXT: [[R:%.*]] = icmp ult i4 [[S]], -4 +; CHECK-NEXT: [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1 ; CHECK-NEXT: ret i1 [[R]] ; %s = ashr i4 %x, 1 @@ -890,8 +887,7 @@ define i1 @ashr_ult_12(i4 %x) { define i1 @ashr_ult_13(i4 %x) { ; CHECK-LABEL: @ashr_ult_13( -; CHECK-NEXT: [[S:%.*]] = ashr i4 [[X:%.*]], 1 -; CHECK-NEXT: [[R:%.*]] = icmp ult i4 [[S]], -3 +; CHECK-NEXT: [[R:%.*]] = icmp ult i4 [[X:%.*]], -6 ; CHECK-NEXT: ret i1 [[R]] ; %s = ashr i4 %x, 1 @@ -903,8 +899,7 @@ define i1 @ashr_ult_13(i4 %x) { define i1 @ashr_ult_14(i4 %x) { ; CHECK-LABEL: @ashr_ult_14( -; CHECK-NEXT: [[S:%.*]] = ashr i4 [[X:%.*]], 1 -; CHECK-NEXT: [[R:%.*]] = icmp ult i4 [[S]], -2 +; CHECK-NEXT: [[R:%.*]] = icmp ult i4 [[X:%.*]], -4 ; CHECK-NEXT: ret i1 [[R]] ; %s = ashr i4 %x, 1