@@ -4275,25 +4275,23 @@ Value *llvm::simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS,
4275
4275
return ::simplifyFCmpInst (Predicate, LHS, RHS, FMF, Q, RecursionLimit);
4276
4276
}
4277
4277
4278
- static Value *simplifyWithOpReplaced (Value *V, Value *Op, Value *RepOp,
4279
- const SimplifyQuery &Q,
4280
- bool AllowRefinement,
4281
- SmallVectorImpl<Instruction *> *DropFlags,
4282
- unsigned MaxRecurse) {
4278
+ static Value *simplifyWithOpsReplaced (Value *V,
4279
+ ArrayRef<std::pair<Value *, Value *>> Ops,
4280
+ const SimplifyQuery &Q,
4281
+ bool AllowRefinement,
4282
+ SmallVectorImpl<Instruction *> *DropFlags,
4283
+ unsigned MaxRecurse) {
4283
4284
assert ((AllowRefinement || !Q.CanUseUndef ) &&
4284
4285
" If AllowRefinement=false then CanUseUndef=false" );
4285
-
4286
- // Trivial replacement.
4287
- if (V == Op)
4288
- return RepOp;
4286
+ for (const auto &OpAndRepOp : Ops) {
4287
+ // Trivial replacement.
4288
+ if (V == OpAndRepOp.first )
4289
+ return OpAndRepOp.second ;
4290
+ }
4289
4291
4290
4292
if (!MaxRecurse--)
4291
4293
return nullptr ;
4292
4294
4293
- // We cannot replace a constant, and shouldn't even try.
4294
- if (isa<Constant>(Op))
4295
- return nullptr ;
4296
-
4297
4295
auto *I = dyn_cast<Instruction>(V);
4298
4296
if (!I)
4299
4297
return nullptr ;
@@ -4303,11 +4301,6 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4303
4301
if (isa<PHINode>(I))
4304
4302
return nullptr ;
4305
4303
4306
- // For vector types, the simplification must hold per-lane, so forbid
4307
- // potentially cross-lane operations like shufflevector.
4308
- if (Op->getType ()->isVectorTy () && !isNotCrossLaneOperation (I))
4309
- return nullptr ;
4310
-
4311
4304
// Don't fold away llvm.is.constant checks based on assumptions.
4312
4305
if (match (I, m_Intrinsic<Intrinsic::is_constant>()))
4313
4306
return nullptr ;
@@ -4316,12 +4309,30 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4316
4309
if (isa<FreezeInst>(I))
4317
4310
return nullptr ;
4318
4311
4312
+ SmallVector<std::pair<Value *, Value *>> ValidReplacements{};
4313
+ for (const auto &OpAndRepOp : Ops) {
4314
+ // We cannot replace a constant, and shouldn't even try.
4315
+ if (isa<Constant>(OpAndRepOp.first ))
4316
+ return nullptr ;
4317
+
4318
+ // For vector types, the simplification must hold per-lane, so forbid
4319
+ // potentially cross-lane operations like shufflevector.
4320
+ if (OpAndRepOp.first ->getType ()->isVectorTy () &&
4321
+ !isNotCrossLaneOperation (I))
4322
+ continue ;
4323
+ ValidReplacements.emplace_back (OpAndRepOp);
4324
+ }
4325
+
4326
+ if (ValidReplacements.empty ())
4327
+ return nullptr ;
4328
+
4319
4329
// Replace Op with RepOp in instruction operands.
4320
4330
SmallVector<Value *, 8 > NewOps;
4321
4331
bool AnyReplaced = false ;
4322
4332
for (Value *InstOp : I->operands ()) {
4323
- if (Value *NewInstOp = simplifyWithOpReplaced (
4324
- InstOp, Op, RepOp, Q, AllowRefinement, DropFlags, MaxRecurse)) {
4333
+ if (Value *NewInstOp =
4334
+ simplifyWithOpsReplaced (InstOp, ValidReplacements, Q,
4335
+ AllowRefinement, DropFlags, MaxRecurse)) {
4325
4336
NewOps.push_back (NewInstOp);
4326
4337
AnyReplaced = InstOp != NewInstOp;
4327
4338
} else {
@@ -4372,7 +4383,9 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4372
4383
// by assumption and this case never wraps, so nowrap flags can be
4373
4384
// ignored.
4374
4385
if ((Opcode == Instruction::Sub || Opcode == Instruction::Xor) &&
4375
- NewOps[0 ] == RepOp && NewOps[1 ] == RepOp)
4386
+ any_of (ValidReplacements, [=](const auto &Rep) {
4387
+ return NewOps[0 ] == NewOps[1 ] && NewOps[0 ] == Rep.second ;
4388
+ }))
4376
4389
return Constant::getNullValue (I->getType ());
4377
4390
4378
4391
// If we are substituting an absorber constant into a binop and extra
@@ -4382,10 +4395,10 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4382
4395
// (Op == 0) ? 0 : (Op & -Op) --> Op & -Op
4383
4396
// (Op == 0) ? 0 : (Op * (binop Op, C)) --> Op * (binop Op, C)
4384
4397
// (Op == -1) ? -1 : (Op | (binop C, Op) --> Op | (binop C, Op)
4385
- Constant *Absorber =
4386
- ConstantExpr::getBinOpAbsorber (Opcode, I->getType ());
4398
+ Constant *Absorber = ConstantExpr::getBinOpAbsorber (Opcode, I->getType ());
4387
4399
if ((NewOps[0 ] == Absorber || NewOps[1 ] == Absorber) &&
4388
- impliesPoison (BO, Op))
4400
+ all_of (ValidReplacements,
4401
+ [=](const auto &Rep) { return impliesPoison (BO, Rep.first ); }))
4389
4402
return Absorber;
4390
4403
}
4391
4404
@@ -4453,6 +4466,15 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4453
4466
/* AllowNonDeterministic=*/ false );
4454
4467
}
4455
4468
4469
+ static Value *simplifyWithOpReplaced (Value *V, Value *Op, Value *RepOp,
4470
+ const SimplifyQuery &Q,
4471
+ bool AllowRefinement,
4472
+ SmallVectorImpl<Instruction *> *DropFlags,
4473
+ unsigned MaxRecurse) {
4474
+ return simplifyWithOpsReplaced (V, {{Op, RepOp}}, Q, AllowRefinement,
4475
+ DropFlags, MaxRecurse);
4476
+ }
4477
+
4456
4478
Value *llvm::simplifyWithOpReplaced (Value *V, Value *Op, Value *RepOp,
4457
4479
const SimplifyQuery &Q,
4458
4480
bool AllowRefinement,
0 commit comments