[llvm] [InstSimplify] Simplify `select cond, undef, val` to `val` if `val = poison` implies `cond = poison` (PR #76465)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 27 11:15:56 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
This patch folds:
```
select cond, undef, val -> val
select cond, val, undef -> val
```
iff `impliesPoison(val, cond)` returns true.
Example:
```
define i32 @<!-- -->src1(i32 %retval.0.i.i) {
%cmp.i = icmp sgt i32 %retval.0.i.i, -1
%spec.select.i = select i1 %cmp.i, i32 %retval.0.i.i, i32 undef
ret i32 %spec.select.i
}
define i32 @<!-- -->tgt1(i32 %retval.0.i.i) {
ret i32 %retval.0.i.i
}
```
Alive2: https://alive2.llvm.org/ce/z/okJW3G
---
Full diff: https://github.com/llvm/llvm-project/pull/76465.diff
4 Files Affected:
- (modified) llvm/lib/Analysis/InstructionSimplify.cpp (+4-2)
- (modified) llvm/test/Transforms/InstCombine/select.ll (+3-6)
- (modified) llvm/test/Transforms/InstSimplify/select-inseltpoison.ll (+2-6)
- (modified) llvm/test/Transforms/InstSimplify/select.ll (+2-6)
``````````diff
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 5beac5547d65e0..87c3c4e7aeb0ad 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4858,13 +4858,15 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
// select ?, undef, X -> X
if (isa<PoisonValue>(TrueVal) ||
(Q.isUndefValue(TrueVal) &&
- isGuaranteedNotToBePoison(FalseVal, Q.AC, Q.CxtI, Q.DT)))
+ (isGuaranteedNotToBePoison(FalseVal, Q.AC, Q.CxtI, Q.DT) ||
+ impliesPoison(FalseVal, Cond))))
return FalseVal;
// select ?, X, poison -> X
// select ?, X, undef -> X
if (isa<PoisonValue>(FalseVal) ||
(Q.isUndefValue(FalseVal) &&
- isGuaranteedNotToBePoison(TrueVal, Q.AC, Q.CxtI, Q.DT)))
+ (isGuaranteedNotToBePoison(TrueVal, Q.AC, Q.CxtI, Q.DT) ||
+ impliesPoison(TrueVal, Cond))))
return TrueVal;
// Deal with partial undef vector constants: select ?, VecC, VecC' --> VecC''
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 94aa012f868015..d3e959b1eaa0e8 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -2895,10 +2895,7 @@ define i8 @select_replacement_loop(i8 %x, i8 %y, i8 %z) {
define i32 @select_replacement_loop2(i32 %arg, i32 %arg2) {
; CHECK-LABEL: @select_replacement_loop2(
; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[ARG:%.*]], [[ARG2:%.*]]
-; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[DIV]], [[ARG2]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL]], [[ARG]]
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[DIV]], i32 undef
-; CHECK-NEXT: ret i32 [[SEL]]
+; CHECK-NEXT: ret i32 [[DIV]]
;
%div = udiv i32 %arg, %arg2
%mul = mul nsw i32 %div, %arg2
@@ -3627,8 +3624,8 @@ define i32 @pr62088() {
; CHECK: loop:
; CHECK-NEXT: [[NOT2:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ -2, [[LOOP]] ]
; CHECK-NEXT: [[H_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ 1, [[LOOP]] ]
-; CHECK-NEXT: [[XOR1:%.*]] = or disjoint i32 [[H_0]], [[NOT2]]
-; CHECK-NEXT: [[SUB5:%.*]] = sub i32 -1824888657, [[XOR1]]
+; CHECK-NEXT: [[XOR:%.*]] = or disjoint i32 [[H_0]], [[NOT2]]
+; CHECK-NEXT: [[SUB5:%.*]] = sub i32 -1824888657, [[XOR]]
; CHECK-NEXT: [[XOR6:%.*]] = xor i32 [[SUB5]], -1260914025
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[XOR6]], 824855120
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
diff --git a/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll b/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll
index 74a1ed27e59d1d..2a4ce85ed11f8d 100644
--- a/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll
+++ b/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll
@@ -926,12 +926,8 @@ define <2 x i32> @all_constant_true_undef_false_constexpr_vec() {
define i1 @expand_binop_undef(i32 %x, i32 %y) {
; CHECK-LABEL: @expand_binop_undef(
-; CHECK-NEXT: [[CMP9_NOT_1:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[CMP15:%.*]] = icmp slt i32 [[X]], [[Y]]
-; CHECK-NEXT: [[SPEC_SELECT39:%.*]] = select i1 [[CMP9_NOT_1]], i1 undef, i1 [[CMP15]]
-; CHECK-NEXT: [[SPEC_SELECT40:%.*]] = xor i1 [[CMP9_NOT_1]], true
-; CHECK-NEXT: [[SPEC_SELECT:%.*]] = and i1 [[SPEC_SELECT39]], [[SPEC_SELECT40]]
-; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
+; CHECK-NEXT: [[CMP15:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: ret i1 [[CMP15]]
;
%cmp9.not.1 = icmp eq i32 %x, %y
%cmp15 = icmp slt i32 %x, %y
diff --git a/llvm/test/Transforms/InstSimplify/select.ll b/llvm/test/Transforms/InstSimplify/select.ll
index b9c79f02245ccf..1b229f55109394 100644
--- a/llvm/test/Transforms/InstSimplify/select.ll
+++ b/llvm/test/Transforms/InstSimplify/select.ll
@@ -971,12 +971,8 @@ define <2 x i32> @all_constant_true_undef_false_constexpr_vec() {
define i1 @expand_binop_undef(i32 %x, i32 %y) {
; CHECK-LABEL: @expand_binop_undef(
-; CHECK-NEXT: [[CMP9_NOT_1:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[CMP15:%.*]] = icmp slt i32 [[X]], [[Y]]
-; CHECK-NEXT: [[SPEC_SELECT39:%.*]] = select i1 [[CMP9_NOT_1]], i1 undef, i1 [[CMP15]]
-; CHECK-NEXT: [[SPEC_SELECT40:%.*]] = xor i1 [[CMP9_NOT_1]], true
-; CHECK-NEXT: [[SPEC_SELECT:%.*]] = and i1 [[SPEC_SELECT39]], [[SPEC_SELECT40]]
-; CHECK-NEXT: ret i1 [[SPEC_SELECT]]
+; CHECK-NEXT: [[CMP15:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: ret i1 [[CMP15]]
;
%cmp9.not.1 = icmp eq i32 %x, %y
%cmp15 = icmp slt i32 %x, %y
``````````
</details>
https://github.com/llvm/llvm-project/pull/76465
More information about the llvm-commits
mailing list