@@ -916,9 +916,9 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
916916 // to that block.
917917 if (CurLoop->hasLoopInvariantOperands (&I) &&
918918 canSinkOrHoistInst (I, AA, DT, CurLoop, MSSAU, true , Flags, ORE) &&
919- isSafeToExecuteUnconditionally (
920- I, DT, TLI, CurLoop, SafetyInfo, ORE ,
921- Preheader-> getTerminator (), AC, AllowSpeculation)) {
919+ isSafeToExecuteUnconditionally (I, DT, TLI, CurLoop, SafetyInfo, ORE,
920+ Preheader-> getTerminator (), AC ,
921+ AllowSpeculation)) {
922922 hoist (I, DT, CurLoop, CFH.getOrCreateHoistedBlock (BB), SafetyInfo,
923923 MSSAU, SE, ORE);
924924 HoistedInstructions.push_back (&I);
@@ -1035,8 +1035,8 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
10351035 if (VerifyMemorySSA)
10361036 MSSAU.getMemorySSA ()->verifyMemorySSA ();
10371037
1038- // Now that we've finished hoisting make sure that LI and DT are still
1039- // valid.
1038+ // Now that we've finished hoisting make sure that LI and DT are still
1039+ // valid.
10401040#ifdef EXPENSIVE_CHECKS
10411041 if (Changed) {
10421042 assert (DT->verify (DominatorTree::VerificationLevel::Fast) &&
@@ -1137,7 +1137,7 @@ bool isOnlyMemoryAccess(const Instruction *I, const Loop *L,
11371137 }
11381138 return true ;
11391139}
1140- }
1140+ } // namespace
11411141
11421142static MemoryAccess *getClobberingMemoryAccess (MemorySSA &MSSA,
11431143 BatchAAResults &BAA,
@@ -1186,8 +1186,8 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
11861186
11871187 bool InvariantGroup = LI->hasMetadata (LLVMContext::MD_invariant_group);
11881188
1189- bool Invalidated = pointerInvalidatedByLoop (
1190- MSSA, MU, CurLoop, I, Flags, InvariantGroup);
1189+ bool Invalidated =
1190+ pointerInvalidatedByLoop ( MSSA, MU, CurLoop, I, Flags, InvariantGroup);
11911191 // Check loop-invariant address because this may also be a sinkable load
11921192 // whose address is not necessarily loop-invariant.
11931193 if (ORE && Invalidated && CurLoop->isLoopInvariant (LI->getPointerOperand ()))
@@ -1284,7 +1284,7 @@ static bool isTriviallyReplaceablePHI(const PHINode &PN, const Instruction &I) {
12841284
12851285// / Return true if the instruction is foldable in the loop.
12861286static bool isFoldableInLoop (const Instruction &I, const Loop *CurLoop,
1287- const TargetTransformInfo *TTI) {
1287+ const TargetTransformInfo *TTI) {
12881288 if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
12891289 InstructionCost CostI =
12901290 TTI->getInstructionCost (&I, TargetTransformInfo::TCK_SizeAndLatency);
@@ -1639,7 +1639,7 @@ static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,
16391639 // the instruction.
16401640 // First check if I is worth sinking for all uses. Sink only when it is worth
16411641 // across all uses.
1642- SmallSetVector<User*, 8 > Users (I.user_begin (), I.user_end ());
1642+ SmallSetVector<User *, 8 > Users (I.user_begin (), I.user_end ());
16431643 for (auto *UI : Users) {
16441644 auto *User = cast<Instruction>(UI);
16451645
@@ -1672,8 +1672,8 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
16721672 LLVM_DEBUG (dbgs () << " LICM hoisting to " << Dest->getNameOrAsOperand () << " : "
16731673 << I << " \n " );
16741674 ORE->emit ([&]() {
1675- return OptimizationRemark (DEBUG_TYPE, " Hoisted" , &I) << " hoisting "
1676- << ore::NV (" Inst" , &I);
1675+ return OptimizationRemark (DEBUG_TYPE, " Hoisted" , &I)
1676+ << " hoisting " << ore::NV (" Inst" , &I);
16771677 });
16781678
16791679 // Metadata can be dependent on conditions we are hoisting above.
@@ -2376,7 +2376,8 @@ static bool pointerInvalidatedByLoop(MemorySSA *MSSA, MemoryUse *MU,
23762376 MemoryAccess *Source = getClobberingMemoryAccess (*MSSA, BAA, Flags, MU);
23772377 return !MSSA->isLiveOnEntryDef (Source) &&
23782378 CurLoop->contains (Source->getBlock ()) &&
2379- !(InvariantGroup && Source->getBlock () == CurLoop->getHeader () && isa<MemoryPhi>(Source));
2379+ !(InvariantGroup && Source->getBlock () == CurLoop->getHeader () &&
2380+ isa<MemoryPhi>(Source));
23802381 }
23812382
23822383 // For sinking, we'd need to check all Defs below this use. The getClobbering
@@ -2535,6 +2536,26 @@ static bool hoistGEP(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo,
25352536 all_of (Src->indices (), NonNegative) &&
25362537 all_of (GEP->indices (), NonNegative);
25372538
2539+ // CHERIoT has very tight representable bounds in its capability formatting,
2540+ // meaning that any intermediate out-of-bounds values during offsetting are
2541+ // likely to cause invalid pointers. As such, it require a much stricter
2542+ // condition to reorder indices than other targets, namely that the indices
2543+ // must be known either to be all non-negative, or all non-positive.
2544+ StringRef ABI = GEP->getModule ()->getTargetABIFromMD ();
2545+ bool MustStayInBounds = DL.isFatPointer (GEP->getType ()) &&
2546+ (ABI == " cheriot" || ABI == " cheriot-baremetal" );
2547+ if (MustStayInBounds) {
2548+ auto NonPositive = [&](Value *V) {
2549+ return !isKnownPositive (V, SimplifyQuery (DL, DT, AC, GEP));
2550+ };
2551+ bool AllNonNeg = all_of (Src->indices (), NonNegative) &&
2552+ all_of (GEP->indices (), NonNegative);
2553+ bool AllNonPos = all_of (Src->indices (), NonPositive) &&
2554+ all_of (GEP->indices (), NonPositive);
2555+ if (!AllNonNeg && !AllNonPos)
2556+ return false ;
2557+ }
2558+
25382559 BasicBlock *Preheader = L.getLoopPreheader ();
25392560 IRBuilder<> Builder (Preheader->getTerminator ());
25402561 Value *NewSrc = Builder.CreateGEP (GEP->getSourceElementType (), SrcPtr,
0 commit comments