@@ -4275,25 +4275,27 @@ 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" );
4286
+ for (const auto &OpAndRepOp : Ops) {
4287
+ // We cannot replace a constant, and shouldn't even try.
4288
+ if (isa<Constant>(OpAndRepOp.first ))
4289
+ return nullptr ;
4285
4290
4286
- // Trivial replacement.
4287
- if (V == Op)
4288
- return RepOp;
4291
+ // Trivial replacement.
4292
+ if (V == OpAndRepOp.first )
4293
+ return OpAndRepOp.second ;
4294
+ }
4289
4295
4290
4296
if (!MaxRecurse--)
4291
4297
return nullptr ;
4292
4298
4293
- // We cannot replace a constant, and shouldn't even try.
4294
- if (isa<Constant>(Op))
4295
- return nullptr ;
4296
-
4297
4299
auto *I = dyn_cast<Instruction>(V);
4298
4300
if (!I)
4299
4301
return nullptr ;
@@ -4303,11 +4305,6 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4303
4305
if (isa<PHINode>(I))
4304
4306
return nullptr ;
4305
4307
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
4308
// Don't fold away llvm.is.constant checks based on assumptions.
4312
4309
if (match (I, m_Intrinsic<Intrinsic::is_constant>()))
4313
4310
return nullptr ;
@@ -4316,12 +4313,20 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4316
4313
if (isa<FreezeInst>(I))
4317
4314
return nullptr ;
4318
4315
4316
+ for (const auto &OpAndRepOp : Ops) {
4317
+ // For vector types, the simplification must hold per-lane, so forbid
4318
+ // potentially cross-lane operations like shufflevector.
4319
+ if (OpAndRepOp.first ->getType ()->isVectorTy () &&
4320
+ !isNotCrossLaneOperation (I))
4321
+ return nullptr ;
4322
+ }
4323
+
4319
4324
// Replace Op with RepOp in instruction operands.
4320
4325
SmallVector<Value *, 8 > NewOps;
4321
4326
bool AnyReplaced = false ;
4322
4327
for (Value *InstOp : I->operands ()) {
4323
- if (Value *NewInstOp = simplifyWithOpReplaced (
4324
- InstOp, Op, RepOp , Q, AllowRefinement, DropFlags, MaxRecurse)) {
4328
+ if (Value *NewInstOp = simplifyWithOpsReplaced (
4329
+ InstOp, Ops , Q, AllowRefinement, DropFlags, MaxRecurse)) {
4325
4330
NewOps.push_back (NewInstOp);
4326
4331
AnyReplaced = InstOp != NewInstOp;
4327
4332
} else {
@@ -4372,7 +4377,8 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4372
4377
// by assumption and this case never wraps, so nowrap flags can be
4373
4378
// ignored.
4374
4379
if ((Opcode == Instruction::Sub || Opcode == Instruction::Xor) &&
4375
- NewOps[0 ] == RepOp && NewOps[1 ] == RepOp)
4380
+ NewOps[0 ] == NewOps[1 ] &&
4381
+ any_of (Ops, [=](const auto &Rep) { return NewOps[0 ] == Rep.second ; }))
4376
4382
return Constant::getNullValue (I->getType ());
4377
4383
4378
4384
// If we are substituting an absorber constant into a binop and extra
@@ -4382,10 +4388,10 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4382
4388
// (Op == 0) ? 0 : (Op & -Op) --> Op & -Op
4383
4389
// (Op == 0) ? 0 : (Op * (binop Op, C)) --> Op * (binop Op, C)
4384
4390
// (Op == -1) ? -1 : (Op | (binop C, Op) --> Op | (binop C, Op)
4385
- Constant *Absorber =
4386
- ConstantExpr::getBinOpAbsorber (Opcode, I->getType ());
4391
+ Constant *Absorber = ConstantExpr::getBinOpAbsorber (Opcode, I->getType ());
4387
4392
if ((NewOps[0 ] == Absorber || NewOps[1 ] == Absorber) &&
4388
- impliesPoison (BO, Op))
4393
+ any_of (Ops,
4394
+ [=](const auto &Rep) { return impliesPoison (BO, Rep.first ); }))
4389
4395
return Absorber;
4390
4396
}
4391
4397
@@ -4453,6 +4459,15 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
4453
4459
/* AllowNonDeterministic=*/ false );
4454
4460
}
4455
4461
4462
+ static Value *simplifyWithOpReplaced (Value *V, Value *Op, Value *RepOp,
4463
+ const SimplifyQuery &Q,
4464
+ bool AllowRefinement,
4465
+ SmallVectorImpl<Instruction *> *DropFlags,
4466
+ unsigned MaxRecurse) {
4467
+ return simplifyWithOpsReplaced (V, {{Op, RepOp}}, Q, AllowRefinement,
4468
+ DropFlags, MaxRecurse);
4469
+ }
4470
+
4456
4471
Value *llvm::simplifyWithOpReplaced (Value *V, Value *Op, Value *RepOp,
4457
4472
const SimplifyQuery &Q,
4458
4473
bool AllowRefinement,
@@ -4595,21 +4610,20 @@ static Value *simplifySelectWithFakeICmpEq(Value *CmpLHS, Value *CmpRHS,
4595
4610
4596
4611
// / Try to simplify a select instruction when its condition operand is an
4597
4612
// / integer equality or floating-point equivalence comparison.
4598
- static Value *simplifySelectWithEquivalence (Value *CmpLHS, Value *CmpRHS,
4599
- Value *TrueVal, Value *FalseVal,
4600
- const SimplifyQuery &Q,
4601
- unsigned MaxRecurse) {
4613
+ static Value *simplifySelectWithEquivalence (
4614
+ ArrayRef<std::pair<Value *, Value *>> Replacements, Value *TrueVal,
4615
+ Value *FalseVal, const SimplifyQuery &Q, unsigned MaxRecurse) {
4602
4616
Value *SimplifiedFalseVal =
4603
- simplifyWithOpReplaced (FalseVal, CmpLHS, CmpRHS , Q.getWithoutUndef (),
4604
- /* AllowRefinement */ false ,
4605
- /* DropFlags */ nullptr , MaxRecurse);
4617
+ simplifyWithOpsReplaced (FalseVal, Replacements , Q.getWithoutUndef (),
4618
+ /* AllowRefinement */ false ,
4619
+ /* DropFlags */ nullptr , MaxRecurse);
4606
4620
if (!SimplifiedFalseVal)
4607
4621
SimplifiedFalseVal = FalseVal;
4608
4622
4609
4623
Value *SimplifiedTrueVal =
4610
- simplifyWithOpReplaced (TrueVal, CmpLHS, CmpRHS , Q,
4611
- /* AllowRefinement */ true ,
4612
- /* DropFlags */ nullptr , MaxRecurse);
4624
+ simplifyWithOpsReplaced (TrueVal, Replacements , Q,
4625
+ /* AllowRefinement */ true ,
4626
+ /* DropFlags */ nullptr , MaxRecurse);
4613
4627
if (!SimplifiedTrueVal)
4614
4628
SimplifiedTrueVal = TrueVal;
4615
4629
@@ -4707,10 +4721,10 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
4707
4721
// the arms of the select. See if substituting this value into the arm and
4708
4722
// simplifying the result yields the same value as the other arm.
4709
4723
if (Pred == ICmpInst::ICMP_EQ) {
4710
- if (Value *V = simplifySelectWithEquivalence (CmpLHS, CmpRHS, TrueVal,
4724
+ if (Value *V = simplifySelectWithEquivalence ({{ CmpLHS, CmpRHS}} , TrueVal,
4711
4725
FalseVal, Q, MaxRecurse))
4712
4726
return V;
4713
- if (Value *V = simplifySelectWithEquivalence (CmpRHS, CmpLHS, TrueVal,
4727
+ if (Value *V = simplifySelectWithEquivalence ({{ CmpRHS, CmpLHS}} , TrueVal,
4714
4728
FalseVal, Q, MaxRecurse))
4715
4729
return V;
4716
4730
@@ -4720,23 +4734,17 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal,
4720
4734
if (match (CmpLHS, m_Or (m_Value (X), m_Value (Y))) &&
4721
4735
match (CmpRHS, m_Zero ())) {
4722
4736
// (X | Y) == 0 implies X == 0 and Y == 0.
4723
- if (Value *V = simplifySelectWithEquivalence (X, CmpRHS, TrueVal, FalseVal,
4724
- Q, MaxRecurse))
4725
- return V;
4726
- if (Value *V = simplifySelectWithEquivalence (Y, CmpRHS, TrueVal, FalseVal,
4727
- Q, MaxRecurse))
4737
+ if (Value *V = simplifySelectWithEquivalence (
4738
+ {{X, CmpRHS}, {Y, CmpRHS}}, TrueVal, FalseVal, Q, MaxRecurse))
4728
4739
return V;
4729
4740
}
4730
4741
4731
4742
// select((X & Y) == -1 ? X : -1) --> -1 (commuted 2 ways)
4732
4743
if (match (CmpLHS, m_And (m_Value (X), m_Value (Y))) &&
4733
4744
match (CmpRHS, m_AllOnes ())) {
4734
4745
// (X & Y) == -1 implies X == -1 and Y == -1.
4735
- if (Value *V = simplifySelectWithEquivalence (X, CmpRHS, TrueVal, FalseVal,
4736
- Q, MaxRecurse))
4737
- return V;
4738
- if (Value *V = simplifySelectWithEquivalence (Y, CmpRHS, TrueVal, FalseVal,
4739
- Q, MaxRecurse))
4746
+ if (Value *V = simplifySelectWithEquivalence (
4747
+ {{X, CmpRHS}, {Y, CmpRHS}}, TrueVal, FalseVal, Q, MaxRecurse))
4740
4748
return V;
4741
4749
}
4742
4750
}
@@ -4765,11 +4773,11 @@ static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F,
4765
4773
// This transforms is safe if at least one operand is known to not be zero.
4766
4774
// Otherwise, the select can change the sign of a zero operand.
4767
4775
if (IsEquiv) {
4768
- if (Value *V =
4769
- simplifySelectWithEquivalence (CmpLHS, CmpRHS, T, F, Q, MaxRecurse))
4776
+ if (Value *V = simplifySelectWithEquivalence ({{CmpLHS, CmpRHS}}, T, F, Q,
4777
+ MaxRecurse))
4770
4778
return V;
4771
- if (Value *V =
4772
- simplifySelectWithEquivalence (CmpRHS, CmpLHS, T, F, Q, MaxRecurse))
4779
+ if (Value *V = simplifySelectWithEquivalence ({{CmpRHS, CmpLHS}}, T, F, Q,
4780
+ MaxRecurse))
4773
4781
return V;
4774
4782
}
4775
4783
0 commit comments