@@ -4275,25 +4275,23 @@ Value *llvm::simplifyFCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS,
42754275 return ::simplifyFCmpInst (Predicate, LHS, RHS, FMF, Q, RecursionLimit);
42764276}
42774277
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) {
42834284 assert ((AllowRefinement || !Q.CanUseUndef ) &&
42844285 " 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+ }
42894291
42904292 if (!MaxRecurse--)
42914293 return nullptr ;
42924294
4293- // We cannot replace a constant, and shouldn't even try.
4294- if (isa<Constant>(Op))
4295- return nullptr ;
4296-
42974295 auto *I = dyn_cast<Instruction>(V);
42984296 if (!I)
42994297 return nullptr ;
@@ -4303,11 +4301,6 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
43034301 if (isa<PHINode>(I))
43044302 return nullptr ;
43054303
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-
43114304 // Don't fold away llvm.is.constant checks based on assumptions.
43124305 if (match (I, m_Intrinsic<Intrinsic::is_constant>()))
43134306 return nullptr ;
@@ -4316,12 +4309,30 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
43164309 if (isa<FreezeInst>(I))
43174310 return nullptr ;
43184311
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+
43194329 // Replace Op with RepOp in instruction operands.
43204330 SmallVector<Value *, 8 > NewOps;
43214331 bool AnyReplaced = false ;
43224332 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)) {
43254336 NewOps.push_back (NewInstOp);
43264337 AnyReplaced = InstOp != NewInstOp;
43274338 } else {
@@ -4372,7 +4383,9 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
43724383 // by assumption and this case never wraps, so nowrap flags can be
43734384 // ignored.
43744385 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+ }))
43764389 return Constant::getNullValue (I->getType ());
43774390
43784391 // 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,
43824395 // (Op == 0) ? 0 : (Op & -Op) --> Op & -Op
43834396 // (Op == 0) ? 0 : (Op * (binop Op, C)) --> Op * (binop Op, C)
43844397 // (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 ());
43874399 if ((NewOps[0 ] == Absorber || NewOps[1 ] == Absorber) &&
4388- impliesPoison (BO, Op))
4400+ all_of (ValidReplacements,
4401+ [=](const auto &Rep) { return impliesPoison (BO, Rep.first ); }))
43894402 return Absorber;
43904403 }
43914404
@@ -4453,6 +4466,15 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
44534466 /* AllowNonDeterministic=*/ false );
44544467}
44554468
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+
44564478Value *llvm::simplifyWithOpReplaced (Value *V, Value *Op, Value *RepOp,
44574479 const SimplifyQuery &Q,
44584480 bool AllowRefinement,
0 commit comments