@@ -202,8 +202,12 @@ class GuardWideningImpl {
202
202
// / expensive as computing one of the two. If \p InsertPt is true then
203
203
// / actually generate the resulting expression, make it available at \p
204
204
// / InsertPt and return it in \p Result (else no change to the IR is made).
205
- bool widenCondCommon (Value *Cond0, Value *Cond1, Instruction *InsertPt,
206
- Value *&Result);
205
+ std::optional<Value *> mergeChecks (Value *Cond0, Value *Cond1,
206
+ Instruction *InsertPt);
207
+
208
+ // / Generate the logical AND of \p Cond0 and \p Cond1 and make it available at
209
+ // / \p InsertPt
210
+ Value *hoistChecks (Value *Cond0, Value *Cond1, Instruction *InsertPt);
207
211
208
212
// / Adds freeze to Orig and push it as far as possible very aggressively.
209
213
// / Also replaces all uses of frozen instruction with frozen version.
@@ -269,15 +273,18 @@ class GuardWideningImpl {
269
273
// / Can we compute the logical AND of \p Cond0 and \p Cond1 for the price of
270
274
// / computing only one of the two expressions?
271
275
bool isWideningCondProfitable (Value *Cond0, Value *Cond1) {
272
- Value *ResultUnused;
273
- return widenCondCommon (Cond0, Cond1, /* InsertPt=*/ nullptr , ResultUnused);
276
+ return mergeChecks (Cond0, Cond1, /* InsertPt=*/ nullptr ).has_value ();
274
277
}
275
278
276
279
// / Widen \p ToWiden to fail if \p NewCondition is false
277
280
void widenGuard (Instruction *ToWiden, Value *NewCondition) {
278
- Value *Result;
279
281
Instruction *InsertPt = findInsertionPointForWideCondition (ToWiden);
280
- widenCondCommon (getCondition (ToWiden), NewCondition, InsertPt, Result);
282
+ auto MergedCheck =
283
+ mergeChecks (getCondition (ToWiden), NewCondition, InsertPt);
284
+ Value *Result = MergedCheck ? *MergedCheck
285
+ : hoistChecks (getCondition (ToWiden),
286
+ NewCondition, InsertPt);
287
+
281
288
if (isGuardAsWidenableBranch (ToWiden)) {
282
289
setWidenableBranchCond (cast<BranchInst>(ToWiden), Result);
283
290
return ;
@@ -654,10 +661,12 @@ Value *GuardWideningImpl::freezeAndPush(Value *Orig, Instruction *InsertPt) {
654
661
return Result;
655
662
}
656
663
657
- bool GuardWideningImpl::widenCondCommon (Value *Cond0, Value *Cond1,
658
- Instruction *InsertPt, Value *&Result) {
664
+ std::optional<Value *> GuardWideningImpl::mergeChecks (Value *Cond0,
665
+ Value *Cond1,
666
+ Instruction *InsertPt) {
659
667
using namespace llvm ::PatternMatch;
660
668
669
+ Value *Result = nullptr ;
661
670
{
662
671
// L >u C0 && L >u C1 -> L >u max(C0, C1)
663
672
ConstantInt *RHS0, *RHS1;
@@ -686,7 +695,7 @@ bool GuardWideningImpl::widenCondCommon(Value *Cond0, Value *Cond1,
686
695
makeAvailableAt (LHS, InsertPt);
687
696
Result = new ICmpInst (InsertPt, Pred, LHS, NewRHS, " wide.chk" );
688
697
}
689
- return true ;
698
+ return Result ;
690
699
}
691
700
}
692
701
}
@@ -697,7 +706,6 @@ bool GuardWideningImpl::widenCondCommon(Value *Cond0, Value *Cond1,
697
706
if (parseRangeChecks (Cond0, Checks) && parseRangeChecks (Cond1, Checks) &&
698
707
combineRangeChecks (Checks, CombinedChecks)) {
699
708
if (InsertPt) {
700
- Result = nullptr ;
701
709
for (auto &RC : CombinedChecks) {
702
710
makeAvailableAt (RC.getCheckInst (), InsertPt);
703
711
if (Result)
@@ -710,21 +718,19 @@ bool GuardWideningImpl::widenCondCommon(Value *Cond0, Value *Cond1,
710
718
Result->setName (" wide.chk" );
711
719
Result = freezeAndPush (Result, InsertPt);
712
720
}
713
- return true ;
721
+ return Result ;
714
722
}
715
723
}
716
-
717
- // Base case -- just logical-and the two conditions together.
718
-
719
- if (InsertPt) {
720
- makeAvailableAt (Cond0, InsertPt);
721
- makeAvailableAt (Cond1, InsertPt);
722
- Cond1 = freezeAndPush (Cond1, InsertPt);
723
- Result = BinaryOperator::CreateAnd (Cond0, Cond1, " wide.chk" , InsertPt);
724
- }
725
-
726
724
// We were not able to compute Cond0 AND Cond1 for the price of one.
727
- return false ;
725
+ return std::nullopt;
726
+ }
727
+
728
+ Value *GuardWideningImpl::hoistChecks (Value *Cond0, Value *Cond1,
729
+ Instruction *InsertPt) {
730
+ makeAvailableAt (Cond0, InsertPt);
731
+ makeAvailableAt (Cond1, InsertPt);
732
+ Cond1 = freezeAndPush (Cond1, InsertPt);
733
+ return BinaryOperator::CreateAnd (Cond0, Cond1, " wide.chk" , InsertPt);
728
734
}
729
735
730
736
bool GuardWideningImpl::parseRangeChecks (
0 commit comments