[llvm] b554e41 - [CVP] Canonicalize signed relational comparisons of scalar integers to unsigned comparison predicates

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 1 02:16:32 PDT 2021


Author: Roman Lebedev
Date: 2021-11-01T12:16:05+03:00
New Revision: b554e41e2d15b78679231b390e543153e05c9efe

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

LOG: [CVP] Canonicalize signed relational comparisons of scalar integers to unsigned comparison predicates

Now that the reasoning was added to ConstantRange in D90924,
this replicates IndVars variant of this transform (D111836)
in a pass that uses value range reasoning for the transform.

Reviewed By: nikic

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

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
    llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
    llvm/test/Transforms/CorrelatedValuePropagation/deopt.ll
    llvm/test/Transforms/CorrelatedValuePropagation/minmaxabs.ll
    llvm/test/Transforms/CorrelatedValuePropagation/overflow_predicate.ll
    llvm/test/Transforms/CorrelatedValuePropagation/range.ll
    llvm/test/Transforms/CorrelatedValuePropagation/sdiv.ll
    llvm/test/Transforms/CorrelatedValuePropagation/srem.ll
    llvm/test/Transforms/PhaseOrdering/X86/vector-reductions-logical.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index 4b8392db96287..ca9567dc7ac8a 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -67,6 +67,7 @@ STATISTIC(NumUDivURemsNarrowed,
 STATISTIC(NumAShrs,     "Number of ashr converted to lshr");
 STATISTIC(NumSRems,     "Number of srem converted to urem");
 STATISTIC(NumSExt,      "Number of sext converted to zext");
+STATISTIC(NumSICmps,    "Number of signed icmp preds simplified to unsigned");
 STATISTIC(NumAnd,       "Number of ands removed");
 STATISTIC(NumNW,        "Number of no-wrap deductions");
 STATISTIC(NumNSW,       "Number of no-signed-wrap deductions");
@@ -295,11 +296,34 @@ static bool processMemAccess(Instruction *I, LazyValueInfo *LVI) {
   return true;
 }
 
+static bool processICmp(ICmpInst *Cmp, LazyValueInfo *LVI) {
+  // Only for signed relational comparisons of scalar integers.
+  if (Cmp->getType()->isVectorTy() ||
+      !Cmp->getOperand(0)->getType()->isIntegerTy())
+    return false;
+
+  if (!Cmp->isSigned())
+    return false;
+
+  ICmpInst::Predicate UnsignedPred =
+      ConstantRange::getEquivalentPredWithFlippedSignedness(
+          Cmp->getPredicate(), LVI->getConstantRange(Cmp->getOperand(0), Cmp),
+          LVI->getConstantRange(Cmp->getOperand(1), Cmp));
+
+  if (UnsignedPred == ICmpInst::Predicate::BAD_ICMP_PREDICATE)
+    return false;
+
+  ++NumSICmps;
+  Cmp->setPredicate(UnsignedPred);
+
+  return true;
+}
+
 /// See if LazyValueInfo's ability to exploit edge conditions or range
 /// information is sufficient to prove this comparison. Even for local
 /// conditions, this can sometimes prove conditions instcombine can't by
 /// exploiting range information.
-static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
+static bool constantFoldCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
   Value *Op0 = Cmp->getOperand(0);
   auto *C = dyn_cast<Constant>(Cmp->getOperand(1));
   if (!C)
@@ -318,6 +342,17 @@ static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
   return true;
 }
 
+static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
+  if (constantFoldCmp(Cmp, LVI))
+    return true;
+
+  if (auto *ICmp = dyn_cast<ICmpInst>(Cmp))
+    if (processICmp(ICmp, LVI))
+      return true;
+
+  return false;
+}
+
 /// Simplify a switch instruction by removing cases which can never fire. If the
 /// uselessness of a case could be determined locally then constant propagation
 /// would already have figured it out. Instead, walk the predecessors and

diff  --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
index a620c8468d4d8..9caaacfa00d21 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
@@ -533,7 +533,7 @@ define i1 @smin(i32 %a, i32 %b) {
 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20
 ; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
 ; CHECK:       b_guard:
-; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sle i32 [[A]], [[B]]
+; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ule i32 [[A]], [[B]]
 ; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
 ; CHECK-NEXT:    ret i1 false
 ; CHECK:       out:
@@ -565,7 +565,7 @@ define i1 @smax(i32 %a, i32 %b) {
 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20
 ; CHECK-NEXT:    br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
 ; CHECK:       b_guard:
-; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sge i32 [[A]], [[B]]
+; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
 ; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
 ; CHECK-NEXT:    ret i1 false
 ; CHECK:       out:
@@ -738,7 +738,7 @@ define i1 @clamp_low3(i32 %a) {
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
 ; CHECK:       a_guard:
-; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sgt i32 [[A]], 5
+; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ugt i32 [[A]], 5
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
 ; CHECK-NEXT:    ret i1 false
@@ -765,7 +765,7 @@ define i1 @clamp_low4(i32 %a) {
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
 ; CHECK-NEXT:    br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
 ; CHECK:       a_guard:
-; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp sle i32 [[A]], 5
+; CHECK-NEXT:    [[SEL_CMP:%.*]] = icmp ule i32 [[A]], 5
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], -1
 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
 ; CHECK-NEXT:    ret i1 false
@@ -934,10 +934,10 @@ define void @abs1(i32 %a, i1* %p) {
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 0
 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
 ; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
-; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[ABS]], 19
+; CHECK-NEXT:    [[C2:%.*]] = icmp ult i32 [[ABS]], 19
 ; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
 ; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
-; CHECK-NEXT:    [[C4:%.*]] = icmp sge i32 [[ABS]], 1
+; CHECK-NEXT:    [[C4:%.*]] = icmp uge i32 [[ABS]], 1
 ; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
 ; CHECK-NEXT:    br label [[EXIT]]
 ; CHECK:       exit:
@@ -979,10 +979,10 @@ define void @abs2(i32 %a, i1* %p) {
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[A]], 0
 ; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
 ; CHECK-NEXT:    store i1 true, i1* [[P:%.*]], align 1
-; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[ABS]], 19
+; CHECK-NEXT:    [[C2:%.*]] = icmp ult i32 [[ABS]], 19
 ; CHECK-NEXT:    store i1 [[C2]], i1* [[P]], align 1
 ; CHECK-NEXT:    store i1 true, i1* [[P]], align 1
-; CHECK-NEXT:    [[C4:%.*]] = icmp sge i32 [[ABS]], 1
+; CHECK-NEXT:    [[C4:%.*]] = icmp uge i32 [[ABS]], 1
 ; CHECK-NEXT:    store i1 [[C4]], i1* [[P]], align 1
 ; CHECK-NEXT:    br label [[EXIT]]
 ; CHECK:       exit:

diff  --git a/llvm/test/Transforms/CorrelatedValuePropagation/deopt.ll b/llvm/test/Transforms/CorrelatedValuePropagation/deopt.ll
index af4bf6f90c77a..096c5d7e3698c 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/deopt.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/deopt.ll
@@ -97,7 +97,7 @@ define void @test3(i1 %c, i1 %c2) {
 ; CHECK-LABEL: @test3(
 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C:%.*]], i64 0, i64 1
 ; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[C2:%.*]], i64 [[SEL]], i64 2
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[SEL2]], 1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[SEL2]], 1
 ; CHECK-NEXT:    br i1 [[CMP]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
 ; CHECK:       taken:
 ; CHECK-NEXT:    call void @use() [ "deopt"(i64 2) ]
@@ -122,7 +122,7 @@ define void @test4(i1 %c, i1 %c2) {
 ; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[C2:%.*]], i64 0, i64 1
 ; CHECK-NEXT:    [[ADD1:%.*]] = add nuw nsw i64 0, [[SEL]]
 ; CHECK-NEXT:    [[ADD2:%.*]] = add nuw nsw i64 [[ADD1]], [[SEL2]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[ADD2]], 1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[ADD2]], 1
 ; CHECK-NEXT:    br i1 [[CMP]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
 ; CHECK:       taken:
 ; CHECK-NEXT:    call void @use() [ "deopt"(i64 2) ]

diff  --git a/llvm/test/Transforms/CorrelatedValuePropagation/minmaxabs.ll b/llvm/test/Transforms/CorrelatedValuePropagation/minmaxabs.ll
index bc0a0150de76c..5bb34185cde4d 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/minmaxabs.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/minmaxabs.ll
@@ -60,7 +60,7 @@ define void @test_smax(i32 %x) {
 ; CHECK-LABEL: @test_smax(
 ; CHECK-NEXT:    [[M:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 10)
 ; CHECK-NEXT:    call void @use(i1 true)
-; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[M]], 10
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i32 [[M]], 10
 ; CHECK-NEXT:    call void @use(i1 [[C2]])
 ; CHECK-NEXT:    ret void
 ;
@@ -110,7 +110,7 @@ define void @test_abs3(i32 %x) {
 ; CHECK-LABEL: @test_abs3(
 ; CHECK-NEXT:    [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
 ; CHECK-NEXT:    call void @use(i1 true)
-; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[A]], 0
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i32 [[A]], 0
 ; CHECK-NEXT:    call void @use(i1 [[C2]])
 ; CHECK-NEXT:    ret void
 ;

diff  --git a/llvm/test/Transforms/CorrelatedValuePropagation/overflow_predicate.ll b/llvm/test/Transforms/CorrelatedValuePropagation/overflow_predicate.ll
index b4e10110f7490..f3943edbd8fc8 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/overflow_predicate.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/overflow_predicate.ll
@@ -113,7 +113,7 @@ define i1 @sadd_ov_true(i8 %x, i8* %px, i1* %pc) {
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
 ; CHECK-NEXT:    br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]
 ; CHECK:       overflow:
-; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i8 [[X]], 28
+; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[X]], 28
 ; CHECK-NEXT:    store i1 [[C1]], i1* [[PC:%.*]], align 1
 ; CHECK-NEXT:    ret i1 true
 ; CHECK:       trap:
@@ -241,7 +241,7 @@ define i1 @ssub_ov_true(i8 %x, i8* %px, i1* %pc) {
 ; CHECK-NEXT:    [[OV:%.*]] = extractvalue { i8, i1 } [[VAL_OV]], 1
 ; CHECK-NEXT:    br i1 [[OV]], label [[OVERFLOW:%.*]], label [[TRAP:%.*]]
 ; CHECK:       overflow:
-; CHECK-NEXT:    [[C1:%.*]] = icmp slt i8 [[X]], -29
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult i8 [[X]], -29
 ; CHECK-NEXT:    store i1 [[C1]], i1* [[PC:%.*]], align 1
 ; CHECK-NEXT:    ret i1 true
 ; CHECK:       trap:

diff  --git a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll
index 89bcf9fd15f51..570b5dcad02f2 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll
@@ -64,7 +64,7 @@ define i32 @test3(i32 %c) nounwind {
 ; CHECK:       if.then:
 ; CHECK-NEXT:    ret i32 1
 ; CHECK:       if.end:
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[C]], 3
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[C]], 3
 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END8:%.*]]
 ; CHECK:       if.then2:
 ; CHECK-NEXT:    br i1 true, label [[IF_THEN4:%.*]], label [[IF_END6:%.*]]

diff  --git a/llvm/test/Transforms/CorrelatedValuePropagation/sdiv.ll b/llvm/test/Transforms/CorrelatedValuePropagation/sdiv.ll
index 9150e8170cc2a..8da9a203be562 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/sdiv.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/sdiv.ll
@@ -128,10 +128,10 @@ define void @test5(i32 %n) {
 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP:%.*]], label [[EXIT:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ [[N]], [[ENTRY:%.*]] ], [ [[DIV1:%.*]], [[LOOP]] ]
-; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[A]], 4
+; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A]], 4
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])
 ; CHECK-NEXT:    [[DIV1]] = udiv i32 [[A]], 6
-; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp sgt i32 [[DIV1]], 8
+; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp ugt i32 [[DIV1]], 8
 ; CHECK-NEXT:    br i1 [[LOOPCOND]], label [[LOOP]], label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void

diff  --git a/llvm/test/Transforms/CorrelatedValuePropagation/srem.ll b/llvm/test/Transforms/CorrelatedValuePropagation/srem.ll
index 192d9160ba40d..c3df87e5969fb 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/srem.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/srem.ll
@@ -41,10 +41,10 @@ define void @test4(i32 %n) {
 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP:%.*]], label [[EXIT:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ [[N]], [[ENTRY:%.*]] ], [ [[REM1:%.*]], [[LOOP]] ]
-; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[A]], 4
+; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A]], 4
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])
 ; CHECK-NEXT:    [[REM1]] = urem i32 [[A]], 17
-; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp sgt i32 [[REM1]], 8
+; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp ugt i32 [[REM1]], 8
 ; CHECK-NEXT:    br i1 [[LOOPCOND]], label [[LOOP]], label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void

diff  --git a/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions-logical.ll b/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions-logical.ll
index 2fafc768bd962..dd2742c209e2d 100644
--- a/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions-logical.ll
+++ b/llvm/test/Transforms/PhaseOrdering/X86/vector-reductions-logical.ll
@@ -583,7 +583,7 @@ define i32 @test_separate_anyof_v4si(<4 x i32> %t) {
 ; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i4 [[TMP1]], 0
 ; CHECK-NEXT:    br i1 [[DOTNOT]], label [[IF_END:%.*]], label [[RETURN:%.*]]
 ; CHECK:       if.end:
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <4 x i32> [[T_FR]], <i32 255, i32 255, i32 255, i32 255>
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt <4 x i32> [[T_FR]], <i32 255, i32 255, i32 255, i32 255>
 ; CHECK-NEXT:    [[TMP3:%.*]] = bitcast <4 x i1> [[TMP2]] to i4
 ; CHECK-NEXT:    [[DOTNOT7:%.*]] = icmp eq i4 [[TMP3]], 0
 ; CHECK-NEXT:    [[SHIFT:%.*]] = shufflevector <4 x i32> [[T_FR]], <4 x i32> poison, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>


        


More information about the llvm-commits mailing list