@@ -132,6 +132,11 @@ static cl::opt<unsigned> HoistLoadsStoresWithCondFaultingThreshold(
132
132
" to speculatively execute to eliminate conditional branch "
133
133
" (default = 6)" ));
134
134
135
+ static cl::opt<unsigned > DisableCloadCstore (
136
+ " disable-cload-cstore" , cl::Hidden, cl::init(0 ),
137
+ cl::desc(" Control to disable cond-faulting-load(1)/cond-faulting-store(2)"
138
+ " /all(3)" ));
139
+
135
140
static cl::opt<unsigned >
136
141
HoistCommonSkipLimit (" simplifycfg-hoist-common-skip-limit" , cl::Hidden,
137
142
cl::init (20 ),
@@ -1682,22 +1687,22 @@ static bool areIdenticalUpToCommutativity(const Instruction *I1,
1682
1687
static void hoistConditionalLoadsStores (
1683
1688
BranchInst *BI,
1684
1689
SmallVectorImpl<Instruction *> &SpeculatedConditionalLoadsStores,
1685
- std::optional<bool > Invert) {
1690
+ std::optional<bool > Invert, Instruction *Sel ) {
1686
1691
auto &Context = BI->getParent ()->getContext ();
1687
1692
auto *VCondTy = FixedVectorType::get (Type::getInt1Ty (Context), 1 );
1688
1693
auto *Cond = BI->getOperand (0 );
1689
1694
// Construct the condition if needed.
1690
1695
BasicBlock *BB = BI->getParent ();
1691
- IRBuilder<> Builder (
1692
- Invert.has_value () ? SpeculatedConditionalLoadsStores.back () : BI);
1693
1696
Value *Mask = nullptr ;
1694
1697
Value *MaskFalse = nullptr ;
1695
1698
Value *MaskTrue = nullptr ;
1696
1699
if (Invert.has_value ()) {
1700
+ IRBuilder<> Builder (Sel ? Sel : SpeculatedConditionalLoadsStores.back ());
1697
1701
Mask = Builder.CreateBitCast (
1698
1702
*Invert ? Builder.CreateXor (Cond, ConstantInt::getTrue (Context)) : Cond,
1699
1703
VCondTy);
1700
1704
} else {
1705
+ IRBuilder<> Builder (BI);
1701
1706
MaskFalse = Builder.CreateBitCast (
1702
1707
Builder.CreateXor (Cond, ConstantInt::getTrue (Context)), VCondTy);
1703
1708
MaskTrue = Builder.CreateBitCast (Cond, VCondTy);
@@ -1723,13 +1728,20 @@ static void hoistConditionalLoadsStores(
1723
1728
PHINode *PN = nullptr ;
1724
1729
Value *PassThru = nullptr ;
1725
1730
if (Invert.has_value ())
1726
- for (User *U : I->users ())
1731
+ for (User *U : I->users ()) {
1727
1732
if ((PN = dyn_cast<PHINode>(U))) {
1728
1733
PassThru = Builder.CreateBitCast (
1729
1734
PeekThroughBitcasts (PN->getIncomingValueForBlock (BB)),
1730
1735
FixedVectorType::get (Ty, 1 ));
1731
- break ;
1736
+ } else if (auto *Ins = cast<Instruction>(U);
1737
+ Sel && Ins->getParent () == BB) {
1738
+ // This happens when store or/and a speculative instruction between
1739
+ // load and store were hoisted to the BB. Make sure the masked load
1740
+ // inserted before its use.
1741
+ // We assume there's one of such use.
1742
+ Builder.SetInsertPoint (Ins);
1732
1743
}
1744
+ }
1733
1745
MaskedLoadStore = Builder.CreateMaskedLoad (
1734
1746
FixedVectorType::get (Ty, 1 ), Op0, LI->getAlign (), Mask, PassThru);
1735
1747
Value *NewLoadStore = Builder.CreateBitCast (MaskedLoadStore, Ty);
@@ -1769,10 +1781,10 @@ static bool isSafeCheapLoadStore(const Instruction *I,
1769
1781
const TargetTransformInfo &TTI) {
1770
1782
// Not handle volatile or atomic.
1771
1783
if (auto *L = dyn_cast<LoadInst>(I)) {
1772
- if (!L->isSimple ())
1784
+ if (!L->isSimple () || (DisableCloadCstore & 1 ) )
1773
1785
return false ;
1774
1786
} else if (auto *S = dyn_cast<StoreInst>(I)) {
1775
- if (!S->isSimple ())
1787
+ if (!S->isSimple () || (DisableCloadCstore & 2 ) )
1776
1788
return false ;
1777
1789
} else
1778
1790
return false ;
@@ -3308,6 +3320,7 @@ bool SimplifyCFGOpt::speculativelyExecuteBB(BranchInst *BI,
3308
3320
// If we get here, we can hoist the instruction and if-convert.
3309
3321
LLVM_DEBUG (dbgs () << " SPECULATIVELY EXECUTING BB" << *ThenBB << " \n " ;);
3310
3322
3323
+ Instruction *Sel = nullptr ;
3311
3324
// Insert a select of the value of the speculated store.
3312
3325
if (SpeculatedStoreValue) {
3313
3326
IRBuilder<NoFolder> Builder (BI);
@@ -3318,6 +3331,7 @@ bool SimplifyCFGOpt::speculativelyExecuteBB(BranchInst *BI,
3318
3331
std::swap (TrueV, FalseV);
3319
3332
Value *S = Builder.CreateSelect (
3320
3333
BrCond, TrueV, FalseV, " spec.store.select" , BI);
3334
+ Sel = cast<Instruction>(S);
3321
3335
SpeculatedStore->setOperand (0 , S);
3322
3336
SpeculatedStore->applyMergedLocation (BI->getDebugLoc (),
3323
3337
SpeculatedStore->getDebugLoc ());
@@ -3390,7 +3404,8 @@ bool SimplifyCFGOpt::speculativelyExecuteBB(BranchInst *BI,
3390
3404
std::prev (ThenBB->end ()));
3391
3405
3392
3406
if (!SpeculatedConditionalLoadsStores.empty ())
3393
- hoistConditionalLoadsStores (BI, SpeculatedConditionalLoadsStores, Invert);
3407
+ hoistConditionalLoadsStores (BI, SpeculatedConditionalLoadsStores, Invert,
3408
+ Sel);
3394
3409
3395
3410
// Insert selects and rewrite the PHI operands.
3396
3411
IRBuilder<NoFolder> Builder (BI);
@@ -8042,7 +8057,7 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
8042
8057
8043
8058
if (CanSpeculateConditionalLoadsStores ()) {
8044
8059
hoistConditionalLoadsStores (BI, SpeculatedConditionalLoadsStores,
8045
- std::nullopt);
8060
+ std::nullopt, nullptr );
8046
8061
return requestResimplify ();
8047
8062
}
8048
8063
}
0 commit comments