Skip to content

Commit 7e6f960

Browse files
committed
Handle may/parital alias and clean up code
1 parent e8163c9 commit 7e6f960

File tree

3 files changed

+44
-22
lines changed

3 files changed

+44
-22
lines changed

llvm/include/llvm/Analysis/AliasAnalysis.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,11 @@ class BatchAAResults {
667667
MemoryLocation(V2, LocationSize::precise(1))) ==
668668
AliasResult::MustAlias;
669669
}
670+
bool isNoAlias(const Value *V1, const Value *V2) {
671+
return alias(MemoryLocation(V1, LocationSize::precise(1)),
672+
MemoryLocation(V2, LocationSize::precise(1))) ==
673+
AliasResult::NoAlias;
674+
}
670675
ModRefInfo callCapturesBefore(const Instruction *I,
671676
const MemoryLocation &MemLoc,
672677
DominatorTree *DT) {

llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -834,9 +834,8 @@ struct MemoryLocationWrapper {
834834
// A memory def wrapper that represents a MemoryDef and the MemoryLocation(s)
835835
// defined by this MemoryDef.
836836
struct MemoryDefWrapper {
837-
MemoryDefWrapper(
838-
MemoryDef *MemDef,
839-
const SmallVectorImpl<std::pair<MemoryLocation, bool>> &MemLocations) {
837+
MemoryDefWrapper(MemoryDef *MemDef,
838+
ArrayRef<std::pair<MemoryLocation, bool>> MemLocations) {
840839
DefInst = MemDef->getMemoryInst();
841840
for (auto &[MemLoc, DefByInitializesAttr] : MemLocations)
842841
DefinedLocations.push_back(
@@ -866,17 +865,16 @@ struct ArgumentInitInfo {
866865
// Return the intersected range list of the initializes attributes of "Args".
867866
// "Args" are call arguments that alias to each other.
868867
// If any argument in "Args" doesn't have dead_on_unwind attr and
869-
// "FuncHasNoUnwindAttr" is false, return empty.
870-
ConstantRangeList
871-
getIntersectedInitRangeList(const SmallVectorImpl<ArgumentInitInfo> &Args,
872-
bool FuncHasNoUnwindAttr) {
868+
// "CallHasNoUnwindAttr" is false, return empty.
869+
ConstantRangeList getIntersectedInitRangeList(ArrayRef<ArgumentInitInfo> Args,
870+
bool CallHasNoUnwindAttr) {
873871
if (Args.empty())
874872
return {};
875873

876874
// To address unwind, the function should have nounwind attribute or the
877875
// arguments have dead_on_unwind attribute. Otherwise, return empty.
878876
for (const auto &Arg : Args) {
879-
if (!FuncHasNoUnwindAttr && !Arg.HasDeadOnUnwindAttr)
877+
if (!CallHasNoUnwindAttr && !Arg.HasDeadOnUnwindAttr)
880878
return {};
881879
if (Arg.Inits.empty())
882880
return {};
@@ -885,14 +883,14 @@ getIntersectedInitRangeList(const SmallVectorImpl<ArgumentInitInfo> &Args,
885883
if (Args.size() == 1)
886884
return Args[0].Inits;
887885

888-
ConstantRangeList IntersectedIntervals = Args[0].Inits;
889-
for (size_t I = 1, Count = Args.size(); I < Count; ++I)
890-
IntersectedIntervals = IntersectedIntervals.intersectWith(Args[I].Inits);
886+
ConstantRangeList IntersectedIntervals = Args.front().Inits;
887+
for (auto &Arg : Args.drop_front())
888+
IntersectedIntervals = IntersectedIntervals.intersectWith(Arg.Inits);
891889

892890
return IntersectedIntervals;
893891
}
894892

895-
// Return the locations wrote by the initializes attribute.
893+
// Return the locations written by the initializes attribute.
896894
// Note that this function considers:
897895
// 1. Unwind edge: apply "initializes" attribute only if the callee has
898896
// "nounwind" attribute or the argument has "dead_on_unwind" attribute.
@@ -908,19 +906,20 @@ getInitializesArgMemLoc(const Instruction *I, BatchAAResults &BatchAA) {
908906
SmallMapVector<Value *, SmallVector<ArgumentInitInfo, 2>, 2> Arguments;
909907
for (unsigned Idx = 0, Count = CB->arg_size(); Idx < Count; ++Idx) {
910908
ConstantRangeList Inits;
911-
if (CB->paramHasAttr(Idx, Attribute::Initializes))
912-
Inits = CB->getParamAttr(Idx, Attribute::Initializes)
913-
.getValueAsConstantRangeList();
909+
Attribute InitializesAttr = CB->getParamAttr(Idx, Attribute::Initializes);
910+
if (InitializesAttr.isValid())
911+
Inits = InitializesAttr.getValueAsConstantRangeList();
914912

915913
bool HasDeadOnUnwindAttr = CB->paramHasAttr(Idx, Attribute::DeadOnUnwind);
916914
ArgumentInitInfo InitInfo{Idx, HasDeadOnUnwindAttr, Inits};
917915
Value *CurArg = CB->getArgOperand(Idx);
918916
bool FoundAliasing = false;
919917
for (auto &[Arg, AliasList] : Arguments) {
920-
if (BatchAA.isMustAlias(Arg, CurArg)) {
921-
FoundAliasing = true;
922-
AliasList.push_back(InitInfo);
923-
}
918+
if (BatchAA.isNoAlias(Arg, CurArg))
919+
continue;
920+
// Conservatively consider must/may/partial-alias as aliasing.
921+
FoundAliasing = true;
922+
AliasList.push_back(InitInfo);
924923
}
925924
if (!FoundAliasing)
926925
Arguments[CurArg] = {InitInfo};
@@ -929,7 +928,7 @@ getInitializesArgMemLoc(const Instruction *I, BatchAAResults &BatchAA) {
929928
SmallVector<MemoryLocation, 1> Locations;
930929
for (const auto &[_, Args] : Arguments) {
931930
auto IntersectedRanges =
932-
getIntersectedInitRangeList(Args, CB->hasFnAttr(Attribute::NoUnwind));
931+
getIntersectedInitRangeList(Args, CB->doesNotThrow());
933932
if (IntersectedRanges.empty())
934933
continue;
935934

@@ -1736,9 +1735,8 @@ struct DSEState {
17361735
bool IsKillingDefFromInitAttr = false;
17371736
if (IsInitializesAttrMemLoc) {
17381737
if (KillingI == UseInst &&
1739-
KillingUndObj == getUnderlyingObject(MaybeDeadLoc.Ptr)) {
1738+
KillingUndObj == getUnderlyingObject(MaybeDeadLoc.Ptr))
17401739
IsKillingDefFromInitAttr = true;
1741-
}
17421740
}
17431741

17441742
if (isReadClobber(MaybeDeadLoc, UseInst) && !IsKillingDefFromInitAttr) {

llvm/test/Transforms/DeadStoreElimination/inter-procedural.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
declare void @p1_write_only(ptr nocapture noundef writeonly initializes((0, 2)) dead_on_unwind)
55
declare void @p1_write_then_read(ptr nocapture noundef initializes((0, 2)) dead_on_unwind)
6+
declare void @p1_clobber(ptr nocapture noundef)
67
declare void @p2_same_range(ptr nocapture noundef initializes((0, 2)) dead_on_unwind, ptr nocapture noundef initializes((0, 2)) dead_on_unwind)
78
declare void @p2_no_init(ptr nocapture noundef initializes((0, 2)) dead_on_unwind, ptr nocapture noundef dead_on_unwind)
89
declare void @p2_no_dead_on_unwind(ptr nocapture noundef initializes((0, 2)) dead_on_unwind, ptr nocapture noundef initializes((0, 2)))
@@ -38,6 +39,24 @@ define i16 @p1_write_then_read_caller() {
3839
ret i16 %l
3940
}
4041

42+
; Function Attrs: mustprogress nounwind uwtable
43+
define i16 @p1_write_then_read_caller_with_clobber() {
44+
; CHECK-LABEL: @p1_write_then_read_caller_with_clobber(
45+
; CHECK-NEXT: %ptr = alloca i16, align 2
46+
; CHECK-NEXT: store i16 0, ptr %ptr
47+
; CHECK-NEXT: call void @p1_clobber(ptr %ptr)
48+
; CHECK-NEXT: call void @p1_write_then_read(ptr %ptr)
49+
; CHECK-NEXT: %l = load i16, ptr %ptr
50+
; CHECK-NEXT: ret i16 %l
51+
;
52+
%ptr = alloca i16
53+
store i16 0, ptr %ptr
54+
call void @p1_clobber(ptr %ptr)
55+
call void @p1_write_then_read(ptr %ptr)
56+
%l = load i16, ptr %ptr
57+
ret i16 %l
58+
}
59+
4160
; Function Attrs: mustprogress nounwind uwtable
4261
define i16 @p2_same_range_nonalias_caller() {
4362
; CHECK-LABEL: @p2_same_range_nonalias_caller(

0 commit comments

Comments
 (0)