@@ -1120,31 +1120,26 @@ static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo,
11201120// / 1. The pointer select (\p Address) must be defined in \p DepBB.
11211121// / 2. Both value operands of the pointer select must be loaded in the same
11221122// / basic block, before the pointer select.
1123- // / 3. There must be no instructions between the found loads and \p End that may
1123+ // / 3. There must be no instructions between the found loads and \p Sel that may
11241124// / clobber the loads.
11251125static std::optional<AvailableValue>
1126- tryToConvertLoadOfPtrSelect (BasicBlock *DepBB, BasicBlock::iterator End,
1127- Value *Address, Type *LoadTy, DominatorTree &DT,
1126+ tryToConvertLoadOfPtrSelect (SelectInst *Sel, Type *LoadTy, DominatorTree &DT,
11281127 AAResults *AA) {
1129-
1130- auto *Sel = dyn_cast_or_null<SelectInst>(Address);
1131- if (!Sel || DepBB != Sel->getParent ())
1132- return std::nullopt ;
1133-
11341128 LoadInst *L1 = findDominatingLoad (Sel->getOperand (1 ), LoadTy, Sel, DT);
11351129 LoadInst *L2 = findDominatingLoad (Sel->getOperand (2 ), LoadTy, Sel, DT);
11361130 if (!L1 || !L2)
11371131 return std::nullopt ;
11381132
11391133 // Ensure there are no accesses that may modify the locations referenced by
1140- // either L1 or L2 between L1, L2 and the specified End iterator .
1134+ // either L1 or L2 between L1, L2 and the specified Sel instruction .
11411135 Instruction *EarlierLoad = L1->comesBefore (L2) ? L1 : L2;
11421136 MemoryLocation L1Loc = MemoryLocation::get (L1);
11431137 MemoryLocation L2Loc = MemoryLocation::get (L2);
1144- if (any_of (make_range (EarlierLoad->getIterator (), End), [&](Instruction &I) {
1145- return isModSet (AA->getModRefInfo (&I, L1Loc)) ||
1146- isModSet (AA->getModRefInfo (&I, L2Loc));
1147- }))
1138+ if (any_of (make_range (EarlierLoad->getIterator (), Sel->getIterator ()),
1139+ [&](Instruction &I) {
1140+ return isModSet (AA->getModRefInfo (&I, L1Loc)) ||
1141+ isModSet (AA->getModRefInfo (&I, L2Loc));
1142+ }))
11481143 return std::nullopt ;
11491144
11501145 return AvailableValue::getSelect (Sel);
@@ -1153,20 +1148,12 @@ tryToConvertLoadOfPtrSelect(BasicBlock *DepBB, BasicBlock::iterator End,
11531148std::optional<AvailableValue>
11541149GVNPass::AnalyzeLoadAvailability (LoadInst *Load, MemDepResult DepInfo,
11551150 Value *Address) {
1156- if (!DepInfo.isDef () && !DepInfo.isClobber ()) {
1157- assert (isa<SelectInst>(Address));
1158- return tryToConvertLoadOfPtrSelect (Load->getParent (), Load->getIterator (),
1159- Address, Load->getType (),
1160- getDominatorTree (), getAliasAnalysis ());
1161- }
1162-
1163- assert ((DepInfo.isDef () || DepInfo.isClobber ()) &&
1164- " expected a local dependence" );
11651151 assert (Load->isUnordered () && " rules below are incorrect for ordered access" );
1166-
1167- const DataLayout &DL = Load->getModule ()->getDataLayout ();
1152+ assert (DepInfo.isLocal () && " expected a local dependence" );
11681153
11691154 Instruction *DepInst = DepInfo.getInst ();
1155+
1156+ const DataLayout &DL = Load->getModule ()->getDataLayout ();
11701157 if (DepInfo.isClobber ()) {
11711158 // If the dependence is to a store that writes to a superset of the bits
11721159 // read by the load, we can extract the bits we need for the load from the
@@ -1272,6 +1259,13 @@ GVNPass::AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo,
12721259 return AvailableValue::getLoad (LD);
12731260 }
12741261
1262+ // Check if load with Addr dependent from select can be converted to select
1263+ // between load values. There must be no instructions between the found
1264+ // loads and DepInst that may clobber the loads.
1265+ if (auto *Sel = dyn_cast<SelectInst>(DepInst))
1266+ return tryToConvertLoadOfPtrSelect (Sel, Load->getType (), getDominatorTree (),
1267+ getAliasAnalysis ());
1268+
12751269 // Unknown def - must be conservative
12761270 LLVM_DEBUG (
12771271 // fast print dep, using operator<< on instruction is too slow.
@@ -1298,24 +1292,15 @@ void GVNPass::AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps,
12981292 continue ;
12991293 }
13001294
1301- // The address being loaded in this non-local block may not be the same as
1302- // the pointer operand of the load if PHI translation occurs. Make sure
1303- // to consider the right address.
1304- Value *Address = Dep.getAddress ();
1305-
1306- if (!DepInfo.isDef () && !DepInfo.isClobber ()) {
1307- if (auto R = tryToConvertLoadOfPtrSelect (
1308- DepBB, DepBB->end (), Address, Load->getType (), getDominatorTree (),
1309- getAliasAnalysis ())) {
1310- ValuesPerBlock.push_back (
1311- AvailableValueInBlock::get (DepBB, std::move (*R)));
1312- continue ;
1313- }
1295+ if (!DepInfo.isLocal ()) {
13141296 UnavailableBlocks.push_back (DepBB);
13151297 continue ;
13161298 }
13171299
1318- if (auto AV = AnalyzeLoadAvailability (Load, DepInfo, Address)) {
1300+ // The address being loaded in this non-local block may not be the same as
1301+ // the pointer operand of the load if PHI translation occurs. Make sure
1302+ // to consider the right address.
1303+ if (auto AV = AnalyzeLoadAvailability (Load, DepInfo, Dep.getAddress ())) {
13191304 // subtlety: because we know this was a non-local dependency, we know
13201305 // it's safe to materialize anywhere between the instruction within
13211306 // DepInfo and the end of it's block.
@@ -2043,9 +2028,8 @@ bool GVNPass::processLoad(LoadInst *L) {
20432028 if (Dep.isNonLocal ())
20442029 return processNonLocalLoad (L);
20452030
2046- Value *Address = L->getPointerOperand ();
20472031 // Only handle the local case below
2048- if (!Dep.isDef () && !Dep. isClobber () && !isa<SelectInst>(Address )) {
2032+ if (!Dep.isLocal ( )) {
20492033 // This might be a NonFuncLocal or an Unknown
20502034 LLVM_DEBUG (
20512035 // fast print dep, using operator<< on instruction is too slow.
@@ -2054,7 +2038,7 @@ bool GVNPass::processLoad(LoadInst *L) {
20542038 return false ;
20552039 }
20562040
2057- auto AV = AnalyzeLoadAvailability (L, Dep, Address );
2041+ auto AV = AnalyzeLoadAvailability (L, Dep, L-> getPointerOperand () );
20582042 if (!AV)
20592043 return false ;
20602044
0 commit comments