@@ -132,6 +132,11 @@ static cl::opt<unsigned> HoistLoadsStoresWithCondFaultingThreshold(
132132 " to speculatively execute to eliminate conditional branch "
133133 " (default = 6)" ));
134134
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+
135140static cl::opt<unsigned >
136141 HoistCommonSkipLimit (" simplifycfg-hoist-common-skip-limit" , cl::Hidden,
137142 cl::init (20 ),
@@ -1682,22 +1687,22 @@ static bool areIdenticalUpToCommutativity(const Instruction *I1,
16821687static void hoistConditionalLoadsStores (
16831688 BranchInst *BI,
16841689 SmallVectorImpl<Instruction *> &SpeculatedConditionalLoadsStores,
1685- std::optional<bool > Invert) {
1690+ std::optional<bool > Invert, Instruction *Sel ) {
16861691 auto &Context = BI->getParent ()->getContext ();
16871692 auto *VCondTy = FixedVectorType::get (Type::getInt1Ty (Context), 1 );
16881693 auto *Cond = BI->getOperand (0 );
16891694 // Construct the condition if needed.
16901695 BasicBlock *BB = BI->getParent ();
1691- IRBuilder<> Builder (
1692- Invert.has_value () ? SpeculatedConditionalLoadsStores.back () : BI);
16931696 Value *Mask = nullptr ;
16941697 Value *MaskFalse = nullptr ;
16951698 Value *MaskTrue = nullptr ;
16961699 if (Invert.has_value ()) {
1700+ IRBuilder<> Builder (Sel ? Sel : SpeculatedConditionalLoadsStores.back ());
16971701 Mask = Builder.CreateBitCast (
16981702 *Invert ? Builder.CreateXor (Cond, ConstantInt::getTrue (Context)) : Cond,
16991703 VCondTy);
17001704 } else {
1705+ IRBuilder<> Builder (BI);
17011706 MaskFalse = Builder.CreateBitCast (
17021707 Builder.CreateXor (Cond, ConstantInt::getTrue (Context)), VCondTy);
17031708 MaskTrue = Builder.CreateBitCast (Cond, VCondTy);
@@ -1723,13 +1728,20 @@ static void hoistConditionalLoadsStores(
17231728 PHINode *PN = nullptr ;
17241729 Value *PassThru = nullptr ;
17251730 if (Invert.has_value ())
1726- for (User *U : I->users ())
1731+ for (User *U : I->users ()) {
17271732 if ((PN = dyn_cast<PHINode>(U))) {
17281733 PassThru = Builder.CreateBitCast (
17291734 PeekThroughBitcasts (PN->getIncomingValueForBlock (BB)),
17301735 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);
17321743 }
1744+ }
17331745 MaskedLoadStore = Builder.CreateMaskedLoad (
17341746 FixedVectorType::get (Ty, 1 ), Op0, LI->getAlign (), Mask, PassThru);
17351747 Value *NewLoadStore = Builder.CreateBitCast (MaskedLoadStore, Ty);
@@ -1769,10 +1781,10 @@ static bool isSafeCheapLoadStore(const Instruction *I,
17691781 const TargetTransformInfo &TTI) {
17701782 // Not handle volatile or atomic.
17711783 if (auto *L = dyn_cast<LoadInst>(I)) {
1772- if (!L->isSimple ())
1784+ if (!L->isSimple () || (DisableCloadCstore & 1 ) )
17731785 return false ;
17741786 } else if (auto *S = dyn_cast<StoreInst>(I)) {
1775- if (!S->isSimple ())
1787+ if (!S->isSimple () || (DisableCloadCstore & 2 ) )
17761788 return false ;
17771789 } else
17781790 return false ;
@@ -3308,6 +3320,7 @@ bool SimplifyCFGOpt::speculativelyExecuteBB(BranchInst *BI,
33083320 // If we get here, we can hoist the instruction and if-convert.
33093321 LLVM_DEBUG (dbgs () << " SPECULATIVELY EXECUTING BB" << *ThenBB << " \n " ;);
33103322
3323+ Instruction *Sel = nullptr ;
33113324 // Insert a select of the value of the speculated store.
33123325 if (SpeculatedStoreValue) {
33133326 IRBuilder<NoFolder> Builder (BI);
@@ -3318,6 +3331,7 @@ bool SimplifyCFGOpt::speculativelyExecuteBB(BranchInst *BI,
33183331 std::swap (TrueV, FalseV);
33193332 Value *S = Builder.CreateSelect (
33203333 BrCond, TrueV, FalseV, " spec.store.select" , BI);
3334+ Sel = cast<Instruction>(S);
33213335 SpeculatedStore->setOperand (0 , S);
33223336 SpeculatedStore->applyMergedLocation (BI->getDebugLoc (),
33233337 SpeculatedStore->getDebugLoc ());
@@ -3390,7 +3404,8 @@ bool SimplifyCFGOpt::speculativelyExecuteBB(BranchInst *BI,
33903404 std::prev (ThenBB->end ()));
33913405
33923406 if (!SpeculatedConditionalLoadsStores.empty ())
3393- hoistConditionalLoadsStores (BI, SpeculatedConditionalLoadsStores, Invert);
3407+ hoistConditionalLoadsStores (BI, SpeculatedConditionalLoadsStores, Invert,
3408+ Sel);
33943409
33953410 // Insert selects and rewrite the PHI operands.
33963411 IRBuilder<NoFolder> Builder (BI);
@@ -8042,7 +8057,7 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
80428057
80438058 if (CanSpeculateConditionalLoadsStores ()) {
80448059 hoistConditionalLoadsStores (BI, SpeculatedConditionalLoadsStores,
8045- std::nullopt );
8060+ std::nullopt , nullptr );
80468061 return requestResimplify ();
80478062 }
80488063 }
0 commit comments