@@ -327,6 +327,7 @@ enum OverwriteResult {
327
327
OW_End,
328
328
OW_PartialEarlierWithFullLater,
329
329
OW_MaybePartial,
330
+ OW_None,
330
331
OW_Unknown
331
332
};
332
333
@@ -934,6 +935,7 @@ struct DSEState {
934
935
// / Return OW_MaybePartial if \p KillingI does not completely overwrite
935
936
// / \p DeadI, but they both write to the same underlying object. In that
936
937
// / case, use isPartialOverwrite to check if \p KillingI partially overwrites
938
+ // / \p DeadI. Returns 'OR_None' if \p KillingI is known to not overwrite the
937
939
// / \p DeadI. Returns 'OW_Unknown' if nothing can be determined.
938
940
OverwriteResult isOverwrite (const Instruction *KillingI,
939
941
const Instruction *DeadI,
@@ -996,8 +998,16 @@ struct DSEState {
996
998
997
999
// If we can't resolve the same pointers to the same object, then we can't
998
1000
// analyze them at all.
999
- if (DeadUndObj != KillingUndObj)
1001
+ if (DeadUndObj != KillingUndObj) {
1002
+ // Non aliasing stores to different objects don't overlap. Note that
1003
+ // if the killing store is known to overwrite whole object (out of
1004
+ // bounds access overwrites whole object as well) then it is assumed to
1005
+ // completely overwrite any store to the same object even if they don't
1006
+ // actually alias (see next check).
1007
+ if (AAR == AliasResult::NoAlias)
1008
+ return OW_None;
1000
1009
return OW_Unknown;
1010
+ }
1001
1011
1002
1012
// If the KillingI store is to a recognizable object, get its size.
1003
1013
uint64_t KillingUndObjSize = getPointerSize (KillingUndObj, DL, TLI, &F);
@@ -1051,9 +1061,8 @@ struct DSEState {
1051
1061
return OW_MaybePartial;
1052
1062
}
1053
1063
1054
- // Can reach here only if accesses are known not to overlap. There is no
1055
- // dedicated code to indicate no overlap so signal "unknown".
1056
- return OW_Unknown;
1064
+ // Can reach here only if accesses are known not to overlap.
1065
+ return OW_None;
1057
1066
}
1058
1067
1059
1068
bool isInvisibleToCallerAfterRet (const Value *V) {
@@ -1451,7 +1460,7 @@ struct DSEState {
1451
1460
KillingOffset, DeadOffset);
1452
1461
// If Current does not write to the same object as KillingDef, check
1453
1462
// the next candidate.
1454
- if (OR == OW_Unknown)
1463
+ if (OR == OW_Unknown || OR == OW_None )
1455
1464
continue ;
1456
1465
else if (OR == OW_MaybePartial) {
1457
1466
// If KillingDef only partially overwrites Current, check the next
@@ -1460,6 +1469,7 @@ struct DSEState {
1460
1469
// which are less likely to be removable in the end.
1461
1470
if (PartialLimit <= 1 ) {
1462
1471
WalkerStepLimit -= 1 ;
1472
+ LLVM_DEBUG (dbgs () << " ... reached partial limit ... continue with next access\n " );
1463
1473
continue ;
1464
1474
}
1465
1475
PartialLimit -= 1 ;
0 commit comments