[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