@@ -1120,31 +1120,26 @@ static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo,
1120
1120
// / 1. The pointer select (\p Address) must be defined in \p DepBB.
1121
1121
// / 2. Both value operands of the pointer select must be loaded in the same
1122
1122
// / 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
1124
1124
// / clobber the loads.
1125
1125
static 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,
1128
1127
AAResults *AA) {
1129
-
1130
- auto *Sel = dyn_cast_or_null<SelectInst>(Address);
1131
- if (!Sel || DepBB != Sel->getParent ())
1132
- return std::nullopt;
1133
-
1134
1128
LoadInst *L1 = findDominatingLoad (Sel->getOperand (1 ), LoadTy, Sel, DT);
1135
1129
LoadInst *L2 = findDominatingLoad (Sel->getOperand (2 ), LoadTy, Sel, DT);
1136
1130
if (!L1 || !L2)
1137
1131
return std::nullopt;
1138
1132
1139
1133
// 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 .
1141
1135
Instruction *EarlierLoad = L1->comesBefore (L2) ? L1 : L2;
1142
1136
MemoryLocation L1Loc = MemoryLocation::get (L1);
1143
1137
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
+ }))
1148
1143
return std::nullopt;
1149
1144
1150
1145
return AvailableValue::getSelect (Sel);
@@ -1153,20 +1148,12 @@ tryToConvertLoadOfPtrSelect(BasicBlock *DepBB, BasicBlock::iterator End,
1153
1148
std::optional<AvailableValue>
1154
1149
GVNPass::AnalyzeLoadAvailability (LoadInst *Load, MemDepResult DepInfo,
1155
1150
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" );
1165
1151
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" );
1168
1153
1169
1154
Instruction *DepInst = DepInfo.getInst ();
1155
+
1156
+ const DataLayout &DL = Load->getModule ()->getDataLayout ();
1170
1157
if (DepInfo.isClobber ()) {
1171
1158
// If the dependence is to a store that writes to a superset of the bits
1172
1159
// 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,
1272
1259
return AvailableValue::getLoad (LD);
1273
1260
}
1274
1261
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
+
1275
1269
// Unknown def - must be conservative
1276
1270
LLVM_DEBUG (
1277
1271
// fast print dep, using operator<< on instruction is too slow.
@@ -1298,24 +1292,15 @@ void GVNPass::AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps,
1298
1292
continue ;
1299
1293
}
1300
1294
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 ()) {
1314
1296
UnavailableBlocks.push_back (DepBB);
1315
1297
continue ;
1316
1298
}
1317
1299
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 ())) {
1319
1304
// subtlety: because we know this was a non-local dependency, we know
1320
1305
// it's safe to materialize anywhere between the instruction within
1321
1306
// DepInfo and the end of it's block.
@@ -2043,9 +2028,8 @@ bool GVNPass::processLoad(LoadInst *L) {
2043
2028
if (Dep.isNonLocal ())
2044
2029
return processNonLocalLoad (L);
2045
2030
2046
- Value *Address = L->getPointerOperand ();
2047
2031
// Only handle the local case below
2048
- if (!Dep.isDef () && !Dep. isClobber () && !isa<SelectInst>(Address )) {
2032
+ if (!Dep.isLocal ( )) {
2049
2033
// This might be a NonFuncLocal or an Unknown
2050
2034
LLVM_DEBUG (
2051
2035
// fast print dep, using operator<< on instruction is too slow.
@@ -2054,7 +2038,7 @@ bool GVNPass::processLoad(LoadInst *L) {
2054
2038
return false ;
2055
2039
}
2056
2040
2057
- auto AV = AnalyzeLoadAvailability (L, Dep, Address );
2041
+ auto AV = AnalyzeLoadAvailability (L, Dep, L-> getPointerOperand () );
2058
2042
if (!AV)
2059
2043
return false ;
2060
2044
0 commit comments