Skip to content

Commit b1fab40

Browse files
committed
[InstCombine] Generalize select equiv fold for plain condition
The select equivalence fold takes a select like "X == Y ? A : B" and then tries to simplify A based on the known equality. This patch also uses it for the case were we have just "C ? A : B" by treating the condition as either "C == 1" or "C != 1". This is intended as an alternative to llvm#83405 for fixing llvm#83225.
1 parent bd9a2af commit b1fab40

File tree

3 files changed

+25
-35
lines changed

3 files changed

+25
-35
lines changed

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,9 +735,11 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
735735
Value *A, Value *B, Instruction &Outer,
736736
SelectPatternFlavor SPF2, Value *C);
737737
Instruction *foldSelectInstWithICmp(SelectInst &SI, ICmpInst *ICI);
738-
Instruction *foldSelectValueEquivalence(SelectInst &SI, ICmpInst &ICI);
739738
bool replaceInInstruction(Value *V, Value *Old, Value *New,
740739
unsigned Depth = 0);
740+
Instruction *foldSelectValueEquivalence(SelectInst &Sel,
741+
ICmpInst::Predicate Pred,
742+
Value *CmpLHS, Value *CmpRHS);
741743

742744
Value *insertRangeTest(Value *V, const APInt &Lo, const APInt &Hi,
743745
bool isSigned, bool Inside);

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,27 +1262,23 @@ bool InstCombinerImpl::replaceInInstruction(Value *V, Value *Old, Value *New,
12621262
///
12631263
/// We can't replace %sel with %add unless we strip away the flags.
12641264
/// TODO: Wrapping flags could be preserved in some cases with better analysis.
1265-
Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
1266-
ICmpInst &Cmp) {
1267-
if (!Cmp.isEquality())
1265+
Instruction *InstCombinerImpl::foldSelectValueEquivalence(
1266+
SelectInst &Sel, ICmpInst::Predicate Pred, Value *CmpLHS, Value *CmpRHS) {
1267+
if (!ICmpInst::isEquality(Pred))
12681268
return nullptr;
12691269

12701270
// Canonicalize the pattern to ICMP_EQ by swapping the select operands.
12711271
Value *TrueVal = Sel.getTrueValue(), *FalseVal = Sel.getFalseValue();
12721272
bool Swapped = false;
1273-
if (Cmp.getPredicate() == ICmpInst::ICMP_NE) {
1273+
if (Pred == ICmpInst::ICMP_NE) {
12741274
std::swap(TrueVal, FalseVal);
12751275
Swapped = true;
12761276
}
12771277

12781278
// In X == Y ? f(X) : Z, try to evaluate f(Y) and replace the operand.
12791279
// Make sure Y cannot be undef though, as we might pick different values for
1280-
// undef in the icmp and in f(Y). Additionally, take care to avoid replacing
1281-
// X == Y ? X : Z with X == Y ? Y : Z, as that would lead to an infinite
1282-
// replacement cycle.
1283-
Value *CmpLHS = Cmp.getOperand(0), *CmpRHS = Cmp.getOperand(1);
1284-
if (TrueVal != CmpLHS &&
1285-
isGuaranteedNotToBeUndefOrPoison(CmpRHS, SQ.AC, &Sel, &DT)) {
1280+
// undef in the icmp and in f(Y).
1281+
if (isGuaranteedNotToBeUndefOrPoison(CmpRHS, SQ.AC, &Sel, &DT)) {
12861282
if (Value *V = simplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, SQ,
12871283
/* AllowRefinement */ true))
12881284
// Require either the replacement or the simplification result to be a
@@ -1299,7 +1295,7 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
12991295
// profitability is not clear for other cases.
13001296
// FIXME: Support vectors.
13011297
if (match(CmpRHS, m_ImmConstant()) && !match(CmpLHS, m_ImmConstant()) &&
1302-
!Cmp.getType()->isVectorTy())
1298+
!CmpLHS->getType()->isVectorTy())
13031299
if (replaceInInstruction(TrueVal, CmpLHS, CmpRHS))
13041300
return &Sel;
13051301
}
@@ -1680,7 +1676,8 @@ static Value *foldSelectInstWithICmpConst(SelectInst &SI, ICmpInst *ICI,
16801676
/// Visit a SelectInst that has an ICmpInst as its first operand.
16811677
Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
16821678
ICmpInst *ICI) {
1683-
if (Instruction *NewSel = foldSelectValueEquivalence(SI, *ICI))
1679+
if (Instruction *NewSel = foldSelectValueEquivalence(
1680+
SI, ICI->getPredicate(), ICI->getOperand(0), ICI->getOperand(1)))
16841681
return NewSel;
16851682

16861683
if (Value *V =
@@ -3376,21 +3373,15 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
33763373
if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, *this))
33773374
return I;
33783375

3379-
// If the type of select is not an integer type or if the condition and
3380-
// the selection type are not both scalar nor both vector types, there is no
3381-
// point in attempting to match these patterns.
33823376
Type *CondType = CondVal->getType();
3383-
if (!isa<Constant>(CondVal) && SelType->isIntOrIntVectorTy() &&
3384-
CondType->isVectorTy() == SelType->isVectorTy()) {
3385-
if (Value *S = simplifyWithOpReplaced(TrueVal, CondVal,
3386-
ConstantInt::getTrue(CondType), SQ,
3387-
/* AllowRefinement */ true))
3388-
return replaceOperand(SI, 1, S);
3377+
if (!isa<Constant>(CondVal)) {
3378+
if (Instruction *I = foldSelectValueEquivalence(
3379+
SI, ICmpInst::ICMP_EQ, CondVal, ConstantInt::getTrue(CondType)))
3380+
return I;
33893381

3390-
if (Value *S = simplifyWithOpReplaced(FalseVal, CondVal,
3391-
ConstantInt::getFalse(CondType), SQ,
3392-
/* AllowRefinement */ true))
3393-
return replaceOperand(SI, 2, S);
3382+
if (Instruction *I = foldSelectValueEquivalence(
3383+
SI, ICmpInst::ICMP_NE, CondVal, ConstantInt::getFalse(CondType)))
3384+
return I;
33943385
}
33953386

33963387
if (Instruction *R = foldSelectOfBools(SI))

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3709,9 +3709,8 @@ define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
37093709

37103710
define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
37113711
; CHECK-LABEL: @sequence_select_with_same_cond_false(
3712-
; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45
3713-
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]]
3714-
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
3712+
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 45
3713+
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], i32 789, i32 [[S2]]
37153714
; CHECK-NEXT: ret i32 [[S3]]
37163715
;
37173716
%s1 = select i1 %c1, i32 23, i32 45
@@ -3722,9 +3721,8 @@ define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
37223721

37233722
define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){
37243723
; CHECK-LABEL: @sequence_select_with_same_cond_true(
3725-
; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 45, i32 23
3726-
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 [[S1]], i32 666
3727-
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 [[S2]], i32 789
3724+
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 45, i32 666
3725+
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], i32 [[S2]], i32 789
37283726
; CHECK-NEXT: ret i32 [[S3]]
37293727
;
37303728
%s1 = select i1 %c1, i32 45, i32 23
@@ -3735,9 +3733,8 @@ define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){
37353733

37363734
define double @sequence_select_with_same_cond_double(double %a, i1 %c1, i1 %c2, double %r1, double %r2){
37373735
; CHECK-LABEL: @sequence_select_with_same_cond_double(
3738-
; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], double 1.000000e+00, double 0.000000e+00
3739-
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], double [[S1]], double 2.000000e+00
3740-
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], double [[S2]], double 3.000000e+00
3736+
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], double 1.000000e+00, double 2.000000e+00
3737+
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], double [[S2]], double 3.000000e+00
37413738
; CHECK-NEXT: ret double [[S3]]
37423739
;
37433740
%s1 = select i1 %c1, double 1.0, double 0.0

0 commit comments

Comments
 (0)