@@ -256,6 +256,7 @@ enum OverwriteResult {
256
256
OW_End,
257
257
OW_PartialEarlierWithFullLater,
258
258
OW_MaybePartial,
259
+ OW_None,
259
260
OW_Unknown
260
261
};
261
262
@@ -849,6 +850,7 @@ struct DSEState {
849
850
// / Return OW_MaybePartial if \p KillingI does not completely overwrite
850
851
// / \p DeadI, but they both write to the same underlying object. In that
851
852
// / case, use isPartialOverwrite to check if \p KillingI partially overwrites
853
+ // / \p DeadI. Returns 'OR_None' if \p KillingI is known to not overwrite the
852
854
// / \p DeadI. Returns 'OW_Unknown' if nothing can be determined.
853
855
OverwriteResult isOverwrite (const Instruction *KillingI,
854
856
const Instruction *DeadI,
@@ -911,8 +913,16 @@ struct DSEState {
911
913
912
914
// If we can't resolve the same pointers to the same object, then we can't
913
915
// analyze them at all.
914
- if (DeadUndObj != KillingUndObj)
916
+ if (DeadUndObj != KillingUndObj) {
917
+ // Non aliasing stores to different objects don't overlap. Note that
918
+ // if the killing store is known to overwrite whole object (out of
919
+ // bounds access overwrites whole object as well) then it is assumed to
920
+ // completely overwrite any store to the same object even if they don't
921
+ // actually alias (see next check).
922
+ if (AAR == AliasResult::NoAlias)
923
+ return OW_None;
915
924
return OW_Unknown;
925
+ }
916
926
917
927
// If the KillingI store is to a recognizable object, get its size.
918
928
uint64_t KillingUndObjSize = getPointerSize (KillingUndObj, DL, TLI, &F);
@@ -966,9 +976,8 @@ struct DSEState {
966
976
return OW_MaybePartial;
967
977
}
968
978
969
- // Can reach here only if accesses are known not to overlap. There is no
970
- // dedicated code to indicate no overlap so signal "unknown".
971
- return OW_Unknown;
979
+ // Can reach here only if accesses are known not to overlap.
980
+ return OW_None;
972
981
}
973
982
974
983
bool isInvisibleToCallerAfterRet (const Value *V) {
@@ -1368,7 +1377,7 @@ struct DSEState {
1368
1377
KillingOffset, DeadOffset);
1369
1378
// If Current does not write to the same object as KillingDef, check
1370
1379
// the next candidate.
1371
- if (OR == OW_Unknown)
1380
+ if (OR == OW_Unknown || OR == OW_None )
1372
1381
continue ;
1373
1382
else if (OR == OW_MaybePartial) {
1374
1383
// If KillingDef only partially overwrites Current, check the next
@@ -1377,6 +1386,7 @@ struct DSEState {
1377
1386
// which are less likely to be removable in the end.
1378
1387
if (PartialLimit <= 1 ) {
1379
1388
WalkerStepLimit -= 1 ;
1389
+ LLVM_DEBUG (dbgs () << " ... reached partial limit ... continue with next access\n " );
1380
1390
continue ;
1381
1391
}
1382
1392
PartialLimit -= 1 ;
0 commit comments