Skip to content

Commit

Permalink
[InstSimplify] Simplify select cond, undef, val to val if `val = …
Browse files Browse the repository at this point in the history
…poison` implies `cond = poison` (#76465)

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

Compile-time impact:
http://llvm-compile-time-tracker.com/compare.php?from=38c9390b59c4d2b9181614d6a909887497d3692f&to=e146f51ba278aa3bb6879a9ec651831ac8938e91&stat=instructions%3Au
  • Loading branch information
dtcxzyw committed Dec 28, 2023
1 parent 3d7880b commit 554feb0
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 22 deletions.
6 changes: 2 additions & 4 deletions llvm/lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4869,14 +4869,12 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
// select ?, poison, X -> X
// select ?, undef, X -> X
if (isa<PoisonValue>(TrueVal) ||
(Q.isUndefValue(TrueVal) &&
isGuaranteedNotToBePoison(FalseVal, Q.AC, Q.CxtI, Q.DT)))
(Q.isUndefValue(TrueVal) && 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)))
(Q.isUndefValue(FalseVal) && impliesPoison(TrueVal, Cond)))
return TrueVal;

// Deal with partial undef vector constants: select ?, VecC, VecC' --> VecC''
Expand Down
9 changes: 3 additions & 6 deletions llvm/test/Transforms/InstCombine/select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:%.*]]
Expand Down
8 changes: 2 additions & 6 deletions llvm/test/Transforms/InstSimplify/select-inseltpoison.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 2 additions & 6 deletions llvm/test/Transforms/InstSimplify/select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 554feb0

Please sign in to comment.