[llvm] [CVP] Propagate constant range on icmp at use level (PR #73767)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 29 00:58:52 PST 2023


https://github.com/XChy updated https://github.com/llvm/llvm-project/pull/73767

>From 8ede35173d96d0dcbedc52751ac644bfb4561fe2 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Tue, 28 Nov 2023 19:55:00 +0800
Subject: [PATCH 1/2] [CVP] Precommit test for constant propagation of icmp

---
 .../CorrelatedValuePropagation/icmp.ll        | 102 ++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
index 101820a4c65f23b..ff9b5df666860c4 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
@@ -1455,3 +1455,105 @@ entry:
   %select = select i1 %cmp1, i1 %cmp2, i1 false
   ret i1 %select
 }
+
+define i1 @select_ternary_icmp1(i32 noundef %a) {
+; CHECK-LABEL: @select_ternary_icmp1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 3
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], 5
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[A]], 7
+; CHECK-NEXT:    [[COND_V:%.*]] = select i1 [[CMP]], i1 true, i1 [[CMP2]]
+; CHECK-NEXT:    ret i1 [[COND_V]]
+;
+entry:
+  %cmp = icmp slt i32 %a, 3
+  %cmp1 = icmp slt i32 %a, 5
+  %cmp2 = icmp slt i32 %a, 7
+  %cond.v = select i1 %cmp, i1 %cmp1, i1 %cmp2
+  ret i1 %cond.v
+}
+
+define i1 @select_ternary_icmp2(i32 noundef %a) {
+; CHECK-LABEL: @select_ternary_icmp2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 5
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], 7
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 3
+; CHECK-NEXT:    [[COND_V:%.*]] = select i1 [[CMP]], i1 true, i1 false
+; CHECK-NEXT:    ret i1 [[COND_V]]
+;
+entry:
+  %cmp = icmp slt i32 %a, 5
+  %cmp1 = icmp slt i32 %a, 7
+  %cmp2 = icmp slt i32 %a, 3
+  %cond.v = select i1 %cmp, i1 %cmp1, i1 %cmp2
+  ret i1 %cond.v
+}
+
+define i1 @select_ternary_icmp3(i32 noundef %a) {
+; CHECK-LABEL: @select_ternary_icmp3(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 7
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A]], 3
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], 5
+; CHECK-NEXT:    [[COND_V:%.*]] = select i1 [[CMP]], i1 [[CMP1]], i1 false
+; CHECK-NEXT:    ret i1 [[COND_V]]
+;
+entry:
+  %cmp = icmp slt i32 %a, 7
+  %cmp1 = icmp slt i32 %a, 3
+  %cmp2 = icmp slt i32 %a, 5
+  %cond.v = select i1 %cmp, i1 %cmp1, i1 %cmp2
+  ret i1 %cond.v
+}
+
+define i1 @select_ternary_icmp3_reverse(i32 noundef %a) {
+; CHECK-LABEL: @select_ternary_icmp3_reverse(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 3
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[A]], 5
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[A]], 7
+; CHECK-NEXT:    [[COND_V:%.*]] = select i1 [[CMP]], i1 false, i1 [[CMP2]]
+; CHECK-NEXT:    ret i1 [[COND_V]]
+;
+entry:
+  %cmp = icmp slt i32 %a, 3
+  %cmp1 = icmp sge i32 %a, 5
+  %cmp2 = icmp sge i32 %a, 7
+  %cond.v = select i1 %cmp, i1 %cmp1, i1 %cmp2
+  ret i1 %cond.v
+}
+
+define i1 @select_ternary_icmp_fail1(i32 noundef %a, i32 noundef %b) {
+; CHECK-LABEL: @select_ternary_icmp_fail1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 3
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[B:%.*]], 5
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[B]], 7
+; CHECK-NEXT:    [[COND_V:%.*]] = select i1 [[CMP]], i1 [[CMP1]], i1 [[CMP2]]
+; CHECK-NEXT:    ret i1 [[COND_V]]
+;
+entry:
+  %cmp = icmp slt i32 %a, 3
+  %cmp1 = icmp slt i32 %b, 5
+  %cmp2 = icmp slt i32 %b, 7
+  %cond.v = select i1 %cmp, i1 %cmp1, i1 %cmp2
+  ret i1 %cond.v
+}
+
+define i1 @select_ternary_icmp_fail2(i32 noundef %a, i32 noundef %b) {
+; CHECK-LABEL: @select_ternary_icmp_fail2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 3
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sge i32 5, [[B:%.*]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp sge i32 7, [[B]]
+; CHECK-NEXT:    [[COND_V:%.*]] = select i1 [[CMP]], i1 [[CMP1]], i1 [[CMP2]]
+; CHECK-NEXT:    ret i1 [[COND_V]]
+;
+entry:
+  %cmp = icmp slt i32 %a, 3
+  %cmp1 = icmp sge i32 5, %b
+  %cmp2 = icmp sge i32 7, %b
+  %cond.v = select i1 %cmp, i1 %cmp1, i1 %cmp2
+  ret i1 %cond.v
+}

>From 8e13cf02ad0ba1ed818b37e88110dc584b032eb4 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sun, 26 Nov 2023 16:22:29 +0800
Subject: [PATCH 2/2] [CVP] Propagate constant range on icmp at use level

---
 .../Scalar/CorrelatedValuePropagation.cpp     | 23 +++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index 1bdc441d18ea65e..7daf4625d89e321 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -275,11 +275,26 @@ static bool processICmp(ICmpInst *Cmp, LazyValueInfo *LVI) {
   if (!Cmp->isSigned())
     return false;
 
+  auto LHSRange = LVI->getConstantRangeAtUse(Cmp->getOperandUse(0));
+  auto RHSRange = LVI->getConstantRangeAtUse(Cmp->getOperandUse(1));
+
+  // NOTE: It's not the original purpose. Do simple constant propagation at use
+  // level here.
+  if (Cmp->hasOneUse()) {
+    if (LHSRange.icmp(Cmp->getPredicate(), RHSRange)) {
+      Cmp->replaceAllUsesWith(Constant::getAllOnesValue(Cmp->getType()));
+      return true;
+    }
+
+    if (LHSRange.icmp(Cmp->getInversePredicate(), RHSRange)) {
+      Cmp->replaceAllUsesWith(Constant::getNullValue(Cmp->getType()));
+      return true;
+    }
+  }
+
   ICmpInst::Predicate UnsignedPred =
-      ConstantRange::getEquivalentPredWithFlippedSignedness(
-          Cmp->getPredicate(),
-          LVI->getConstantRangeAtUse(Cmp->getOperandUse(0)),
-          LVI->getConstantRangeAtUse(Cmp->getOperandUse(1)));
+      ConstantRange::getEquivalentPredWithFlippedSignedness(Cmp->getPredicate(),
+                                                            LHSRange, RHSRange);
 
   if (UnsignedPred == ICmpInst::Predicate::BAD_ICMP_PREDICATE)
     return false;



More information about the llvm-commits mailing list