[llvm] 9551fc5 - Fold ashr-exact into a icmp-ugt.

Nadav Rotem via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 14 12:59:05 PST 2022


Author: Nadav Rotem
Date: 2022-01-14T12:58:44-08:00
New Revision: 9551fc57b7e98b27844ef840b13773844c738f92

URL: https://github.com/llvm/llvm-project/commit/9551fc57b7e98b27844ef840b13773844c738f92
DIFF: https://github.com/llvm/llvm-project/commit/9551fc57b7e98b27844ef840b13773844c738f92.diff

LOG: Fold ashr-exact into a icmp-ugt.

This commit optimizes the code sequence:
  icmp-XXX (ashr-exact (X, C_1), C_2).

Instcombine already implements this optimization for sgt, and this
patch adds support to additional predicates. The transformation is legal
for all predicates if the 'exact' flag is set, and to SGE, UGE, SLT, ULT
when the exact flag is not present.

This pattern is found in the std::vector bounds checks code of the at()
method.

Alive2 proof:
https://alive2.llvm.org/ce/z/JT_WL8

Differential Revision: https://reviews.llvm.org/D117252

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
    llvm/test/Transforms/InstCombine/icmp-shr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 079afa992aa51..7dc9ae1d9d064 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 
diff icult 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 aae14686b19e1..f5478f8927481 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:%.*]], <i8 3, i8 3, i8 3, i8 3>
-; CHECK-NEXT:    [[C:%.*]] = icmp ult <4 x i8> [[S]], <i8 11, i8 11, i8 11, i8 11>
+; CHECK-NEXT:    [[C:%.*]] = icmp ult <4 x i8> [[X:%.*]], <i8 88, i8 88, i8 88, i8 88>
 ; CHECK-NEXT:    ret <4 x i1> [[C]]
 ;
   %s = ashr exact <4 x i8> %x, <i8 3,i8 3, i8 3, i8 3>

diff  --git a/llvm/test/Transforms/InstCombine/icmp-shr.ll b/llvm/test/Transforms/InstCombine/icmp-shr.ll
index 45f8eb02b57c9..09732fea5e38f 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


        


More information about the llvm-commits mailing list