[llvm] 84bf0da - [Attributor][FIX] Ensure to always translate call site arguments (#107323)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 5 13:37:24 PDT 2024
Author: Johannes Doerfert
Date: 2024-09-05T13:37:21-07:00
New Revision: 84bf0da34dd020090e05816fcbda305d1f422c27
URL: https://github.com/llvm/llvm-project/commit/84bf0da34dd020090e05816fcbda305d1f422c27
DIFF: https://github.com/llvm/llvm-project/commit/84bf0da34dd020090e05816fcbda305d1f422c27.diff
LOG: [Attributor][FIX] Ensure to always translate call site arguments (#107323)
When we propagate call site arguments we always need to translate them,
this is important as we ended up picking the function argument for a
recurisve call not the call site argument. `@recBad` and `@recGood` in
`returned.ll` show the problem as they used to transform them the same
way. The restructuring cleans the code up and helps derive more
"returned" arguments and better information in the presence of recursive
calls. The "dropped" attributes are simply dropped because we do not
query them anymore, not because we cannot derive them.
Added:
Modified:
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
llvm/test/Transforms/Attributor/align.ll
llvm/test/Transforms/Attributor/memory_locations.ll
llvm/test/Transforms/Attributor/range.ll
llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll
llvm/test/Transforms/Attributor/returned.ll
llvm/test/Transforms/OpenMP/replace_globalization.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 6b6d6d8d2a1e45..1fe8e6515fe0e8 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -11516,9 +11516,21 @@ struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
return false;
if (!AddValues)
continue;
- for (const AA::ValueAndContext &VAC : Values)
+
+ bool AllInterAreIntra = false;
+ if (S == AA::Interprocedural)
+ AllInterAreIntra =
+ llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
+ return AA::isValidInScope(*VAC.getValue(), AnchorScope);
+ });
+
+ for (const AA::ValueAndContext &VAC : Values) {
addValue(A, getState(), *VAC.getValue(),
- VAC.getCtxI() ? VAC.getCtxI() : CtxI, S, AnchorScope);
+ VAC.getCtxI() ? VAC.getCtxI() : CtxI,
+ AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
+ }
+ if (AllInterAreIntra)
+ break;
}
return true;
};
@@ -11547,16 +11559,6 @@ struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
: ChangeStatus::CHANGED;
}
- void addValue(Attributor &A, StateType &State, Value &V,
- const Instruction *CtxI, AA::ValueScope S,
- Function *AnchorScope) const override {
- Function *F = getAssociatedFunction();
- if (auto *CB = dyn_cast<CallBase>(&V))
- if (CB->getCalledOperand() == F)
- return;
- Base::addValue(A, State, V, CtxI, S, AnchorScope);
- }
-
ChangeStatus manifest(Attributor &A) override {
if (ReturnedArg)
return ChangeStatus::UNCHANGED;
@@ -11651,64 +11653,39 @@ struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
UsedAssumedInformation))
return indicatePessimisticFixpoint();
- SmallVector<AA::ValueAndContext> Values;
- if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
- Values, AA::Intraprocedural,
- UsedAssumedInformation))
- return indicatePessimisticFixpoint();
-
Function *Caller = CB->getCaller();
- bool AnyNonLocal = false;
- for (auto &It : Values) {
- Value *V = It.getValue();
- std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
- V, *CB, *this, UsedAssumedInformation);
- if (!CallerV.has_value()) {
- // Nothing to do as long as no value was determined.
- continue;
- }
- V = *CallerV ? *CallerV : V;
- if (AA::isDynamicallyUnique(A, *this, *V) &&
- AA::isValidInScope(*V, Caller)) {
- if (*CallerV) {
- SmallVector<AA::ValueAndContext> ArgValues;
- IRPosition IRP = IRPosition::value(*V);
- if (auto *Arg = dyn_cast<Argument>(V))
- if (Arg->getParent() == CB->getCalledOperand())
- IRP = IRPosition::callsite_argument(*CB, Arg->getArgNo());
- if (recurseForValue(A, IRP, AA::AnyScope))
- continue;
- }
- addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope());
- } else {
- AnyNonLocal = true;
- break;
- }
- }
- if (AnyNonLocal) {
- Values.clear();
+ auto AddScope = [&](AA::ValueScope S) {
+ SmallVector<AA::ValueAndContext> Values;
if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
- Values, AA::Interprocedural,
- UsedAssumedInformation))
- return indicatePessimisticFixpoint();
- AnyNonLocal = false;
- getState() = PotentialLLVMValuesState::getBestState();
+ Values, S, UsedAssumedInformation))
+ return false;
+
for (auto &It : Values) {
Value *V = It.getValue();
- if (!AA::isDynamicallyUnique(A, *this, *V))
- return indicatePessimisticFixpoint();
- if (AA::isValidInScope(*V, Caller)) {
- addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope());
- } else {
- AnyNonLocal = true;
- addValue(A, getState(), *V, CB, AA::Interprocedural,
- getAnchorScope());
+ std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
+ V, *CB, *this, UsedAssumedInformation);
+ if (!CallerV.has_value()) {
+ // Nothing to do as long as no value was determined.
+ continue;
+ }
+ V = *CallerV ? *CallerV : V;
+ if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
+ if (recurseForValue(A, IRPosition::value(*V), S))
+ continue;
+ }
+ if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
+ giveUpOnIntraprocedural(A);
+ return true;
}
+ addValue(A, getState(), *V, CB, S, getAnchorScope());
}
- if (AnyNonLocal)
- giveUpOnIntraprocedural(A);
- }
+ return true;
+ };
+ if (!AddScope(AA::Intraprocedural))
+ return indicatePessimisticFixpoint();
+ if (!AddScope(AA::Interprocedural))
+ return indicatePessimisticFixpoint();
return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
: ChangeStatus::CHANGED;
}
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
index 35d0eeac50d516..f673ffc3bfac6d 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
@@ -16,8 +16,7 @@ define void @fn2(ptr %P, i1 %C) {
; TUNIT: if.end:
; TUNIT-NEXT: [[E_2:%.*]] = phi ptr [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[E_2]], align 4
-; TUNIT-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]]) #[[ATTR3:[0-9]+]]
-; TUNIT-NEXT: store i32 [[CALL]], ptr [[P]], align 4
+; TUNIT-NEXT: store i32 [[TMP0]], ptr [[P]], align 4
; TUNIT-NEXT: br label [[FOR_COND1]]
; TUNIT: exit:
; TUNIT-NEXT: ret void
@@ -55,11 +54,11 @@ exit:
}
define internal i32 @fn1(i32 %p1) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
-; CHECK-LABEL: define {{[^@]+}}@fn1
-; CHECK-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 [[P1]]
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@fn1
+; CGSCC-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
+; CGSCC-NEXT: entry:
+; CGSCC-NEXT: ret i32 [[P1]]
;
entry:
%tobool = icmp ne i32 %p1, 0
@@ -71,7 +70,7 @@ define void @fn_no_null_opt(ptr %P, i1 %C) null_pointer_is_valid {
;
; TUNIT: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid
; TUNIT-LABEL: define {{[^@]+}}@fn_no_null_opt
-; TUNIT-SAME: (ptr nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
+; TUNIT-SAME: (ptr nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: br label [[IF_END:%.*]]
; TUNIT: for.cond1:
@@ -79,8 +78,7 @@ define void @fn_no_null_opt(ptr %P, i1 %C) null_pointer_is_valid {
; TUNIT: if.end:
; TUNIT-NEXT: [[E_2:%.*]] = phi ptr [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr null, align 4294967296
-; TUNIT-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) #[[ATTR3]]
-; TUNIT-NEXT: store i32 [[CALL]], ptr [[P]], align 4
+; TUNIT-NEXT: store i32 [[TMP0]], ptr [[P]], align 4
; TUNIT-NEXT: br label [[FOR_COND1]]
; TUNIT: exit:
; TUNIT-NEXT: ret void
@@ -118,11 +116,11 @@ exit:
}
define internal i32 @fn0(i32 %p1) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
-; CHECK-LABEL: define {{[^@]+}}@fn0
-; CHECK-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 [[P1]]
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@fn0
+; CGSCC-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
+; CGSCC-NEXT: entry:
+; CGSCC-NEXT: ret i32 [[P1]]
;
entry:
%tobool = icmp ne i32 %p1, 0
@@ -131,12 +129,12 @@ entry:
}
;.
; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind memory(argmem: readwrite) }
-; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
-; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind null_pointer_is_valid }
-; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind memory(none) }
+; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid }
;.
; CGSCC: attributes #[[ATTR0]] = { nofree nosync nounwind memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR2]] = { nofree nosync nounwind null_pointer_is_valid }
; CGSCC: attributes #[[ATTR3]] = { nofree nosync }
;.
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll
index 9880e53fd43a59..0a0cd415a2ab7e 100644
--- a/llvm/test/Transforms/Attributor/align.ll
+++ b/llvm/test/Transforms/Attributor/align.ll
@@ -416,14 +416,14 @@ define void @test9_traversal(i1 %cnd, ptr align 4 %B, ptr align 8 %C) {
; FIXME: This will work with an upcoming patch (D66618 or similar)
; store i32 -1, ptr %g1, align 32
define ptr @test10a(ptr align 32 %p) {
-; TUNIT: Function Attrs: nofree nosync nounwind
+; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@test10a
; TUNIT-SAME: (ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3:[0-9]+]] {
; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 32
; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
-; TUNIT-NEXT: [[R:%.*]] = call align 32 ptr @test10a(ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]]
+; TUNIT-NEXT: [[R:%.*]] = call align 32 ptr @test10a(ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR13:[0-9]+]]
; TUNIT-NEXT: store i32 1, ptr [[R]], align 32
; TUNIT-NEXT: [[G0:%.*]] = getelementptr i32, ptr [[P]], i32 8
; TUNIT-NEXT: br label [[E:%.*]]
@@ -435,14 +435,14 @@ define ptr @test10a(ptr align 32 %p) {
; TUNIT-NEXT: [[PHI:%.*]] = phi ptr [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
; TUNIT-NEXT: ret ptr [[PHI]]
;
-; CGSCC: Function Attrs: nofree nosync nounwind
+; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@test10a
; CGSCC-SAME: (ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4:[0-9]+]] {
; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 32
; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
-; CGSCC-NEXT: [[R:%.*]] = call align 32 ptr @test10a(ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]]
+; CGSCC-NEXT: [[R:%.*]] = call align 32 ptr @test10a(ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR16:[0-9]+]]
; CGSCC-NEXT: store i32 1, ptr [[R]], align 32
; CGSCC-NEXT: [[G0:%.*]] = getelementptr i32, ptr [[P]], i32 8
; CGSCC-NEXT: br label [[E:%.*]]
@@ -478,14 +478,14 @@ e:
; FIXME: This will work with an upcoming patch (D66618 or similar)
; store i32 -1, ptr %g1, align 32
define ptr @test10b(ptr align 32 %p) {
-; TUNIT: Function Attrs: nofree nosync nounwind
+; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@test10b
; TUNIT-SAME: (ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 32
; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
-; TUNIT-NEXT: [[R:%.*]] = call align 32 ptr @test10b(ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]]
+; TUNIT-NEXT: [[R:%.*]] = call align 32 ptr @test10b(ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR13]]
; TUNIT-NEXT: store i32 1, ptr [[R]], align 32
; TUNIT-NEXT: [[G0:%.*]] = getelementptr i32, ptr [[P]], i32 8
; TUNIT-NEXT: br label [[E:%.*]]
@@ -497,14 +497,14 @@ define ptr @test10b(ptr align 32 %p) {
; TUNIT-NEXT: [[PHI:%.*]] = phi ptr [ [[G0]], [[T]] ], [ [[G1]], [[F]] ]
; TUNIT-NEXT: ret ptr [[PHI]]
;
-; CGSCC: Function Attrs: nofree nosync nounwind
+; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@test10b
; CGSCC-SAME: (ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] {
; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 32
; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
-; CGSCC-NEXT: [[R:%.*]] = call align 32 ptr @test10b(ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]]
+; CGSCC-NEXT: [[R:%.*]] = call align 32 ptr @test10b(ptr nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR16]]
; CGSCC-NEXT: store i32 1, ptr [[R]], align 32
; CGSCC-NEXT: [[G0:%.*]] = getelementptr i32, ptr [[P]], i32 8
; CGSCC-NEXT: br label [[E:%.*]]
@@ -946,7 +946,7 @@ define i32 @musttail_caller_1(ptr %p) {
; TUNIT-NEXT: [[C:%.*]] = load i1, ptr @cnd, align 1
; TUNIT-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
; TUNIT: mt:
-; TUNIT-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(ptr nocapture nofree noundef readonly [[P]]) #[[ATTR13:[0-9]+]]
+; TUNIT-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(ptr nocapture nofree noundef readonly [[P]]) #[[ATTR14:[0-9]+]]
; TUNIT-NEXT: ret i32 [[V]]
; TUNIT: exit:
; TUNIT-NEXT: ret i32 0
@@ -957,7 +957,7 @@ define i32 @musttail_caller_1(ptr %p) {
; CGSCC-NEXT: [[C:%.*]] = load i1, ptr @cnd, align 1
; CGSCC-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
; CGSCC: mt:
-; CGSCC-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(ptr nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR16:[0-9]+]]
+; CGSCC-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(ptr nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR17:[0-9]+]]
; CGSCC-NEXT: ret i32 [[V]]
; CGSCC: exit:
; CGSCC-NEXT: ret i32 0
@@ -1089,7 +1089,7 @@ define ptr @aligned_8_return_caller(ptr align(16) %a, i1 %c1, i1 %c2) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@aligned_8_return_caller
; TUNIT-SAME: (ptr nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] {
-; TUNIT-NEXT: [[R:%.*]] = call align 8 ptr @aligned_8_return(ptr noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 noundef [[C1]], i1 [[C2]]) #[[ATTR14:[0-9]+]]
+; TUNIT-NEXT: [[R:%.*]] = call align 8 ptr @aligned_8_return(ptr noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 noundef [[C1]], i1 [[C2]]) #[[ATTR15:[0-9]+]]
; TUNIT-NEXT: ret ptr [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
@@ -1221,7 +1221,7 @@ attributes #2 = { null_pointer_is_valid }
; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable }
; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree noinline nosync nounwind willreturn memory(none) uwtable }
; TUNIT: attributes #[[ATTR2]] = { nounwind }
-; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind }
+; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind memory(argmem: readwrite) }
; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
; TUNIT: attributes #[[ATTR6]] = { nounwind willreturn }
@@ -1231,14 +1231,15 @@ attributes #2 = { null_pointer_is_valid }
; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read) }
; TUNIT: attributes #[[ATTR12]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) }
-; TUNIT: attributes #[[ATTR13]] = { nofree nosync nounwind willreturn memory(read) }
-; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn }
+; TUNIT: attributes #[[ATTR13]] = { nofree nosync nounwind }
+; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn memory(read) }
+; TUNIT: attributes #[[ATTR15]] = { nofree nosync nounwind willreturn }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree noinline nosync nounwind willreturn memory(none) uwtable }
; CGSCC: attributes #[[ATTR2]] = { noinline nounwind uwtable }
; CGSCC: attributes #[[ATTR3]] = { nounwind }
-; CGSCC: attributes #[[ATTR4]] = { nofree nosync nounwind }
+; CGSCC: attributes #[[ATTR4]] = { nofree nosync nounwind memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
; CGSCC: attributes #[[ATTR7]] = { nounwind willreturn }
@@ -1250,5 +1251,6 @@ attributes #2 = { null_pointer_is_valid }
; CGSCC: attributes #[[ATTR13]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR14]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR15]] = { nofree nosync willreturn }
-; CGSCC: attributes #[[ATTR16]] = { nofree willreturn memory(read) }
+; CGSCC: attributes #[[ATTR16]] = { nofree nosync nounwind }
+; CGSCC: attributes #[[ATTR17]] = { nofree willreturn memory(read) }
;.
diff --git a/llvm/test/Transforms/Attributor/memory_locations.ll b/llvm/test/Transforms/Attributor/memory_locations.ll
index 2dbdf9e6048c0f..a7d3fba9cf9b81 100644
--- a/llvm/test/Transforms/Attributor/memory_locations.ll
+++ b/llvm/test/Transforms/Attributor/memory_locations.ll
@@ -35,7 +35,7 @@ define dso_local ptr @internal_only_rec(i32 %arg) {
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[ARG]], 2
-; CHECK-NEXT: [[CALL:%.*]] = call noalias ptr @internal_only_rec(i32 [[DIV]])
+; CHECK-NEXT: [[CALL:%.*]] = call ptr @internal_only_rec(i32 [[DIV]])
; CHECK-NEXT: br label [[RETURN:%.*]]
; CHECK: if.end:
; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll
index 9b2f9ed2dde919..48040fec772dc0 100644
--- a/llvm/test/Transforms/Attributor/range.ll
+++ b/llvm/test/Transforms/Attributor/range.ll
@@ -48,7 +48,7 @@ define void @test0-icmp-check(ptr %p){
; ret = [0, 10)
; TUNIT-LABEL: define {{[^@]+}}@test0-icmp-check
; TUNIT-SAME: (ptr nocapture nofree readonly align 4 [[P:%.*]]) {
-; TUNIT-NEXT: [[RET:%.*]] = tail call i32 @test0(ptr nocapture nofree noundef readonly align 4 [[P]]) #[[ATTR3]], !range [[RNG0]]
+; TUNIT-NEXT: [[RET:%.*]] = tail call i32 @test0(ptr nocapture nofree noundef readonly align 4 [[P]]) #[[ATTR3]]
; TUNIT-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
; TUNIT-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
; TUNIT-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
diff --git a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll
index 81530e91648996..775c949ca8939c 100644
--- a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll
+++ b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll
@@ -64,7 +64,7 @@ entry:
define internal ptr @internal_ret0_nw(ptr %n0, ptr %w0) {
; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@internal_ret0_nw
-; TUNIT-SAME: (ptr nofree [[N0:%.*]], ptr nofree [[W0:%.*]]) #[[ATTR0]] {
+; TUNIT-SAME: (ptr nofree returned [[N0:%.*]], ptr nofree [[W0:%.*]]) #[[ATTR0]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[R0:%.*]] = alloca i32, align 4
; TUNIT-NEXT: [[R1:%.*]] = alloca i32, align 4
@@ -84,12 +84,12 @@ define internal ptr @internal_ret0_nw(ptr %n0, ptr %w0) {
; TUNIT-NEXT: [[CALL5:%.*]] = call ptr @internal_ret0_nw(ptr nofree nonnull [[N0]], ptr nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]]
; TUNIT-NEXT: br label [[RETURN]]
; TUNIT: return:
-; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
-; TUNIT-NEXT: ret ptr [[RETVAL_0]]
+; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[N0]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
+; TUNIT-NEXT: ret ptr [[N0]]
;
; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@internal_ret0_nw
-; CGSCC-SAME: (ptr nofree [[N0:%.*]], ptr nofree [[W0:%.*]]) #[[ATTR0]] {
+; CGSCC-SAME: (ptr nofree returned [[N0:%.*]], ptr nofree [[W0:%.*]]) #[[ATTR0]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[R0:%.*]] = alloca i32, align 4
; CGSCC-NEXT: [[R1:%.*]] = alloca i32, align 4
@@ -109,8 +109,8 @@ define internal ptr @internal_ret0_nw(ptr %n0, ptr %w0) {
; CGSCC-NEXT: [[CALL5:%.*]] = call ptr @internal_ret0_nw(ptr nofree nonnull [[N0]], ptr nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
; CGSCC-NEXT: br label [[RETURN]]
; CGSCC: return:
-; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
-; CGSCC-NEXT: ret ptr [[RETVAL_0]]
+; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[N0]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
+; CGSCC-NEXT: ret ptr [[N0]]
;
entry:
%r0 = alloca i32, align 4
@@ -164,7 +164,7 @@ define internal ptr @internal_ret1_rrw(ptr %r0, ptr %r1, ptr %w0) {
; TUNIT-NEXT: [[CALL8:%.*]] = call ptr @internal_ret0_nw(ptr nofree nonnull align 4 dereferenceable(4) [[R1]], ptr nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]]
; TUNIT-NEXT: br label [[RETURN]]
; TUNIT: return:
-; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[CALL8]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
+; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[R1]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
; TUNIT-NEXT: ret ptr undef
;
; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
@@ -192,7 +192,7 @@ define internal ptr @internal_ret1_rrw(ptr %r0, ptr %r1, ptr %w0) {
; CGSCC-NEXT: [[CALL8:%.*]] = call ptr @internal_ret0_nw(ptr nofree nonnull align 4 dereferenceable(4) [[R1]], ptr nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
; CGSCC-NEXT: br label [[RETURN]]
; CGSCC: return:
-; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[CALL8]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
+; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[R1]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
; CGSCC-NEXT: ret ptr undef
;
entry:
@@ -259,7 +259,7 @@ return: ; preds = %if.end, %if.then
define internal ptr @internal_ret1_rw(ptr %r0, ptr %w0) {
; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@internal_ret1_rw
-; TUNIT-SAME: (ptr nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], ptr nofree [[W0:%.*]]) #[[ATTR0]] {
+; TUNIT-SAME: (ptr nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], ptr nofree returned [[W0:%.*]]) #[[ATTR0]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[R0]], align 4
; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
@@ -276,12 +276,12 @@ define internal ptr @internal_ret1_rw(ptr %r0, ptr %w0) {
; TUNIT-NEXT: [[CALL4:%.*]] = call ptr @external_ret2_nrw(ptr nofree noundef nonnull align 4 dereferenceable(4) [[R0]], ptr nofree noundef nonnull align 4 dereferenceable(4) [[R0]], ptr nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]]
; TUNIT-NEXT: br label [[RETURN]]
; TUNIT: return:
-; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[CALL4]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
-; TUNIT-NEXT: ret ptr [[RETVAL_0]]
+; TUNIT-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[W0]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
+; TUNIT-NEXT: ret ptr [[W0]]
;
; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@internal_ret1_rw
-; CGSCC-SAME: (ptr nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], ptr nofree [[W0:%.*]]) #[[ATTR0]] {
+; CGSCC-SAME: (ptr nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], ptr nofree returned [[W0:%.*]]) #[[ATTR0]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[R0]], align 4
; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
@@ -298,8 +298,8 @@ define internal ptr @internal_ret1_rw(ptr %r0, ptr %w0) {
; CGSCC-NEXT: [[CALL4:%.*]] = call ptr @external_ret2_nrw(ptr nofree noundef nonnull align 4 dereferenceable(4) [[R0]], ptr nofree noundef nonnull align 4 dereferenceable(4) [[R0]], ptr nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
; CGSCC-NEXT: br label [[RETURN]]
; CGSCC: return:
-; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[CALL4]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
-; CGSCC-NEXT: ret ptr [[RETVAL_0]]
+; CGSCC-NEXT: [[RETVAL_0:%.*]] = phi ptr [ [[W0]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
+; CGSCC-NEXT: ret ptr [[W0]]
;
entry:
%0 = load i32, ptr %r0, align 4
diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll
index e94cb950696945..bc55a50f0e6f77 100644
--- a/llvm/test/Transforms/Attributor/returned.ll
+++ b/llvm/test/Transforms/Attributor/returned.ll
@@ -483,7 +483,7 @@ define ptr @rt0(ptr %a) #0 {
; TUNIT-LABEL: define {{[^@]+}}@rt0
; TUNIT-SAME: (ptr nofree noundef nonnull readonly returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR3:[0-9]+]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[CALL:%.*]] = call ptr @rt0(ptr nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR9:[0-9]+]]
+; TUNIT-NEXT: [[CALL:%.*]] = call ptr @rt0(ptr nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR10:[0-9]+]]
; TUNIT-NEXT: ret ptr [[A]]
;
; CGSCC: Function Attrs: nofree noinline nosync nounwind memory(argmem: read) uwtable
@@ -667,7 +667,7 @@ define ptr @calls_unknown_fn(ptr %r) #0 {
; TUNIT: Function Attrs: noinline nounwind uwtable
; TUNIT-LABEL: define {{[^@]+}}@calls_unknown_fn
; TUNIT-SAME: (ptr nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR5:[0-9]+]] {
-; TUNIT-NEXT: tail call void @unknown_fn(ptr noundef nonnull @calls_unknown_fn) #[[ATTR10:[0-9]+]]
+; TUNIT-NEXT: tail call void @unknown_fn(ptr noundef nonnull @calls_unknown_fn) #[[ATTR11:[0-9]+]]
; TUNIT-NEXT: ret ptr [[R]]
;
; CGSCC: Function Attrs: noinline nounwind uwtable
@@ -716,7 +716,7 @@ define ptr @calls_maybe_redefined_fn(ptr %r) #0 {
; TUNIT-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn
; TUNIT-SAME: (ptr returned [[R:%.*]]) #[[ATTR5]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[CALL:%.*]] = call ptr @maybe_redefined_fn(ptr [[R]]) #[[ATTR10]]
+; TUNIT-NEXT: [[CALL:%.*]] = call ptr @maybe_redefined_fn(ptr [[R]]) #[[ATTR11]]
; TUNIT-NEXT: ret ptr [[R]]
;
; CGSCC: Function Attrs: noinline nounwind uwtable
@@ -765,7 +765,7 @@ define ptr @calls_maybe_redefined_fn2(ptr %r) #0 {
; TUNIT-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2
; TUNIT-SAME: (ptr [[R:%.*]]) #[[ATTR5]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[CALL:%.*]] = call ptr @maybe_redefined_fn2(ptr [[R]]) #[[ATTR10]]
+; TUNIT-NEXT: [[CALL:%.*]] = call ptr @maybe_redefined_fn2(ptr [[R]]) #[[ATTR11]]
; TUNIT-NEXT: ret ptr [[CALL]]
;
; CGSCC: Function Attrs: noinline nounwind uwtable
@@ -1451,6 +1451,103 @@ declare dso_local ptr @__dynamic_cast(ptr, ptr, ptr, i64)
; UTC_ARGS: --enable
+; This does not return %arg, @recGood does.
+
+define internal i32 @recBad(i1 %c, i32 %arg) {
+; TUNIT: Function Attrs: nofree nosync nounwind memory(none)
+; TUNIT-LABEL: define {{[^@]+}}@recBad
+; TUNIT-SAME: (i1 noundef [[C:%.*]], i32 [[ARG:%.*]]) #[[ATTR8]] {
+; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[ARG]], 1
+; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; TUNIT: t:
+; TUNIT-NEXT: [[R:%.*]] = call i32 @recBad(i1 noundef false, i32 [[ADD]]) #[[ATTR8]]
+; TUNIT-NEXT: ret i32 [[ADD]]
+; TUNIT: f:
+; TUNIT-NEXT: ret i32 [[ARG]]
+;
+; CGSCC: Function Attrs: nofree nosync nounwind memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@recBad
+; CGSCC-SAME: (i1 noundef [[C:%.*]], i32 [[ARG:%.*]]) #[[ATTR7]] {
+; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[ARG]], 1
+; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; CGSCC: t:
+; CGSCC-NEXT: [[R:%.*]] = call i32 @recBad(i1 noundef false, i32 [[ADD]]) #[[ATTR7]]
+; CGSCC-NEXT: ret i32 [[ADD]]
+; CGSCC: f:
+; CGSCC-NEXT: ret i32 [[ARG]]
+;
+ %add = add i32 %arg, 1
+ br i1 %c, label %t, label %f
+t:
+ %r = call i32 @recBad(i1 false, i32 %add)
+ ret i32 %r
+f:
+ ret i32 %arg
+}
+
+define i32 @recBadCaller(i1 %cQ, i32 %argQ) {
+; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)
+; TUNIT-LABEL: define {{[^@]+}}@recBadCaller
+; TUNIT-SAME: (i1 [[CQ:%.*]], i32 [[ARGQ:%.*]]) #[[ATTR9:[0-9]+]] {
+; TUNIT-NEXT: [[RQ:%.*]] = call i32 @recBad(i1 noundef [[CQ]], i32 [[ARGQ]]) #[[ATTR8]]
+; TUNIT-NEXT: ret i32 [[RQ]]
+;
+; CGSCC: Function Attrs: nofree nosync nounwind memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@recBadCaller
+; CGSCC-SAME: (i1 noundef [[CQ:%.*]], i32 [[ARGQ:%.*]]) #[[ATTR7]] {
+; CGSCC-NEXT: [[RQ:%.*]] = call i32 @recBad(i1 noundef [[CQ]], i32 [[ARGQ]]) #[[ATTR7]]
+; CGSCC-NEXT: ret i32 [[RQ]]
+;
+ %rQ = call i32 @recBad(i1 %cQ, i32 %argQ)
+ ret i32 %rQ
+}
+
+define internal i32 @recGood(i1 %c, i32 %arg) {
+; TUNIT: Function Attrs: nofree nosync nounwind memory(none)
+; TUNIT-LABEL: define {{[^@]+}}@recGood
+; TUNIT-SAME: (i1 noundef [[C:%.*]], i32 returned [[ARG:%.*]]) #[[ATTR8]] {
+; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; TUNIT: t:
+; TUNIT-NEXT: [[R:%.*]] = call i32 @recGood(i1 noundef false, i32 [[ARG]]) #[[ATTR8]]
+; TUNIT-NEXT: ret i32 [[ARG]]
+; TUNIT: f:
+; TUNIT-NEXT: ret i32 [[ARG]]
+;
+; CGSCC: Function Attrs: nofree nosync nounwind memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@recGood
+; CGSCC-SAME: (i1 noundef [[C:%.*]], i32 returned [[ARG:%.*]]) #[[ATTR7]] {
+; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; CGSCC: t:
+; CGSCC-NEXT: [[R:%.*]] = call i32 @recGood(i1 noundef false, i32 [[ARG]]) #[[ATTR7]]
+; CGSCC-NEXT: ret i32 [[ARG]]
+; CGSCC: f:
+; CGSCC-NEXT: ret i32 [[ARG]]
+;
+ br i1 %c, label %t, label %f
+t:
+ %r = call i32 @recGood(i1 false, i32 %arg)
+ ret i32 %r
+f:
+ ret i32 %arg
+}
+
+define i32 @recGoodCaller(i1 %cQ, i32 %argQ) {
+; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)
+; TUNIT-LABEL: define {{[^@]+}}@recGoodCaller
+; TUNIT-SAME: (i1 [[CQ:%.*]], i32 returned [[ARGQ:%.*]]) #[[ATTR9]] {
+; TUNIT-NEXT: [[RQ:%.*]] = call i32 @recGood(i1 noundef [[CQ]], i32 [[ARGQ]]) #[[ATTR8]]
+; TUNIT-NEXT: ret i32 [[ARGQ]]
+;
+; CGSCC: Function Attrs: nofree nosync nounwind memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@recGoodCaller
+; CGSCC-SAME: (i1 noundef [[CQ:%.*]], i32 [[ARGQ:%.*]]) #[[ATTR7]] {
+; CGSCC-NEXT: [[RQ:%.*]] = call i32 @recGood(i1 noundef [[CQ]], i32 [[ARGQ]]) #[[ATTR7]]
+; CGSCC-NEXT: ret i32 [[RQ]]
+;
+ %rQ = call i32 @recGood(i1 %cQ, i32 %argQ)
+ ret i32 %rQ
+}
+
attributes #0 = { noinline nounwind uwtable }
;.
; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable }
@@ -1462,9 +1559,10 @@ attributes #0 = { noinline nounwind uwtable }
; TUNIT: attributes #[[ATTR6]] = { noreturn }
; TUNIT: attributes #[[ATTR7:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind memory(none) }
-; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind memory(read) }
-; TUNIT: attributes #[[ATTR10]] = { nounwind }
-; TUNIT: attributes #[[ATTR11:[0-9]+]] = { nounwind memory(none) }
+; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind memory(none) }
+; TUNIT: attributes #[[ATTR10]] = { nofree nosync nounwind memory(read) }
+; TUNIT: attributes #[[ATTR11]] = { nounwind }
+; TUNIT: attributes #[[ATTR12:[0-9]+]] = { nounwind memory(none) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable }
; CGSCC: attributes #[[ATTR1]] = { nofree noinline nosync nounwind memory(none) uwtable }
diff --git a/llvm/test/Transforms/OpenMP/replace_globalization.ll b/llvm/test/Transforms/OpenMP/replace_globalization.ll
index 0f89b428de7bf4..6e4fb9e57388ba 100644
--- a/llvm/test/Transforms/OpenMP/replace_globalization.ll
+++ b/llvm/test/Transforms/OpenMP/replace_globalization.ll
@@ -201,7 +201,7 @@ declare void @unknown_no_openmp() "llvm.assume"="omp_no_openmp"
; CHECK-NEXT: ret void
;
;
-; CHECK: Function Attrs: norecurse nosync nounwind allocsize(0) memory(read)
+; CHECK: Function Attrs: nosync nounwind allocsize(0) memory(read)
; CHECK-LABEL: define {{[^@]+}}@__kmpc_alloc_shared
; CHECK-SAME: (i64 [[TMP0:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: [[L:%.*]] = load i32, ptr @offset, align 4
@@ -216,7 +216,7 @@ declare void @unknown_no_openmp() "llvm.assume"="omp_no_openmp"
;.
; CHECK: attributes #[[ATTR0]] = { "kernel" }
; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind memory(write) }
-; CHECK: attributes #[[ATTR2]] = { norecurse nosync nounwind allocsize(0) memory(read) }
+; CHECK: attributes #[[ATTR2]] = { nosync nounwind allocsize(0) memory(read) }
; CHECK: attributes #[[ATTR3:[0-9]+]] = { nosync nounwind }
; CHECK: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
; CHECK: attributes #[[ATTR5]] = { "llvm.assume"="omp_no_openmp" }
More information about the llvm-commits
mailing list