[llvm] [llvm][InstCombine] Fold signum(x) into scmp(x, 0) (PR #143445)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 10 22:59:55 PDT 2025


================
@@ -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()) &&
----------------
dtcxzyw wrote:

RHS is not checked.
Miscompilation reproducer: https://alive2.llvm.org/ce/z/2p2mS6
```
; bin/opt -passes=instcombine test.ll -S
define i32 @src(i32 noundef %0) {
  %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
}
```
```

----------------------------------------
define i32 @src(i32 noundef %#0) {
#1:
  %#2 = icmp ne i32 noundef %#0, 0
  %#3 = zext i1 %#2 to i32
  %#4 = icmp sgt i32 noundef %#0, 1
  %#5 = select i1 %#4, i32 %#3, i32 4294967295
  ret i32 %#5
}
=>
define i32 @tgt(i32 noundef %#0) {
#1:
  %#2 = scmp i32 i32 noundef %#0, 0
  %#range_0_%#2 = !range i32 %#2, i32 4294967295, i32 2
  ret i32 %#range_0_%#2
}
Transformation doesn't verify!

ERROR: Value mismatch

Example:
i32 noundef %#0 = #x00000000 (0)

Source:
i1 %#2 = #x0 (0)
i32 %#3 = #x00000000 (0)
i1 %#4 = #x0 (0)
i32 %#5 = #xffffffff (4294967295, -1)

Target:
i32 %#2 = #x00000000 (0)
i32 %#range_0_%#2 = #x00000000 (0)
Source value: #xffffffff (4294967295, -1)
Target value: #x00000000 (0)
```

https://github.com/llvm/llvm-project/pull/143445


More information about the llvm-commits mailing list