diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -179,6 +179,20 @@ SmallVectorImpl &Objects, const AbstractAttribute &QueryingAA, const Instruction *CtxI); + +/// Collect all potential values of the one stored by \p SI into +/// \p PotentialCopies. That is, the only copies that were made via the +/// store are assumed to be known and all in \p PotentialCopies. Dependences +/// onto \p QueryingAA are properly tracked, \p UsedAssumedInformation will +/// inform the caller if assumed information was used. +/// +/// \returns True if the assumed potential copies are all in \p PotentialCopies, +/// false if something went wrong and the copies could not be +/// determined. +bool getPotentialCopiesOfStoredValue( + Attributor &A, StoreInst &SI, SmallSetVector &PotentialCopies, + const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation); + } // namespace AA /// The value passed to the line option that defines the maximal initialization @@ -4483,9 +4497,9 @@ /// Call \p CB on all accesses that might interfere with \p LI and return true /// if all such accesses were known and the callback returned true for all of /// them, false otherwise. - virtual bool forallInterfearingAccesses( + virtual bool forallInterferingAccesses( LoadInst &LI, function_ref CB) const = 0; - virtual bool forallInterfearingAccesses( + virtual bool forallInterferingAccesses( StoreInst &SI, function_ref CB) const = 0; /// This function should return true if the type of the \p AA is AAPointerInfo diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -29,6 +29,7 @@ #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/GlobalValue.h" +#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/IntrinsicInst.h" @@ -253,6 +254,86 @@ return nullptr; } +bool AA::getPotentialCopiesOfStoredValue( + Attributor &A, StoreInst &SI, SmallSetVector &PotentialCopies, + const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation) { + + Value &Ptr = *SI.getPointerOperand(); + SmallVector Objects; + if (!AA::getAssumedUnderlyingObjects(A, Ptr, Objects, QueryingAA, &SI)) { + LLVM_DEBUG( + dbgs() << "Underlying objects stored into could not be determined\n";); + return false; + } + + SmallVector PIs; + SmallVector NewCopies; + + for (Value *Obj : Objects) { + LLVM_DEBUG(dbgs() << "Visit underlying object " << *Obj << "\n"); + if (isa(Obj)) + continue; + if (isa(Obj)) { + // A null pointer access can be undefined but any offset from null may + // be OK. We do not try to optimize the latter. + if (!NullPointerIsDefined(SI.getFunction(), + Ptr.getType()->getPointerAddressSpace()) && + A.getAssumedSimplified(Ptr, QueryingAA, UsedAssumedInformation) == + Obj) + continue; + LLVM_DEBUG( + dbgs() << "Underlying object is a valid nullptr, giving up.\n";); + return false; + } + if (!isa(Obj) && !isa(Obj)) { + LLVM_DEBUG(dbgs() << "Underlying object is not supported yet: " << *Obj + << "\n";); + return false; + } + if (auto *GV = dyn_cast(Obj)) + if (!GV->hasLocalLinkage()) { + LLVM_DEBUG(dbgs() << "Underlying object is global with external " + "linkage, not supported yet: " + << *Obj << "\n";); + return false; + } + + auto CheckAccess = [&](const AAPointerInfo::Access &Acc, bool IsExact) { + if (!Acc.isRead()) + return true; + auto *LI = dyn_cast(Acc.getRemoteInst()); + if (!LI) { + LLVM_DEBUG(dbgs() << "Underlying object read through a non-load " + "instruction not supported yet: " + << *Acc.getRemoteInst() << "\n";); + return false; + } + NewCopies.push_back(LI); + return true; + }; + + auto &PI = A.getAAFor(QueryingAA, IRPosition::value(*Obj), + DepClassTy::NONE); + if (!PI.forallInterferingAccesses(SI, CheckAccess)) { + LLVM_DEBUG( + dbgs() + << "Failed to verify all interfering accesses for underlying object: " + << *Obj << "\n"); + return false; + } + PIs.push_back(&PI); + } + + for (auto *PI : PIs) { + if (!PI->getState().isAtFixpoint()) + UsedAssumedInformation = true; + A.recordDependence(*PI, QueryingAA, DepClassTy::OPTIONAL); + } + PotentialCopies.insert(NewCopies.begin(), NewCopies.end()); + + return true; +} + /// Return true if \p New is equal or worse than \p Old. static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) { if (!Old.isIntAttribute()) @@ -870,8 +951,7 @@ bool Attributor::checkForAllUses(function_ref Pred, const AbstractAttribute &QueryingAA, - const Value &V, - bool CheckBBLivenessOnly, + const Value &V, bool CheckBBLivenessOnly, DepClassTy LivenessDepClass) { // Check the trivial case first as it catches void values. @@ -911,6 +991,23 @@ continue; } + if (auto *SI = dyn_cast(U->getUser())) { + if (&SI->getOperandUse(0) == U) { + SmallSetVector PotentialCopies; + if (AA::getPotentialCopiesOfStoredValue(*this, *SI, PotentialCopies, + QueryingAA, + UsedAssumedInformation)) { + LLVM_DEBUG(dbgs() << "[Attributor] Value is stored, continue with " + << PotentialCopies.size() + << " potential copies instead!\n"); + for (Value *PotentialCopy : PotentialCopies) + for (const Use &U : PotentialCopy->uses()) + Worklist.push_back(&U); + continue; + } + } + } + bool Follow = false; if (!Pred(*U, Follow)) return false; diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -1010,8 +1010,8 @@ return *It == Before ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED; } - /// See AAPointerInfo::forallInterfearingAccesses. - bool forallInterfearingAccesses( + /// See AAPointerInfo::forallInterferingAccesses. + bool forallInterferingAccesses( Instruction &I, function_ref CB) const { if (!isValidState()) @@ -1070,15 +1070,15 @@ return AAPointerInfo::manifest(A); } - bool forallInterfearingAccesses( + bool forallInterferingAccesses( LoadInst &LI, function_ref CB) const override { - return State::forallInterfearingAccesses(LI, CB); + return State::forallInterferingAccesses(LI, CB); } - bool forallInterfearingAccesses( + bool forallInterferingAccesses( StoreInst &SI, function_ref CB) const override { - return State::forallInterfearingAccesses(SI, CB); + return State::forallInterferingAccesses(SI, CB); } ChangeStatus translateAndAddCalleeState(Attributor &A, @@ -4734,10 +4734,29 @@ return valueMayBeCaptured(UInst); } - // Explicitly catch return instructions. - if (isa(UInst)) + // For stores we check if we can follow the value through memory or not. + if (auto *SI = dyn_cast(UInst)) { + if (SI->isVolatile()) + return isCapturedIn(/* Memory */ true, /* Integer */ false, + /* Return */ false); + bool UsedAssumedInformation = false; + if (!AA::getPotentialCopiesOfStoredValue( + A, *SI, PotentialCopies, NoCaptureAA, UsedAssumedInformation)) + return isCapturedIn(/* Memory */ true, /* Integer */ false, + /* Return */ false); + // Not captured directly, potential copies will be checked. return isCapturedIn(/* Memory */ false, /* Integer */ false, + /* Return */ false); + } + + // Explicitly catch return instructions. + if (isa(UInst)) { + if (UInst->getFunction() == NoCaptureAA.getAnchorScope()) + return isCapturedIn(/* Memory */ false, /* Integer */ false, + /* Return */ true); + return isCapturedIn(/* Memory */ true, /* Integer */ true, /* Return */ true); + } // For now we only use special logic for call sites. However, the tracker // itself knows about a lot of other non-capturing cases already. @@ -5183,7 +5202,7 @@ auto &PI = A.getAAFor(AA, IRPosition::value(*Obj), DepClassTy::REQUIRED); - if (!PI.forallInterfearingAccesses(L, CheckAccess)) + if (!PI.forallInterferingAccesses(L, CheckAccess)) return false; } return true; diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll @@ -23,7 +23,7 @@ ; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 undef, i32* [[X_PRIV]], align 4 ; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* ; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[B_PRIV_CAST]], align 8 @@ -70,9 +70,9 @@ ; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4 ; IS__CGSCC_OPM-NEXT: ret i32 0 ; -; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 @@ -93,8 +93,5 @@ ;. ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } ;. -; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -;. -; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll @@ -40,13 +40,10 @@ ; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = call i64 @CaptureAStruct(i32 [[TMP0]], i64 [[TMP1]]) #[[ATTR0]] ; IS__TUNIT_NPM-NEXT: unreachable ; -; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@run ; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 0), align 8 -; IS__CGSCC____-NEXT: [[A_0_1:%.*]] = getelementptr [[STRUCT_FOO]], %struct.Foo* @a, i32 0, i32 1 -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8 ; IS__CGSCC____-NEXT: unreachable ; entry: @@ -108,7 +105,7 @@ ; ; IS________OPM: Function Attrs: nofree noreturn nosync nounwind readnone ; IS________OPM-LABEL: define {{[^@]+}}@CaptureAStruct -; IS________OPM-SAME: (%struct.Foo* noalias nofree noundef nonnull byval([[STRUCT_FOO:%.*]]) align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR0]] { +; IS________OPM-SAME: (%struct.Foo* noalias nocapture nofree noundef nonnull readnone byval([[STRUCT_FOO:%.*]]) align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR0]] { ; IS________OPM-NEXT: entry: ; IS________OPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8 ; IS________OPM-NEXT: br label [[LOOP:%.*]] @@ -141,9 +138,9 @@ ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8 ; IS__CGSCC____-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.Foo* [[A_PRIV]] to i32* -; IS__CGSCC____-NEXT: store i32 [[TMP0]], i32* [[A_PRIV_CAST]], align 8 +; IS__CGSCC____-NEXT: store i32 undef, i32* [[A_PRIV_CAST]], align 8 ; IS__CGSCC____-NEXT: [[A_PRIV_0_1:%.*]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i32 0, i32 1 -; IS__CGSCC____-NEXT: store i64 [[TMP1]], i64* [[A_PRIV_0_1]], align 8 +; IS__CGSCC____-NEXT: store i64 undef, i64* [[A_PRIV_0_1]], align 8 ; IS__CGSCC____-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8 ; IS__CGSCC____-NEXT: br label [[LOOP:%.*]] ; IS__CGSCC____: loop: @@ -166,7 +163,7 @@ ;. ; NOT_CGSCC_NPM: attributes #[[ATTR0:[0-9]+]] = { nofree noreturn nosync nounwind readnone } ;. -; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll @@ -55,7 +55,7 @@ ; IS__CGSCC_NPM-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8* ; IS__CGSCC_NPM-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]], align 8 ; IS__CGSCC_NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 -; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 undef, i32* [[U_PRIV_0_1]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 ; IS__CGSCC_NPM-NEXT: store i32 99, i32* [[TMP2]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0 @@ -186,13 +186,11 @@ ; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* getelementptr inbounds ([[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 0), align 8 -; IS__CGSCC_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 1 -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 8 -; IS__CGSCC_NPM-NEXT: call void @vfu1(i8 [[TMP0]], i32 [[TMP1]]) #[[ATTR0]] -; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i8, i8* getelementptr inbounds ([[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0), align 8 +; IS__CGSCC_NPM-NEXT: call void @vfu1(i8 [[TMP0]], i32 undef) #[[ATTR0]] +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i8, i8* getelementptr inbounds ([[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0), align 8 ; IS__CGSCC_NPM-NEXT: [[MYSTR_0_12:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 1 -; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[MYSTR_0_12]], align 8 -; IS__CGSCC_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP2]], i32 [[TMP3]]) #[[ATTR0]] +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[MYSTR_0_12]], align 8 +; IS__CGSCC_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP1]], i32 [[TMP2]]) #[[ATTR0]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RESULT]] ; entry: @@ -293,15 +291,15 @@ ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unions_v2 ; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { ; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8* -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]], align 8 -; IS__TUNIT_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 8 -; IS__TUNIT_NPM-NEXT: call void @vfu1(i8 [[TMP0]], i32 [[TMP1]]) #[[ATTR0]] ; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST1:%.*]] = bitcast %struct.MYstr* @mystr to i8* -; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i8, i8* [[MYSTR_CAST1]], align 8 -; IS__TUNIT_NPM-NEXT: [[MYSTR_0_12:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[MYSTR_0_12]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST1]], align 8 +; IS__TUNIT_NPM-NEXT: [[MYSTR_0_12:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_12]], align 8 +; IS__TUNIT_NPM-NEXT: call void @vfu1(i8 [[TMP0]], i32 [[TMP1]]) #[[ATTR0]] +; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8* +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i8, i8* [[MYSTR_CAST]], align 8 +; IS__TUNIT_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[MYSTR_0_1]], align 8 ; IS__TUNIT_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP2]], i32 [[TMP3]]) #[[ATTR2]] ; IS__TUNIT_NPM-NEXT: ret i32 [[RESULT]] ; @@ -317,7 +315,7 @@ ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@unions_v2 ; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { ; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: call void @vfu1(i8 noundef 0, i32 noundef 0) #[[ATTR0]] +; IS__CGSCC_NPM-NEXT: call void @vfu1(i8 noundef 0, i32 undef) #[[ATTR0]] ; IS__CGSCC_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 undef, i32 undef) #[[ATTR0]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RESULT]] ; diff --git a/llvm/test/Transforms/Attributor/nodelete.ll b/llvm/test/Transforms/Attributor/nodelete.ll --- a/llvm/test/Transforms/Attributor/nodelete.ll +++ b/llvm/test/Transforms/Attributor/nodelete.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals -; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM +; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM @@ -18,6 +18,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@f1 ; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] align 2 { ; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[REF_TMP:%.*]] = alloca [[A:%.*]], align 8 ; IS__CGSCC____-NEXT: ret i64 undef ; entry: @@ -29,10 +30,10 @@ define internal i64 @f2(%"a"* %this) align 2 { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f2 -; IS__CGSCC____-SAME: (%a* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] align 2 { +; IS__CGSCC____-SAME: () #[[ATTR0]] align 2 { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[THIS_ADDR:%.*]] = alloca %a*, align 8 -; IS__CGSCC____-NEXT: store %a* [[THIS]], %a** [[THIS_ADDR]], align 8 +; IS__CGSCC____-NEXT: store %a* undef, %a** [[THIS_ADDR]], align 8 ; IS__CGSCC____-NEXT: ret i64 undef ; entry: @@ -47,10 +48,10 @@ define internal void @f3(%"b"* %this) align 2 { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f3 -; IS__CGSCC____-SAME: (%b* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] align 2 { +; IS__CGSCC____-SAME: () #[[ATTR0]] align 2 { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[THIS_ADDR:%.*]] = alloca %b*, align 8 -; IS__CGSCC____-NEXT: store %b* [[THIS]], %b** [[THIS_ADDR]], align 8 +; IS__CGSCC____-NEXT: store %b* undef, %b** [[THIS_ADDR]], align 8 ; IS__CGSCC____-NEXT: ret void ; entry: @@ -64,10 +65,10 @@ define internal i1 @f4(%"b"* %this) align 2 { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f4 -; IS__CGSCC____-SAME: (%b* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] align 2 { +; IS__CGSCC____-SAME: () #[[ATTR0]] align 2 { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[THIS_ADDR:%.*]] = alloca %b*, align 8 -; IS__CGSCC____-NEXT: store %b* [[THIS]], %b** [[THIS_ADDR]], align 8 +; IS__CGSCC____-NEXT: store %b* undef, %b** [[THIS_ADDR]], align 8 ; IS__CGSCC____-NEXT: ret i1 undef ; entry: @@ -81,10 +82,10 @@ define internal %"a"* @f5(%"b"* %this) align 2 { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f5 -; IS__CGSCC____-SAME: (%b* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] align 2 { +; IS__CGSCC____-SAME: () #[[ATTR0]] align 2 { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[THIS_ADDR:%.*]] = alloca %b*, align 8 -; IS__CGSCC____-NEXT: store %b* [[THIS]], %b** [[THIS_ADDR]], align 8 +; IS__CGSCC____-NEXT: store %b* undef, %b** [[THIS_ADDR]], align 8 ; IS__CGSCC____-NEXT: ret %a* undef ; entry: diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -474,11 +474,17 @@ ; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noundef nonnull align 536870912 dereferenceable(4) i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR1]] [ "preallocated"(token [[C]]) ] ; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_preallocated -; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR5:[0-9]+]] -; IS__CGSCC____-NEXT: ret i32* null +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated +; IS__CGSCC_OPM-SAME: () #[[ATTR0:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR5:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32* null +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated +; IS__CGSCC_NPM-SAME: () #[[ATTR0:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR4:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32* null ; %c = call token @llvm.call.preallocated.setup(i32 1) %call = call i32* @test_preallocated(i32* preallocated(i32) null) ["preallocated"(token %c)] @@ -563,7 +569,7 @@ ; IS__CGSCC_NPM-SAME: (i8* noalias nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR1]] { ; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** -; IS__CGSCC_NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8 +; IS__CGSCC_NPM-NEXT: store i8* undef, i8** [[A_PRIV_CAST]], align 8 ; IS__CGSCC_NPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A_PRIV]], i32 0, i32 0 ; IS__CGSCC_NPM-NEXT: store i8* null, i8** [[G0]], align 8 ; IS__CGSCC_NPM-NEXT: ret void @@ -578,15 +584,10 @@ ; IS__TUNIT____-SAME: () #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_byval -; IS__CGSCC_OPM-SAME: () #[[ATTR1]] { -; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval -; IS__CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_byval +; IS__CGSCC____-SAME: () #[[ATTR1]] { +; IS__CGSCC____-NEXT: ret void ; call void @test_byval(%struct.X* byval(%struct.X) @S) ret void @@ -613,7 +614,7 @@ ; IS__TUNIT_NPM-NEXT: ret i8* [[L]] ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_byval2 -; IS__CGSCC_NPM-SAME: (i8* nofree [[TMP0:%.*]]) { +; IS__CGSCC_NPM-SAME: (i8* noalias nofree readnone "no-capture-maybe-returned" [[TMP0:%.*]]) { ; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** ; IS__CGSCC_NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8 @@ -645,7 +646,7 @@ ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval2() { ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0), align 8 -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2(i8* nofree [[TMP1]]) +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2(i8* noalias nofree readnone "no-capture-maybe-returned" [[TMP1]]) ; IS__CGSCC_NPM-NEXT: ret i8* [[C]] ; %c = call i8* @test_byval2(%struct.X* byval(%struct.X) @S) @@ -879,11 +880,17 @@ ; IS__TUNIT_NPM-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC____-LABEL: define {{[^@]+}}@user_as3 -; IS__CGSCC____-SAME: () #[[ATTR4:[0-9]+]] { -; IS__CGSCC____-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4 -; IS__CGSCC____-NEXT: ret void +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@user_as3 +; IS__CGSCC_OPM-SAME: () #[[ATTR4:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@user_as3 +; IS__CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4 +; IS__CGSCC_NPM-NEXT: ret void ; %call = call fastcc i32 addrspace(3)* @const_ptr_return_as3() store i32 0, i32 addrspace(3)* %call @@ -902,11 +909,17 @@ ; IS__TUNIT_NPM-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC____-LABEL: define {{[^@]+}}@user -; IS__CGSCC____-SAME: () #[[ATTR4]] { -; IS__CGSCC____-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4 -; IS__CGSCC____-NEXT: ret void +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@user +; IS__CGSCC_OPM-SAME: () #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@user +; IS__CGSCC_NPM-SAME: () #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4 +; IS__CGSCC_NPM-NEXT: ret void ; %call = call fastcc i32* @const_ptr_return() store i32 0, i32* %call @@ -1269,9 +1282,8 @@ ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR5]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR4]] = { willreturn } ;. ; CHECK: [[RNG0]] = !{i32 0, i32 -2147483648} ;. diff --git a/llvm/test/Transforms/OpenMP/custom_state_machines.ll b/llvm/test/Transforms/OpenMP/custom_state_machines.ll --- a/llvm/test/Transforms/OpenMP/custom_state_machines.ll +++ b/llvm/test/Transforms/OpenMP/custom_state_machines.ll @@ -918,8 +918,8 @@ ; CHECK-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] ; CHECK: user_code.entry: ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR2:[0-9]+]] -; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4 -; CHECK-NEXT: call void @__omp_outlined__(i32* noundef nonnull align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] +; CHECK-NEXT: store i32 undef, i32* [[DOTTHREADID_TEMP_]], align 4 +; CHECK-NEXT: call void @__omp_outlined__(i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) ; CHECK-NEXT: ret void ; CHECK: worker.exit: @@ -935,12 +935,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__ -; CHECK-SAME: (i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @no_parallel_region_in_here.internalized() #[[ATTR7:[0-9]+]] ; CHECK-NEXT: ret void ; @@ -1026,7 +1026,7 @@ ; CHECK: user_code.entry: ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR2]] ; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4 -; CHECK-NEXT: call void @__omp_outlined__1(i32* noundef nonnull align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] +; CHECK-NEXT: call void @__omp_outlined__1(i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) ; CHECK-NEXT: ret void ; CHECK: worker.exit: @@ -1035,14 +1035,14 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__1 -; CHECK-SAME: (i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS1:%.*]] = alloca [0 x i8*], align 8 ; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** ; CHECK-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* noundef @[[GLOB1]], i32 [[TMP0]], i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** noundef [[TMP1]], i64 noundef 0) @@ -1054,12 +1054,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__2 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p0() #[[ATTR8:[0-9]+]] ; CHECK-NEXT: ret void ; @@ -1082,12 +1082,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__3 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p1() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1161,7 +1161,7 @@ ; CHECK: user_code.entry: ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR2]] ; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4 -; CHECK-NEXT: call void @__omp_outlined__4(i32* noundef nonnull align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] +; CHECK-NEXT: call void @__omp_outlined__4(i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) ; CHECK-NEXT: ret void ; CHECK: worker.exit: @@ -1170,13 +1170,13 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__4 -; CHECK-SAME: (i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 ; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @simple_state_machine_interprocedural_before.internalized() #[[ATTR7]] ; CHECK-NEXT: call void @no_parallel_region_in_here.internalized() #[[ATTR7]] ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 @@ -1210,12 +1210,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__5 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p1() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1307,7 +1307,7 @@ ; CHECK: user_code.entry: ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR2]] ; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4 -; CHECK-NEXT: call void @__omp_outlined__6(i32* noundef nonnull align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] +; CHECK-NEXT: call void @__omp_outlined__6(i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) ; CHECK-NEXT: ret void ; CHECK: worker.exit: @@ -1316,14 +1316,14 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__6 -; CHECK-SAME: (i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS1:%.*]] = alloca [0 x i8*], align 8 ; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** ; CHECK-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* noundef @[[GLOB1]], i32 [[TMP0]], i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__7 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__7_wrapper to i8*), i8** noundef [[TMP1]], i64 noundef 0) @@ -1335,12 +1335,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__7 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p0() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1363,12 +1363,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__8 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p1() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1436,7 +1436,7 @@ ; CHECK: user_code.entry: ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR2]] ; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4 -; CHECK-NEXT: call void @__omp_outlined__9(i32* noundef nonnull align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] +; CHECK-NEXT: call void @__omp_outlined__9(i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) ; CHECK-NEXT: ret void ; CHECK: worker.exit: @@ -1445,14 +1445,14 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__9 -; CHECK-SAME: (i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS1:%.*]] = alloca [0 x i8*], align 8 ; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** ; CHECK-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* noundef @[[GLOB1]], i32 [[TMP0]], i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__10 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__10_wrapper to i8*), i8** noundef [[TMP1]], i64 noundef 0) @@ -1464,12 +1464,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__10 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p0() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1492,12 +1492,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__11 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p1() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1531,7 +1531,7 @@ ; CHECK: user_code.entry: ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR2]] ; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4 -; CHECK-NEXT: call void @__omp_outlined__12(i32* noundef nonnull align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] +; CHECK-NEXT: call void @__omp_outlined__12(i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 true, i1 true) ; CHECK-NEXT: ret void ; CHECK: worker.exit: @@ -1540,14 +1540,14 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__12 -; CHECK-SAME: (i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8 ; CHECK-NEXT: [[CAPTURED_VARS_ADDRS1:%.*]] = alloca [0 x i8*], align 8 ; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** ; CHECK-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* noundef @[[GLOB1]], i32 [[TMP0]], i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__13 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__13_wrapper to i8*), i8** noundef [[TMP1]], i64 noundef 0) @@ -1558,12 +1558,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__13 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p0() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1586,12 +1586,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__14 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p1() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1652,8 +1652,8 @@ ; CHECK-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] ; CHECK: user_code.entry: ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR2]] -; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4 -; CHECK-NEXT: call void @__omp_outlined__15(i32* noundef nonnull align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] +; CHECK-NEXT: store i32 undef, i32* [[DOTTHREADID_TEMP_]], align 4 +; CHECK-NEXT: call void @__omp_outlined__15(i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) ; CHECK-NEXT: ret void ; CHECK: worker.exit: @@ -1662,12 +1662,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__15 -; CHECK-SAME: (i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR2]] ; CHECK-NEXT: call void @simple_state_machine_interprocedural_nested_recursive_after.internalized(i32 [[CALL]]) #[[ATTR7]] ; CHECK-NEXT: ret void @@ -1749,8 +1749,8 @@ ; CHECK-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]] ; CHECK: user_code.entry: ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR2]] -; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4 -; CHECK-NEXT: call void @__omp_outlined__16(i32* noundef nonnull align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] +; CHECK-NEXT: store i32 undef, i32* [[DOTTHREADID_TEMP_]], align 4 +; CHECK-NEXT: call void @__omp_outlined__16(i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]] ; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 false, i1 true) ; CHECK-NEXT: ret void ; CHECK: worker.exit: @@ -1759,12 +1759,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__16 -; CHECK-SAME: (i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @weak_callee_empty() #[[ATTR7]] ; CHECK-NEXT: ret void ; @@ -1778,12 +1778,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__17 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p0() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1806,12 +1806,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__18 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p0() #[[ATTR8]] ; CHECK-NEXT: ret void ; @@ -1856,12 +1856,12 @@ ; ; CHECK: Function Attrs: convergent norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__19 -; CHECK-SAME: (i32* noalias nofree [[DOTGLOBAL_TID_:%.*]], i32* noalias nofree [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 ; CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -; CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -; CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +; CHECK-NEXT: store i32* undef, i32** [[DOTBOUND_TID__ADDR]], align 8 ; CHECK-NEXT: call void @p0() #[[ATTR8]] ; CHECK-NEXT: ret void ;