[llvm] [llvm][InstCombine] Fold signum(x) into scmp(x, 0) (PR #143445)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 9 14:46:25 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Yash Solanki (yashnator)
<details>
<summary>Changes</summary>
Currently:
```cpp
int signum(int x) {
if (x < 0) return -1;
if (x > 0) return +1;
return 0;
}
```
is not identified as `scmp(x,0)`.
This patch adds folding for the edge case: `(x > -1) ? zext(x != 0) : -1`, which is generated for the above signum and is equivalent to `scmp(x, 0)`. For other constants/variables, the fold is already optimised.
[Alive2 proof](https://alive2.llvm.org/ce/z/EYQZwV) (taken from issue)
Resolves #<!-- -->143259
---
Full diff: https://github.com/llvm/llvm-project/pull/143445.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+12)
- (modified) llvm/test/Transforms/InstCombine/scmp.ll (+14)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 8f46ae304353d..ec0cda18a6492 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3603,6 +3603,18 @@ Instruction *InstCombinerImpl::foldSelectToCmp(SelectInst &SI) {
ICmpInst::getSwappedPredicate(ExtendedCmpPredicate) == Pred))
Replace = true;
+ // Handle the edge case (x > -1) ? zext(x != 0), -1
+ if (IsSigned && ICmpInst::isGT(Pred) && match(FV, m_AllOnes()) &&
+ match(TV, m_ZExt(m_c_ICmp(ExtendedCmpPredicate, m_Specific(LHS),
+ m_Zero()))) &&
+ (ExtendedCmpPredicate == ICmpInst::ICMP_NE ||
+ ICmpInst::getSwappedPredicate(ExtendedCmpPredicate) == Pred)) {
+ Value *Zero = ConstantInt::get(LHS->getType(), 0);
+ return replaceInstUsesWith(
+ SI,
+ Builder.CreateIntrinsic(SI.getType(), Intrinsic::scmp, {LHS, Zero}));
+ }
+
// (x == y) ? 0 : (x > y ? 1 : -1)
CmpPredicate FalseBranchSelectPredicate;
const APInt *InnerTV, *InnerFV;
diff --git a/llvm/test/Transforms/InstCombine/scmp.ll b/llvm/test/Transforms/InstCombine/scmp.ll
index 2140a59de3fa9..b685ca20998bd 100644
--- a/llvm/test/Transforms/InstCombine/scmp.ll
+++ b/llvm/test/Transforms/InstCombine/scmp.ll
@@ -473,3 +473,17 @@ define i8 @scmp_from_select_eq_and_gt_neg3(i32 %x, i32 %y) {
%r = select i1 %eq, i8 0, i8 %sel1
ret i8 %r
}
+
+; Fold (x > -1) ? zext(x != 0), -1 to scmp(x, 0)
+define i32 @scmp_x_0_from_gt_minus_1(i32 noundef %0) local_unnamed_addr #0 {
+; CHECK-LABEL: define i32 @scmp_x_0_from_gt_minus_1(
+; CHECK-SAME: i32 noundef [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[TMP0]], i32 0)
+; CHECK-NEXT: ret i32 [[TMP2]]
+;
+ %2 = icmp ne i32 %0, 0
+ %3 = zext i1 %2 to i32
+ %4 = icmp sgt i32 %0, -1
+ %5 = select i1 %4, i32 %3, i32 -1
+ ret i32 %5
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/143445
More information about the llvm-commits
mailing list