[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