[llvm] [InstSimplify] Simplify the select with integer comparison relationship (PR #66668)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 18 09:20:09 PDT 2023


https://github.com/vfdff created https://github.com/llvm/llvm-project/pull/66668

x-y+1 is positive when x > y, so abs (x-y+1) --> x-y+1

Fixes https://github.com/llvm/llvm-project/issues/54735

>From fe146fc4421ce06ce063fc4ff55eda76f035055c Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Mon, 18 Sep 2023 05:07:53 -0400
Subject: [PATCH] [InstSimplify] Simplify the select with integer comparison
 relationship

x-y+1 is positive when x > y, so abs (x-y+1) --> x-y+1

Fixes https://github.com/llvm/llvm-project/issues/54735
---
 llvm/lib/Analysis/InstructionSimplify.cpp     | 25 ++++++++++++++
 .../Transforms/InstSimplify/select-icmp.ll    | 33 +++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100755 llvm/test/Transforms/InstSimplify/select-icmp.ll

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 5fe0d53c313d40e..ecb261716cb71fb 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4547,6 +4547,20 @@ static Value *simplifySelectWithICmpEq(Value *CmpLHS, Value *CmpRHS,
   return nullptr;
 }
 
+/// Return nullptr if the comparison relationship of X and Y can't be inferred.
+static Value *simplifySelectWithICmpKnownRelation(ICmpInst::Predicate Pred,
+                                                  Value *CmpLHS, Value *CmpRHS,
+                                                  Value *TrueVal,
+                                                  Value *FalseVal,
+                                                  const SimplifyQuery &Q) {
+  if (std::optional<bool> Flag =
+          isImpliedByDomCondition(Pred, CmpLHS, CmpRHS, Q.CxtI, Q.DL)) {
+    if (Flag)
+      return *Flag ? TrueVal : FalseVal;
+  }
+  return nullptr;
+}
+
 /// Try to simplify a select instruction when its condition operand is an
 /// integer comparison.
 static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
@@ -4669,6 +4683,17 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
     }
   }
 
+  if (Pred == ICmpInst::ICMP_SLT) {
+    Value *X;
+    Value *Y;
+    const APInt *C;
+    // x-y+1 is positive when x >= y or non-positive when x < y
+    if (match(CmpLHS, m_NSWSub(m_Value(X), m_Value(Y))) &&
+        match(CmpRHS, m_AllOnes()))
+      return simplifySelectWithICmpKnownRelation(ICmpInst::ICMP_SLT, X, Y,
+                                                 TrueVal, FalseVal, Q);
+  }
+
   return nullptr;
 }
 
diff --git a/llvm/test/Transforms/InstSimplify/select-icmp.ll b/llvm/test/Transforms/InstSimplify/select-icmp.ll
new file mode 100755
index 000000000000000..1271941565d9dc3
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/select-icmp.ll
@@ -0,0 +1,33 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
+
+; https://alive2.llvm.org/ce/z/zKX64J
+define i32 @pr54735(i32 noundef %x, i32 noundef %y) {
+; CHECK-LABEL: @pr54735(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
+; CHECK:       cond.true:
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], 1
+; CHECK-NEXT:    br label [[COND_END]]
+; CHECK:       cond.end:
+; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[ADD]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    ret i32 [[COND]]
+;
+entry:
+  %cmp = icmp sgt i32 %x, %y
+  br i1 %cmp, label %cond.true, label %cond.end
+
+cond.true:                                        ; preds = %entry
+  %sub = sub nsw i32 %x, %y
+  %add = add nsw i32 %sub, 1
+  %neg = xor i32 %sub, -1                         ; sub nsw i32 0, %add
+  %abscond = icmp slt i32 %sub, -1
+  %abs = select i1 %abscond, i32 %neg, i32 %add
+  br label %cond.end
+
+cond.end:                                         ; preds = %entry, %cond.true
+  %cond = phi i32 [ %abs, %cond.true ], [ 0, %entry ]
+  ret i32 %cond
+}



More information about the llvm-commits mailing list