@@ -1288,38 +1288,55 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
1288
1288
Swapped = true ;
1289
1289
}
1290
1290
1291
- // In X == Y ? f(X) : Z, try to evaluate f(Y) and replace the operand.
1292
- // Make sure Y cannot be undef though, as we might pick different values for
1293
- // undef in the icmp and in f(Y). Additionally, take care to avoid replacing
1294
- // X == Y ? X : Z with X == Y ? Y : Z, as that would lead to an infinite
1295
- // replacement cycle.
1296
1291
Value *CmpLHS = Cmp.getOperand (0 ), *CmpRHS = Cmp.getOperand (1 );
1297
- if (TrueVal != CmpLHS && isGuaranteedNotToBeUndef (CmpRHS, SQ.AC , &Sel, &DT)) {
1298
- if (Value *V = simplifyWithOpReplaced (TrueVal, CmpLHS, CmpRHS, SQ,
1299
- /* AllowRefinement */ true ))
1300
- // Require either the replacement or the simplification result to be a
1301
- // constant to avoid infinite loops.
1302
- // FIXME: Make this check more precise.
1303
- if (isa<Constant>(CmpRHS) || isa<Constant>(V))
1292
+ auto ReplaceOldOpWithNewOp = [&](Value *OldOp,
1293
+ Value *NewOp) -> Instruction * {
1294
+ // In X == Y ? f(X) : Z, try to evaluate f(Y) and replace the operand.
1295
+ // Take care to avoid replacing X == Y ? X : Z with X == Y ? Y : Z, as that
1296
+ // would lead to an infinite replacement cycle.
1297
+ // If we will be able to evaluate f(Y) to a constant, we can allow undef,
1298
+ // otherwise Y cannot be undef as we might pick different values for undef
1299
+ // in the icmp and in f(Y).
1300
+ if (TrueVal == OldOp)
1301
+ return nullptr ;
1302
+
1303
+ if (Value *V = simplifyWithOpReplaced (TrueVal, OldOp, NewOp, SQ,
1304
+ /* AllowRefinement=*/ true )) {
1305
+ // Need some guarantees about the new simplified op to ensure we don't inf
1306
+ // loop.
1307
+ // If we simplify to a constant, replace if we aren't creating new undef.
1308
+ if (match (V, m_ImmConstant ()) &&
1309
+ isGuaranteedNotToBeUndef (V, SQ.AC , &Sel, &DT))
1304
1310
return replaceOperand (Sel, Swapped ? 2 : 1 , V);
1305
1311
1312
+ // If NewOp is a constant and OldOp is not replace iff NewOp doesn't
1313
+ // contain and undef elements.
1314
+ if (match (NewOp, m_ImmConstant ())) {
1315
+ if (isGuaranteedNotToBeUndef (NewOp, SQ.AC , &Sel, &DT))
1316
+ return replaceOperand (Sel, Swapped ? 2 : 1 , V);
1317
+ return nullptr ;
1318
+ }
1319
+ }
1320
+
1306
1321
// Even if TrueVal does not simplify, we can directly replace a use of
1307
1322
// CmpLHS with CmpRHS, as long as the instruction is not used anywhere
1308
1323
// else and is safe to speculatively execute (we may end up executing it
1309
1324
// with different operands, which should not cause side-effects or trigger
1310
1325
// undefined behavior). Only do this if CmpRHS is a constant, as
1311
1326
// profitability is not clear for other cases.
1312
1327
// FIXME: Support vectors.
1313
- if (match (CmpRHS, m_ImmConstant ()) && !match (CmpLHS, m_ImmConstant ()) &&
1314
- !Cmp.getType ()->isVectorTy ())
1315
- if (replaceInInstruction (TrueVal, CmpLHS, CmpRHS))
1328
+ if (OldOp == CmpLHS && match (NewOp, m_ImmConstant ()) &&
1329
+ !match (OldOp, m_ImmConstant ()) && !Cmp.getType ()->isVectorTy () &&
1330
+ isGuaranteedNotToBeUndef (NewOp, SQ.AC , &Sel, &DT))
1331
+ if (replaceInInstruction (TrueVal, OldOp, NewOp))
1316
1332
return &Sel;
1317
- }
1318
- if (TrueVal != CmpRHS && isGuaranteedNotToBeUndef (CmpLHS, SQ.AC , &Sel, &DT))
1319
- if (Value *V = simplifyWithOpReplaced (TrueVal, CmpRHS, CmpLHS, SQ,
1320
- /* AllowRefinement */ true ))
1321
- if (isa<Constant>(CmpLHS) || isa<Constant>(V))
1322
- return replaceOperand (Sel, Swapped ? 2 : 1 , V);
1333
+ return nullptr ;
1334
+ };
1335
+
1336
+ if (Instruction *R = ReplaceOldOpWithNewOp (CmpLHS, CmpRHS))
1337
+ return R;
1338
+ if (Instruction *R = ReplaceOldOpWithNewOp (CmpRHS, CmpLHS))
1339
+ return R;
1323
1340
1324
1341
auto *FalseInst = dyn_cast<Instruction>(FalseVal);
1325
1342
if (!FalseInst)
0 commit comments