Skip to content

Commit 78d332b

Browse files
committed
[InstCombine] Improve coverage of foldSelectValueEquivalence for non-constants
If f(Y) simplifies to Y. This requires that Y is not undef or poison. This handles things like `or`/`min`/`max`/`select`/etc...
1 parent 9895c99 commit 78d332b

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,8 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
12991299
if (TrueVal == OldOp)
13001300
return nullptr;
13011301

1302+
bool NewOpNeverUndef = false;
1303+
13021304
if (Value *V = simplifyWithOpReplaced(TrueVal, OldOp, NewOp, SQ,
13031305
/* AllowRefinement=*/true)) {
13041306
// Need some guarantees about the new simplified op to ensure we don't inf
@@ -1308,13 +1310,20 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
13081310
isGuaranteedNotToBeUndef(V, SQ.AC, &Sel, &DT))
13091311
return replaceOperand(Sel, Swapped ? 2 : 1, V);
13101312

1311-
// If NewOp is a constant and OldOp is not replace iff NewOp doesn't
1312-
// contain and undef elements.
1313-
if (match(NewOp, m_ImmConstant())) {
1314-
if (isGuaranteedNotToBeUndef(NewOp, SQ.AC, &Sel, &DT))
1315-
return replaceOperand(Sel, Swapped ? 2 : 1, V);
1313+
// We can't do any further replacement if NewOp may be undef.
1314+
if (!isGuaranteedNotToBeUndef(NewOp, SQ.AC, &Sel, &DT))
13161315
return nullptr;
1317-
}
1316+
1317+
// If NewOp is a constant, replace.
1318+
if (match(NewOp, m_ImmConstant()))
1319+
return replaceOperand(Sel, Swapped ? 2 : 1, V);
1320+
1321+
// If we simplified the TrueArm -> NewOp then replace.
1322+
// This handles things like `select`/`min`/`max`/`or`/`and`/etc...
1323+
if (NewOp == V)
1324+
return replaceOperand(Sel, Swapped ? 2 : 1, V);
1325+
1326+
NewOpNeverUndef = true;
13181327
}
13191328

13201329
// Even if TrueVal does not simplify, we can directly replace a use of
@@ -1326,7 +1335,7 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
13261335
// FIXME: Support vectors.
13271336
if (OldOp == CmpLHS && match(NewOp, m_ImmConstant()) &&
13281337
!match(OldOp, m_ImmConstant()) && !Cmp.getType()->isVectorTy() &&
1329-
isGuaranteedNotToBeUndef(NewOp, SQ.AC, &Sel, &DT))
1338+
(NewOpNeverUndef || isGuaranteedNotToBeUndef(NewOp, SQ.AC, &Sel, &DT)))
13301339
if (replaceInInstruction(TrueVal, OldOp, NewOp))
13311340
return &Sel;
13321341
return nullptr;

llvm/test/Transforms/InstCombine/select-cmp-eq-op-fold.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ declare void @use.i8(i8)
66
define i8 @replace_with_y_noundef(i8 %x, i8 noundef %y, i8 %z) {
77
; CHECK-LABEL: @replace_with_y_noundef(
88
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
9-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]]
10-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 [[Z:%.*]]
9+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[Y]], i8 [[Z:%.*]]
1110
; CHECK-NEXT: ret i8 [[SEL]]
1211
;
1312
%cmp = icmp eq i8 %x, %y
@@ -20,8 +19,7 @@ define i8 @replace_with_x_noundef(i8 noundef %x, i8 %y, i8 %z) {
2019
; CHECK-LABEL: @replace_with_x_noundef(
2120
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
2221
; CHECK-NEXT: call void @use.i1(i1 [[CMP]])
23-
; CHECK-NEXT: [[AND:%.*]] = or i8 [[X]], [[Y]]
24-
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[Z:%.*]], i8 [[AND]]
22+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 [[Z:%.*]], i8 [[X]]
2523
; CHECK-NEXT: ret i8 [[SEL]]
2624
;
2725
%cmp = icmp ne i8 %x, %y

0 commit comments

Comments
 (0)