Skip to content

[Attributor] Improve AAUnderlyingObjects #104835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11901,9 +11901,9 @@ struct AAUnderlyingObjectsImpl
ChangeStatus updateImpl(Attributor &A) override {
auto &Ptr = getAssociatedValue();

bool UsedAssumedInformation = false;
auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
AA::ValueScope Scope) {
bool UsedAssumedInformation = false;
SmallPtrSet<Value *, 8> SeenObjects;
SmallVector<AA::ValueAndContext> Values;

Expand All @@ -11917,31 +11917,43 @@ struct AAUnderlyingObjectsImpl
auto &VAC = Values[I];
auto *Obj = VAC.getValue();
Value *UO = getUnderlyingObject(Obj);
if (UO && UO != VAC.getValue() && SeenObjects.insert(UO).second) {
if (!SeenObjects.insert(UO ? UO : Obj).second)
continue;
if (UO && UO != Obj) {
if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
Changed |= UnderlyingObjects.insert(UO);
continue;
}

const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
*this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
auto Pred = [&Values](Value &V) {
Values.emplace_back(V, nullptr);
auto Pred = [&](Value &V) {
if (&V == UO)
Changed |= UnderlyingObjects.insert(UO);
else
Values.emplace_back(V, nullptr);
return true;
};

if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
llvm_unreachable(
"The forall call should not return false at this position");

UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
continue;
}

if (isa<SelectInst>(Obj)) {
Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope);
Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
UsedAssumedInformation);
continue;
}
if (auto *PHI = dyn_cast<PHINode>(Obj)) {
// Explicitly look through PHIs as we do not care about dynamically
// uniqueness.
for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
Changed |= handleIndirect(A, *PHI->getIncomingValue(u),
UnderlyingObjects, Scope);
Changed |=
handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
Scope, UsedAssumedInformation);
}
continue;
}
Expand All @@ -11955,7 +11967,8 @@ struct AAUnderlyingObjectsImpl
bool Changed = false;
Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);

if (!UsedAssumedInformation)
indicateOptimisticFixpoint();
return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
}

Expand All @@ -11980,7 +11993,7 @@ struct AAUnderlyingObjectsImpl
/// as a phi node or a select instruction.
bool handleIndirect(Attributor &A, Value &V,
SmallSetVector<Value *, 8> &UnderlyingObjects,
AA::ValueScope Scope) {
AA::ValueScope Scope, bool &UsedAssumedInformation) {
bool Changed = false;
const auto *AA = A.getAAFor<AAUnderlyingObjects>(
*this, IRPosition::value(V), DepClassTy::OPTIONAL);
Expand All @@ -11991,6 +12004,7 @@ struct AAUnderlyingObjectsImpl
if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
llvm_unreachable(
"The forall call should not return false at this position");
UsedAssumedInformation |= !AA->getState().isAtFixpoint();
return Changed;
}

Expand Down
39 changes: 19 additions & 20 deletions llvm/test/Transforms/Attributor/call-simplify-pointer-info.ll
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ define i8 @call_simplifiable_1() {
; CGSCC-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CGSCC-NEXT: [[I0:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2
; CGSCC-NEXT: store i8 2, ptr [[I0]], align 2
; CGSCC-NEXT: [[R:%.*]] = call i8 @read_arg(ptr nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I0]]) #[[ATTR4:[0-9]+]]
; CGSCC-NEXT: [[R:%.*]] = call i8 @read_arg(ptr nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I0]]) #[[ATTR3:[0-9]+]]
; CGSCC-NEXT: ret i8 [[R]]
;
entry:
Expand Down Expand Up @@ -77,8 +77,8 @@ define internal i8 @sum_two_same_loads(ptr %p) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
; CGSCC-LABEL: define {{[^@]+}}@sum_two_same_loads
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly dereferenceable(1022) [[P:%.*]]) #[[ATTR2:[0-9]+]] {
; CGSCC-NEXT: [[X:%.*]] = call i8 @read_arg_1(ptr nocapture nofree noundef nonnull readonly dereferenceable(1022) [[P]]) #[[ATTR4]]
; CGSCC-NEXT: [[Y:%.*]] = call i8 @read_arg_1(ptr nocapture nofree noundef nonnull readonly dereferenceable(1022) [[P]]) #[[ATTR4]]
; CGSCC-NEXT: [[X:%.*]] = call i8 @read_arg_1(ptr nocapture nofree noundef nonnull readonly dereferenceable(1022) [[P]]) #[[ATTR3]]
; CGSCC-NEXT: [[Y:%.*]] = call i8 @read_arg_1(ptr nocapture nofree noundef nonnull readonly dereferenceable(1022) [[P]]) #[[ATTR3]]
; CGSCC-NEXT: [[Z:%.*]] = add nsw i8 [[X]], [[Y]]
; CGSCC-NEXT: ret i8 [[Z]]
;
Expand Down Expand Up @@ -107,7 +107,7 @@ define i8 @call_simplifiable_2() {
; CGSCC-NEXT: store i8 2, ptr [[I0]], align 2
; CGSCC-NEXT: [[I1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 3
; CGSCC-NEXT: store i8 3, ptr [[I1]], align 1
; CGSCC-NEXT: [[R:%.*]] = call i8 @sum_two_same_loads(ptr nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I0]]) #[[ATTR4]]
; CGSCC-NEXT: [[R:%.*]] = call i8 @sum_two_same_loads(ptr nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I0]]) #[[ATTR3]]
; CGSCC-NEXT: ret i8 [[R]]
;
entry:
Expand Down Expand Up @@ -136,7 +136,7 @@ define i8 @call_simplifiable_3() {
; CGSCC-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CGSCC-NEXT: [[I2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 2
; CGSCC-NEXT: store i8 2, ptr [[I2]], align 2
; CGSCC-NEXT: [[R:%.*]] = call i8 @read_arg_index(ptr nocapture nofree noundef nonnull readonly align 16 dereferenceable(1024) [[BYTES]]) #[[ATTR4]]
; CGSCC-NEXT: [[R:%.*]] = call i8 @read_arg_index(ptr nocapture nofree noundef nonnull readonly align 16 dereferenceable(1024) [[BYTES]]) #[[ATTR3]]
; CGSCC-NEXT: ret i8 [[R]]
;
entry:
Expand Down Expand Up @@ -174,16 +174,16 @@ define internal i8 @sum_two_different_loads(ptr %p, ptr %q) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
; TUNIT-LABEL: define {{[^@]+}}@sum_two_different_loads
; TUNIT-SAME: (ptr nocapture nofree nonnull readonly dereferenceable(972) [[P:%.*]], ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[Q:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: [[X:%.*]] = call i8 @read_arg_2(ptr nocapture nofree noundef nonnull readonly dereferenceable(972) [[P]]) #[[ATTR3:[0-9]+]]
; TUNIT-NEXT: [[Y:%.*]] = call i8 @read_arg_2(ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[Q]]) #[[ATTR3]]
; TUNIT-NEXT: [[X:%.*]] = call i8 @read_arg_2(ptr nocapture nofree noundef nonnull readonly dereferenceable(972) [[P]]) #[[ATTR2:[0-9]+]]
; TUNIT-NEXT: [[Y:%.*]] = call i8 @read_arg_2(ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[Q]]) #[[ATTR2]]
; TUNIT-NEXT: [[Z:%.*]] = add nsw i8 [[X]], [[Y]]
; TUNIT-NEXT: ret i8 [[Z]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
; CGSCC-LABEL: define {{[^@]+}}@sum_two_different_loads
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly dereferenceable(972) [[P:%.*]], ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[Q:%.*]]) #[[ATTR2]] {
; CGSCC-NEXT: [[X:%.*]] = call i8 @read_arg_2(ptr nocapture nofree noundef nonnull readonly dereferenceable(972) [[P]]) #[[ATTR4]]
; CGSCC-NEXT: [[Y:%.*]] = call i8 @read_arg_2(ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[Q]]) #[[ATTR4]]
; CGSCC-NEXT: [[X:%.*]] = call i8 @read_arg_2(ptr nocapture nofree noundef nonnull readonly dereferenceable(972) [[P]]) #[[ATTR3]]
; CGSCC-NEXT: [[Y:%.*]] = call i8 @read_arg_2(ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[Q]]) #[[ATTR3]]
; CGSCC-NEXT: [[Z:%.*]] = add nsw i8 [[X]], [[Y]]
; CGSCC-NEXT: ret i8 [[Z]]
;
Expand All @@ -204,7 +204,7 @@ define i8 @call_partially_simplifiable_1() {
; TUNIT-NEXT: [[I3:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 3
; TUNIT-NEXT: store i8 3, ptr [[I3]], align 1
; TUNIT-NEXT: [[I4:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 4
; TUNIT-NEXT: [[R:%.*]] = call i8 @sum_two_different_loads(ptr nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I2]], ptr nocapture nofree noundef nonnull readonly dereferenceable(1021) [[I3]]) #[[ATTR3]]
; TUNIT-NEXT: [[R:%.*]] = call i8 @sum_two_different_loads(ptr nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I2]], ptr nocapture nofree noundef nonnull readonly dereferenceable(1021) [[I3]]) #[[ATTR3:[0-9]+]]
; TUNIT-NEXT: ret i8 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
Expand All @@ -218,7 +218,7 @@ define i8 @call_partially_simplifiable_1() {
; CGSCC-NEXT: store i8 3, ptr [[I3]], align 1
; CGSCC-NEXT: [[I4:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 4
; CGSCC-NEXT: store i8 4, ptr [[I4]], align 4
; CGSCC-NEXT: [[R:%.*]] = call i8 @sum_two_different_loads(ptr nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I2]], ptr nocapture nofree noundef nonnull readonly dereferenceable(1021) [[I3]]) #[[ATTR4]]
; CGSCC-NEXT: [[R:%.*]] = call i8 @sum_two_different_loads(ptr nocapture nofree noundef nonnull readonly align 2 dereferenceable(1022) [[I2]], ptr nocapture nofree noundef nonnull readonly dereferenceable(1021) [[I3]]) #[[ATTR3]]
; CGSCC-NEXT: ret i8 [[R]]
;
entry:
Expand All @@ -235,9 +235,9 @@ entry:
}

define i8 @call_partially_simplifiable_2(i1 %cond) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@call_partially_simplifiable_2
; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR2:[0-9]+]] {
; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; TUNIT-NEXT: [[I51:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 51
Expand All @@ -250,9 +250,9 @@ define i8 @call_partially_simplifiable_2(i1 %cond) {
; TUNIT-NEXT: [[R:%.*]] = call i8 @sum_two_different_loads(ptr nocapture nofree nonnull readonly dereferenceable(972) [[SEL]], ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[I53]]) #[[ATTR3]]
; TUNIT-NEXT: ret i8 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@call_partially_simplifiable_2
; CGSCC-SAME: (i1 [[COND:%.*]]) #[[ATTR3:[0-9]+]] {
; CGSCC-SAME: (i1 [[COND:%.*]]) #[[ATTR1]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CGSCC-NEXT: [[I51:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 51
Expand All @@ -263,7 +263,7 @@ define i8 @call_partially_simplifiable_2(i1 %cond) {
; CGSCC-NEXT: [[I54:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 54
; CGSCC-NEXT: store i8 4, ptr [[I54]], align 2
; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[COND]], ptr [[I51]], ptr [[I52]]
; CGSCC-NEXT: [[R:%.*]] = call i8 @sum_two_different_loads(ptr nocapture nofree noundef nonnull readonly dereferenceable(972) [[SEL]], ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[I53]]) #[[ATTR4]]
; CGSCC-NEXT: [[R:%.*]] = call i8 @sum_two_different_loads(ptr nocapture nofree noundef nonnull readonly dereferenceable(972) [[SEL]], ptr nocapture nofree noundef nonnull readonly dereferenceable(971) [[I53]]) #[[ATTR3]]
; CGSCC-NEXT: ret i8 [[R]]
;
entry:
Expand All @@ -284,12 +284,11 @@ entry:
;.
; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(read) }
; TUNIT: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn memory(read) }
; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(read) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: read) }
; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR4]] = { nofree willreturn memory(read) }
; CGSCC: attributes #[[ATTR3]] = { nofree willreturn memory(read) }
;.
24 changes: 10 additions & 14 deletions llvm/test/Transforms/Attributor/multiple-offsets-pointer-info.ll
Original file line number Diff line number Diff line change
Expand Up @@ -267,15 +267,14 @@ entry:
}

define i8 @select_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@select_gep_simplifiable_1
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
; CHECK-NEXT: [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]
; CHECK-NEXT: store i8 42, ptr [[SEL_PTR]], align 4
; CHECK-NEXT: ret i8 21
;
entry:
Expand All @@ -291,9 +290,9 @@ entry:
}

define i8 @select_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@select_gep_not_simplifiable_1
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CHECK-NEXT: [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
Expand All @@ -318,9 +317,9 @@ entry:
; FIXME: The whole function is just "ret i8 21".

define i8 @phi_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_1
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
Expand Down Expand Up @@ -364,9 +363,9 @@ join:
; FIXME: The whole function is just "ret i8 42".

define i8 @phi_gep_simplifiable_2(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_2
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR2]] {
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CHECK-NEXT: br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
Expand All @@ -378,7 +377,6 @@ define i8 @phi_gep_simplifiable_2(i1 %cnd1, i1 %cnd2) {
; CHECK-NEXT: br label [[JOIN]]
; CHECK: join:
; CHECK-NEXT: [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
; CHECK-NEXT: store i8 21, ptr [[PHI_PTR]], align 4
; CHECK-NEXT: ret i8 42
;
entry:
Expand All @@ -405,9 +403,9 @@ join:
}

define i8 @phi_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_1
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR3]] {
; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
; CHECK-NEXT: [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
Expand Down Expand Up @@ -518,8 +516,6 @@ join:
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" }
; CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
; CHECK: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
; CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn }
;.
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CGSCC: {{.*}}
Expand Down
Loading
Loading