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 @@ -722,7 +722,10 @@ [&](const Function &F) { return AG.getAnalysis(F); }), - AG(AG), CGSCC(CGSCC) {} + AG(AG), CGSCC(CGSCC) { + if (CGSCC) + initializeModuleSlice(*CGSCC); + } ~InformationCache() { // The FunctionInfo objects are allocated via a BumpPtrAllocator, we call @@ -731,6 +734,68 @@ It.getSecond()->~FunctionInfo(); } + /// Apply \p CB to all uses of \p F. If \p LookThroughConstantExprUses is + /// true, constant expression users are not given to \p CB but their uses are + /// traversed transitively. + template + static void foreachUse(Function &F, CBTy CB, + bool LookThroughConstantExprUses = true) { + SmallVector Worklist(make_pointer_range(F.uses())); + + for (unsigned Idx = 0; Idx < Worklist.size(); ++Idx) { + Use &U = *Worklist[Idx]; + + // Allow use in constant bitcasts and simply look through them. + if (LookThroughConstantExprUses && isa(U.getUser())) { + for (Use &CEU : cast(U.getUser())->uses()) + Worklist.push_back(&CEU); + continue; + } + + CB(U); + } + } + + /// Initialize the ModuleSlice member based on \p SCC. ModuleSlices contains + /// (a subset of) all functions that we can look at during this SCC traversal. + /// This includes functions (transitively) called from the SCC and the + /// (transitive) callers of SCC functions. We also can look at a function if + /// there is a "reference edge", i.a., if the function somehow uses (!=calls) + /// a function in the SCC or a caller of a function in the SCC. + void initializeModuleSlice(SetVector &SCC) { + ModuleSlice.insert(SCC.begin(), SCC.end()); + + SmallPtrSet Seen; + SmallVector Worklist(SCC.begin(), SCC.end()); + while (!Worklist.empty()) { + Function *F = Worklist.pop_back_val(); + ModuleSlice.insert(F); + + for (Instruction &I : instructions(*F)) + if (auto *CB = dyn_cast(&I)) + if (Function *Callee = CB->getCalledFunction()) + if (Seen.insert(Callee).second) + Worklist.push_back(Callee); + } + + Seen.clear(); + Worklist.append(SCC.begin(), SCC.end()); + while (!Worklist.empty()) { + Function *F = Worklist.pop_back_val(); + ModuleSlice.insert(F); + + // Traverse all transitive uses. + foreachUse(*F, [&](Use &U) { + if (auto *UsrI = dyn_cast(U.getUser())) + if (Seen.insert(UsrI->getFunction()).second) + Worklist.push_back(UsrI->getFunction()); + }); + } + } + + /// The slice of the module we are allowed to look at. + SmallPtrSet ModuleSlice; + /// A vector type to hold instructions. using InstructionVectorTy = SmallVector; @@ -804,6 +869,11 @@ return Result; } + /// Check whether \p F is part of module slice. + bool isInModuleSlice(const Function &F) { + return ModuleSlice.count(const_cast(&F)); + } + private: struct FunctionInfo { ~FunctionInfo(); @@ -1013,12 +1083,16 @@ TimeTraceScope TimeScope(AA.getName() + "::initialize"); AA.initialize(*this); } - // We can initialize (=look at) code outside the current function set but - // not call update because that would again spawn new abstract attributes in - // potentially unconnected code regions (=SCCs). + + // Initialize and update is allowed for code outside of the current function + // set, but only if it is part of module slice we are allowed to look at. + // Only exception is AAIsDeadFunction whose initialization is prevented + // directly, since we don't to compute it twice. if (FnScope && !Functions.count(const_cast(FnScope))) { - AA.getState().indicatePessimisticFixpoint(); - return AA; + if (!getInfoCache().isInModuleSlice(*FnScope)) { + AA.getState().indicatePessimisticFixpoint(); + return AA; + } } // If this is queried in the manifest stage, we force the AA to indicate 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 @@ -1298,8 +1298,11 @@ for (Function *Fn : CGModifiedFunctions) CGUpdater.reanalyzeFunction(*Fn); - for (Function *Fn : ToBeDeletedFunctions) + for (Function *Fn : ToBeDeletedFunctions) { + if (!Functions.count(Fn)) + continue; CGUpdater.removeFunction(*Fn); + } if (!ToBeDeletedFunctions.empty()) ManifestChange = ChangeStatus::CHANGED; @@ -1607,7 +1610,7 @@ Function *OldFn = It.getFirst(); // Deleted functions do not require rewrites. - if (ToBeDeletedFunctions.count(OldFn)) + if (!Functions.count(OldFn) || ToBeDeletedFunctions.count(OldFn)) continue; const SmallVectorImpl> &ARIs = 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 @@ -3032,8 +3032,14 @@ void initialize(Attributor &A) override { const Function *F = getAnchorScope(); if (F && !F->isDeclaration()) { - ToBeExploredFrom.insert(&F->getEntryBlock().front()); - assumeLive(A, F->getEntryBlock()); + // We only want to compute liveness once. If the function is not part of + // the SCC, skip it. + if (A.isRunOn(*const_cast(F))) { + ToBeExploredFrom.insert(&F->getEntryBlock().front()); + assumeLive(A, F->getEntryBlock()); + } else { + indicatePessimisticFixpoint(); + } } } diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp --- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp +++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp @@ -67,28 +67,6 @@ static constexpr auto TAG = "[" DEBUG_TYPE "]"; #endif -/// Apply \p CB to all uses of \p F. If \p LookThroughConstantExprUses is -/// true, constant expression users are not given to \p CB but their uses are -/// traversed transitively. -template -static void foreachUse(Function &F, CBTy CB, - bool LookThroughConstantExprUses = true) { - SmallVector Worklist(make_pointer_range(F.uses())); - - for (unsigned idx = 0; idx < Worklist.size(); ++idx) { - Use &U = *Worklist[idx]; - - // Allow use in constant bitcasts and simply look through them. - if (LookThroughConstantExprUses && isa(U.getUser())) { - for (Use &CEU : cast(U.getUser())->uses()) - Worklist.push_back(&CEU); - continue; - } - - CB(U); - } -} - /// Helper struct to store tracked ICV values at specif instructions. struct ICVValue { Instruction *Inst; @@ -138,7 +116,6 @@ SmallPtrSetImpl &Kernels) : InformationCache(M, AG, Allocator, &CGSCC), OMPBuilder(M), Kernels(Kernels) { - initializeModuleSlice(CGSCC); OMPBuilder.initialize(); initializeRuntimeFunctions(); @@ -265,46 +242,6 @@ DenseMap> UsesMap; }; - /// Initialize the ModuleSlice member based on \p SCC. ModuleSlices contains - /// (a subset of) all functions that we can look at during this SCC traversal. - /// This includes functions (transitively) called from the SCC and the - /// (transitive) callers of SCC functions. We also can look at a function if - /// there is a "reference edge", i.a., if the function somehow uses (!=calls) - /// a function in the SCC or a caller of a function in the SCC. - void initializeModuleSlice(SetVector &SCC) { - ModuleSlice.insert(SCC.begin(), SCC.end()); - - SmallPtrSet Seen; - SmallVector Worklist(SCC.begin(), SCC.end()); - while (!Worklist.empty()) { - Function *F = Worklist.pop_back_val(); - ModuleSlice.insert(F); - - for (Instruction &I : instructions(*F)) - if (auto *CB = dyn_cast(&I)) - if (Function *Callee = CB->getCalledFunction()) - if (Seen.insert(Callee).second) - Worklist.push_back(Callee); - } - - Seen.clear(); - Worklist.append(SCC.begin(), SCC.end()); - while (!Worklist.empty()) { - Function *F = Worklist.pop_back_val(); - ModuleSlice.insert(F); - - // Traverse all transitive uses. - foreachUse(*F, [&](Use &U) { - if (auto *UsrI = dyn_cast(U.getUser())) - if (Seen.insert(UsrI->getFunction()).second) - Worklist.push_back(UsrI->getFunction()); - }); - } - } - - /// The slice of the module we are allowed to look at. - SmallPtrSet ModuleSlice; - /// An OpenMP-IR-Builder instance OpenMPIRBuilder OMPBuilder; @@ -1106,7 +1043,7 @@ // TODO: In the future we want to track more than just a unique kernel. SmallPtrSet PotentialKernels; - foreachUse(F, [&](const Use &U) { + OMPInformationCache::foreachUse(F, [&](const Use &U) { PotentialKernels.insert(GetUniqueKernelForUse(U)); }); @@ -1137,7 +1074,7 @@ unsigned NumDirectCalls = 0; SmallVector ToBeReplacedStateMachineUses; - foreachUse(*F, [&](Use &U) { + OMPInformationCache::foreachUse(*F, [&](Use &U) { if (auto *CB = dyn_cast(U.getUser())) if (CB->isCallee(&U)) { ++NumDirectCalls; @@ -1475,7 +1412,6 @@ Attributor A(Functions, InfoCache, CGUpdater); - // TODO: Compute the module slice we are allowed to look at. OpenMPOpt OMPOpt(SCC, CGUpdater, OREGetter, InfoCache, A); bool Changed = OMPOpt.run(); if (Changed) @@ -1552,7 +1488,6 @@ Attributor A(Functions, InfoCache, CGUpdater); - // TODO: Compute the module slice we are allowed to look at. OpenMPOpt OMPOpt(SCC, CGUpdater, OREGetter, InfoCache, A); return OMPOpt.run(); } diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll @@ -21,12 +21,21 @@ ; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X_PRIV]], align 4 ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP2]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@deref -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4 -; IS__CGSCC____-NEXT: ret i32 [[TMP2]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@deref +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@deref +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP2]] ; entry: %tmp2 = load i32, i32* %x, align 4 @@ -53,14 +62,24 @@ ; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[TMP0]]) [[ATTR2:#.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP1]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@f -; IS__CGSCC____-SAME: (i32 [[X:%.*]]) [[ATTR1:#.*]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X_ADDR]]) [[ATTR2:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[TMP1]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) [[ATTR1:#.*]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X_ADDR]]) [[ATTR2:#.*]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) [[ATTR0]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[TMP0]]) [[ATTR1:#.*]] +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP1]] ; entry: %x_addr = alloca i32 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll @@ -26,7 +26,6 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@callee ; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[A_0:%.*]] = load i32, i32* [[A]], align 4 ; IS__CGSCC____-NEXT: br label [[F:%.*]] ; IS__CGSCC____: T: ; IS__CGSCC____-NEXT: unreachable diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll @@ -9,21 +9,21 @@ target triple = "x86_64-unknown-linux-gnu" define internal fastcc void @no_promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 { -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote_avx2 -; NOT_TUNIT_NPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) [[ATTR0:#.*]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 -; NOT_TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 -; NOT_TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@no_promote_avx2 +; IS________OPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) [[ATTR0:#.*]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 +; IS________OPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 +; IS________OPM-NEXT: ret void ; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote_avx2 -; IS__TUNIT_NPM-SAME: (<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) [[ATTR0:#.*]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 -; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 -; IS__TUNIT_NPM-NEXT: ret void +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@no_promote_avx2 +; IS________NPM-SAME: (<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) [[ATTR0:#.*]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 +; IS________NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <4 x i64>, <4 x i64>* %arg1 @@ -96,23 +96,23 @@ } define internal fastcc void @promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 { -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@promote_avx2 -; NOT_TUNIT_NPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) [[ATTR0]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 -; NOT_TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 -; NOT_TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@promote_avx2 +; IS________OPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) [[ATTR0]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align 32 +; IS________OPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 +; IS________OPM-NEXT: ret void ; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote_avx2 -; IS__TUNIT_NPM-SAME: (<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]]) [[ATTR0]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <4 x i64>, align 32 -; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP0]], <4 x i64>* [[ARG1_PRIV]], align 32 -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1_PRIV]], align 32 -; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 -; IS__TUNIT_NPM-NEXT: ret void +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@promote_avx2 +; IS________NPM-SAME: (<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]]) [[ATTR0]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <4 x i64>, align 32 +; IS________NPM-NEXT: store <4 x i64> [[TMP0]], <4 x i64>* [[ARG1_PRIV]], align 32 +; IS________NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1_PRIV]], align 32 +; IS________NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <4 x i64>, <4 x i64>* %arg1 @@ -169,7 +169,8 @@ ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture noundef nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) [[ATTR4]] -; IS__CGSCC_NPM-NEXT: call fastcc void @promote_avx2(<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[TMP]]) [[ATTR5]] +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load <4 x i64>, <4 x i64>* [[TMP]], align 32 +; IS__CGSCC_NPM-NEXT: call fastcc void @promote_avx2(<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64> [[TMP0]]) [[ATTR5]] ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]], align 32 ; IS__CGSCC_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__CGSCC_NPM-NEXT: ret void diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll @@ -11,23 +11,23 @@ ; This should promote define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #0 { ; -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 -; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR0:#.*]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 -; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR0:#.*]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 +; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR0:#.*]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________OPM-NEXT: ret void +; +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 +; IS________NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR0:#.*]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -85,7 +85,8 @@ ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) [[ATTR11:#.*]] -; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP]]) [[ATTR12:#.*]] +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 64 +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) [[ATTR12:#.*]] ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 ; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_NPM-NEXT: ret void @@ -104,23 +105,23 @@ ; This should promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { ; -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 -; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR2:#.*]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 -; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR2:#.*]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 +; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR2:#.*]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________OPM-NEXT: ret void +; +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 +; IS________NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR2:#.*]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -178,7 +179,8 @@ ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) [[ATTR11]] -; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP]]) [[ATTR12]] +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 64 +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) [[ATTR12]] ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 ; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_NPM-NEXT: ret void @@ -197,23 +199,23 @@ ; This should promote define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { ; -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256 -; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR2]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256 -; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR2]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256 +; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR2]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________OPM-NEXT: ret void +; +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256 +; IS________NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR2]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -271,7 +273,8 @@ ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) [[ATTR11]] -; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP]]) [[ATTR12]] +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 64 +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) [[ATTR12]] ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 ; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_NPM-NEXT: ret void @@ -290,23 +293,23 @@ ; This should promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #0 { ; -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512 -; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR0]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512 -; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR0]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512 +; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR0]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________OPM-NEXT: ret void +; +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512 +; IS________NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR0]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -364,7 +367,8 @@ ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) [[ATTR11]] -; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP]]) [[ATTR12]] +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 64 +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) [[ATTR12]] ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 ; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_NPM-NEXT: ret void @@ -383,21 +387,21 @@ ; This should not promote define internal fastcc void @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { ; -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256 -; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR2]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256 -; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR2]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256 +; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR2]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________OPM-NEXT: ret void +; +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256 +; IS________NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR2]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -473,21 +477,21 @@ ; This should not promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #2 { ; -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256 -; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR5:#.*]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256 -; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR5:#.*]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256 +; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR5:#.*]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________OPM-NEXT: ret void +; +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256 +; IS________NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR5:#.*]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -563,23 +567,23 @@ ; This should promote define internal fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #3 { ; -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256 -; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR6:#.*]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256 -; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR6:#.*]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256 +; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR6:#.*]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________OPM-NEXT: ret void +; +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256 +; IS________NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR6:#.*]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -637,7 +641,8 @@ ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) [[ATTR11]] -; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP]]) [[ATTR12]] +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 64 +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) [[ATTR12]] ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 ; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_NPM-NEXT: ret void @@ -656,23 +661,23 @@ ; This should promote define internal fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #4 { ; -; NOT_TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256 -; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR8:#.*]] { -; NOT_TUNIT_NPM-NEXT: bb: -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 -; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256 -; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR8:#.*]] { -; IS__TUNIT_NPM-NEXT: bb: -; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 -; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256 +; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) [[ATTR8:#.*]] { +; IS________OPM-NEXT: bb: +; IS________OPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align 64 +; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________OPM-NEXT: ret void +; +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256 +; IS________NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) [[ATTR8:#.*]] { +; IS________NPM-NEXT: bb: +; IS________NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>, align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]], align 64 +; IS________NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 +; IS________NPM-NEXT: ret void ; bb: %tmp = load <8 x i64>, <8 x i64>* %arg1 @@ -730,7 +735,8 @@ ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) [[ATTR11]] -; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>* noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[TMP]]) [[ATTR12]] +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align 64 +; IS__CGSCC_NPM-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64> [[TMP0]]) [[ATTR12]] ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]], align 64 ; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_NPM-NEXT: ret void diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll @@ -15,25 +15,15 @@ %struct.a = type { i8 } define internal x86_thiscallcc void @internalfun(%struct.a* %this, <{ %struct.a }>* inalloca) { -; IS__TUNIT____-LABEL: define {{[^@]+}}@internalfun -; IS__TUNIT____-SAME: (%struct.a* noalias nocapture nofree readnone [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[TMP0:%.*]]) { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 -; IS__TUNIT____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 -; IS__TUNIT____-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 -; IS__TUNIT____-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* noundef nonnull align 4 dereferenceable(1) [[TMP1]], %struct.a* noundef nonnull align 4 dereferenceable(1) [[A]]) -; IS__TUNIT____-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[ARGMEM]]) -; IS__TUNIT____-NEXT: ret void -; -; IS__CGSCC____-LABEL: define {{[^@]+}}@internalfun -; IS__CGSCC____-SAME: (%struct.a* nocapture nofree readnone [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[TMP0:%.*]]) { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 -; IS__CGSCC____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* noundef nonnull align 4 dereferenceable(1) [[TMP1]], %struct.a* noundef nonnull align 4 dereferenceable(1) [[A]]) -; IS__CGSCC____-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[ARGMEM]]) -; IS__CGSCC____-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@internalfun +; CHECK-SAME: (%struct.a* noalias nocapture nofree readnone [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[TMP0:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 +; CHECK-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 +; CHECK-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* noundef nonnull align 4 dereferenceable(1) [[TMP1]], %struct.a* noundef nonnull align 4 dereferenceable(1) [[A]]) +; CHECK-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[ARGMEM]]) +; CHECK-NEXT: ret void ; entry: %a = getelementptr inbounds <{ %struct.a }>, <{ %struct.a }>* %0, i32 0, i32 0 @@ -46,21 +36,13 @@ ; This is here to ensure @internalfun is live. define void @exportedfun(%struct.a* %a) { -; IS__TUNIT____-LABEL: define {{[^@]+}}@exportedfun -; IS__TUNIT____-SAME: (%struct.a* nocapture nofree readnone [[A:%.*]]) { -; IS__TUNIT____-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() -; IS__TUNIT____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 -; IS__TUNIT____-NEXT: call x86_thiscallcc void @internalfun(%struct.a* noalias nocapture nofree readnone undef, <{ [[STRUCT_A]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[ARGMEM]]) -; IS__TUNIT____-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]]) -; IS__TUNIT____-NEXT: ret void -; -; IS__CGSCC____-LABEL: define {{[^@]+}}@exportedfun -; IS__CGSCC____-SAME: (%struct.a* nocapture nofree readnone [[A:%.*]]) { -; IS__CGSCC____-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() -; IS__CGSCC____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 -; IS__CGSCC____-NEXT: call x86_thiscallcc void @internalfun(%struct.a* noalias nocapture nofree readnone [[A]], <{ [[STRUCT_A]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[ARGMEM]]) -; IS__CGSCC____-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]]) -; IS__CGSCC____-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@exportedfun +; CHECK-SAME: (%struct.a* nocapture nofree readnone [[A:%.*]]) { +; CHECK-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() +; CHECK-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 +; CHECK-NEXT: call x86_thiscallcc void @internalfun(%struct.a* noalias nocapture nofree readnone undef, <{ [[STRUCT_A]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[ARGMEM]]) +; CHECK-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]]) +; CHECK-NEXT: ret void ; %inalloca.save = tail call i8* @llvm.stacksave() %argmem = alloca inalloca <{ %struct.a }>, align 4 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll @@ -5,18 +5,18 @@ ; 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 define void @f() { -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@f() { -; NOT_TUNIT_NPM-NEXT: entry: -; NOT_TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 1 -; NOT_TUNIT_NPM-NEXT: call void @g(i32* noalias nocapture noundef nonnull readonly dereferenceable(4) [[A]]) -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f() { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 1 -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 1 -; IS__TUNIT_NPM-NEXT: call void @g(i32 [[TMP0]]) -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@f() { +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[A:%.*]] = alloca i32, align 1 +; IS________OPM-NEXT: call void @g(i32* noalias nocapture noundef nonnull readonly dereferenceable(4) [[A]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@f() { +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[A:%.*]] = alloca i32, align 1 +; IS________NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 1 +; IS________NPM-NEXT: call void @g(i32 [[TMP0]]) +; IS________NPM-NEXT: ret void ; entry: %a = alloca i32, align 1 @@ -25,11 +25,11 @@ } define internal void @g(i32* %a) { -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@g -; IS__TUNIT_OPM-SAME: (i32* noalias nocapture noundef nonnull readonly dereferenceable(4) [[A:%.*]]) { -; IS__TUNIT_OPM-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1 -; IS__TUNIT_OPM-NEXT: call void @z(i32 [[AA]]) -; IS__TUNIT_OPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@g +; IS________OPM-SAME: (i32* noalias nocapture noundef nonnull readonly dereferenceable(4) [[A:%.*]]) { +; IS________OPM-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1 +; IS________OPM-NEXT: call void @z(i32 [[AA]]) +; IS________OPM-NEXT: ret void ; ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@g ; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) { @@ -39,11 +39,13 @@ ; IS__TUNIT_NPM-NEXT: call void @z(i32 [[AA]]) ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC____-LABEL: define {{[^@]+}}@g -; IS__CGSCC____-SAME: (i32* nocapture noundef nonnull readonly dereferenceable(4) [[A:%.*]]) { -; IS__CGSCC____-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1 -; IS__CGSCC____-NEXT: call void @z(i32 [[AA]]) -; IS__CGSCC____-NEXT: ret void +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) { +; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[AA:%.*]] = load i32, i32* [[A_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: call void @z(i32 [[AA]]) +; IS__CGSCC_NPM-NEXT: ret void ; %aa = load i32, i32* %a, align 1 call void @z(i32 %aa) @@ -87,19 +89,37 @@ ; IS__TUNIT_NPM: Return2: ; IS__TUNIT_NPM-NEXT: ret i32 [[A]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@test -; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[Y:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4 -; IS__CGSCC____-NEXT: [[B:%.*]] = load i64, i64* [[Y]], align 8 -; IS__CGSCC____-NEXT: [[C:%.*]] = add i32 [[A]], 1 -; IS__CGSCC____-NEXT: [[D:%.*]] = add i64 [[B]], 1 -; IS__CGSCC____-NEXT: [[COND:%.*]] = icmp sgt i64 [[D]], -1 -; IS__CGSCC____-NEXT: br i1 [[COND]], label [[RETURN1:%.*]], label [[RETURN2:%.*]] -; IS__CGSCC____: Return1: -; IS__CGSCC____-NEXT: ret i32 [[C]] -; IS__CGSCC____: Return2: -; IS__CGSCC____-NEXT: ret i32 [[A]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i64* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[Y:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4 +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = load i64, i64* [[Y]], align 8 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = add i32 [[A]], 1 +; IS__CGSCC_OPM-NEXT: [[D:%.*]] = add i64 [[B]], 1 +; IS__CGSCC_OPM-NEXT: [[COND:%.*]] = icmp sgt i64 [[D]], -1 +; IS__CGSCC_OPM-NEXT: br i1 [[COND]], label [[RETURN1:%.*]], label [[RETURN2:%.*]] +; IS__CGSCC_OPM: Return1: +; IS__CGSCC_OPM-NEXT: ret i32 [[C]] +; IS__CGSCC_OPM: Return2: +; IS__CGSCC_OPM-NEXT: ret i32 [[A]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_NPM-NEXT: [[Y_PRIV:%.*]] = alloca i64, align 8 +; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[Y_PRIV]], align 8 +; IS__CGSCC_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = load i32, i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = load i64, i64* [[Y_PRIV]], align 8 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = add i32 [[A]], 1 +; IS__CGSCC_NPM-NEXT: [[D:%.*]] = add i64 [[B]], 1 +; IS__CGSCC_NPM-NEXT: [[COND:%.*]] = icmp sgt i64 [[D]], -1 +; IS__CGSCC_NPM-NEXT: br i1 [[COND]], label [[RETURN1:%.*]], label [[RETURN2:%.*]] +; IS__CGSCC_NPM: Return1: +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] +; IS__CGSCC_NPM: Return2: +; IS__CGSCC_NPM-NEXT: ret i32 [[A]] ; %A = load i32, i32* %X %B = load i64, i64* %Y @@ -134,13 +154,25 @@ ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i64 [[TMP3]]) [[ATTR3:#.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[C]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@caller -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) [[ATTR1:#.*]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i64, align 8 -; IS__CGSCC____-NEXT: store i64 1, i64* [[B]], align 8 -; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i64* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B]]) [[ATTR3:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[C]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) [[ATTR1:#.*]] { +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i64, align 8 +; IS__CGSCC_OPM-NEXT: store i64 1, i64* [[B]], align 8 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i64* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B]]) [[ATTR3:#.*]] +; IS__CGSCC_OPM-NEXT: ret i32 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) [[ATTR0]] { +; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i64, align 8 +; IS__CGSCC_NPM-NEXT: store i64 1, i64* [[B]], align 8 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[A_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[B]], align 8 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i64 [[TMP3]]) [[ATTR1:#.*]] +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] ; %B = alloca i64 store i64 1, i64* %B @@ -166,13 +198,22 @@ ; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]]) [[ATTR4:#.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[X]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller -; IS__CGSCC____-SAME: () [[ATTR2:#.*]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4 -; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[X]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callercaller +; IS__CGSCC_OPM-SAME: () [[ATTR2:#.*]] { +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 2, i32* [[B]], align 4 +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4:#.*]] +; IS__CGSCC_OPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callercaller +; IS__CGSCC_NPM-SAME: () [[ATTR0]] { +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 2, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]]) [[ATTR2:#.*]] +; IS__CGSCC_NPM-NEXT: ret i32 [[X]] ; %B = alloca i32 store i32 2, i32* %B diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll @@ -63,7 +63,7 @@ ; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], 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 [[TMP0]], i32* [[B_PRIV_CAST]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 8 ; IS__CGSCC_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 ; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll @@ -26,13 +26,25 @@ ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] ; IS__TUNIT_NPM-NEXT: ret i32 [[C]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@test -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[Y:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4 -; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[Y]], align 4 -; IS__CGSCC____-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] -; IS__CGSCC____-NEXT: ret i32 [[C]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[Y:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4 +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = load i32, i32* [[Y]], align 4 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC_OPM-NEXT: ret i32 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_NPM-NEXT: [[Y_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[Y_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = load i32, i32* [[X_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = load i32, i32* [[Y_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] ; %A = load i32, i32* %X %B = load i32, i32* %Y @@ -61,13 +73,25 @@ ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i32 [[TMP3]]) [[ATTR3:#.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[C]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@caller -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR1:#.*]] { -; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: store i32 1, i32* [[A]], align 4 -; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR3:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[C]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR1:#.*]] { +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[A]], align 4 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR3:#.*]] +; IS__CGSCC_OPM-NEXT: ret i32 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) [[ATTR0]] { +; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[A]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[B_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i32 [[TMP3]]) [[ATTR1:#.*]] +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] ; %A = alloca i32 store i32 1, i32* %A @@ -93,13 +117,22 @@ ; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]]) [[ATTR4:#.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[X]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller -; IS__CGSCC____-SAME: () [[ATTR2:#.*]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4 -; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[X]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callercaller +; IS__CGSCC_OPM-SAME: () [[ATTR2:#.*]] { +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 2, i32* [[B]], align 4 +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4:#.*]] +; IS__CGSCC_OPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callercaller +; IS__CGSCC_NPM-SAME: () [[ATTR0]] { +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 2, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]]) [[ATTR2:#.*]] +; IS__CGSCC_NPM-NEXT: ret i32 [[X]] ; %B = alloca i32 store i32 2, i32* %B 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 @@ -26,7 +26,7 @@ ; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], 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 [[TMP0]], i32* [[B_PRIV_CAST]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 8 ; IS__CGSCC_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 ; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll @@ -36,12 +36,12 @@ ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f -; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull byval align 8 dereferenceable(12) [[B:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull byval align 32 dereferenceable(12) [[B:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 -; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32 ; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32 ; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn @@ -50,7 +50,7 @@ ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]], align 4 ; IS__CGSCC_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* -; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 8 ; IS__CGSCC_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 ; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 @@ -110,7 +110,7 @@ ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]], align 4 ; IS__CGSCC_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32* -; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 32 ; IS__CGSCC_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 ; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 @@ -152,15 +152,15 @@ ; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8 ; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 ; IS__TUNIT_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4 -; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 8 -; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 8 -; IS__TUNIT_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) [[ATTR0]] ; IS__TUNIT_NPM-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to i32* -; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align 32 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST1]], align 8 ; IS__TUNIT_NPM-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 32 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_12]], align 8 +; IS__TUNIT_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]]) [[ATTR0]] +; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32* +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST]], align 32 +; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_1]], align 32 ; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]]) [[ATTR0]] ; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] ; IS__TUNIT_NPM-NEXT: ret i32 [[A]] diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll @@ -29,15 +29,27 @@ ; IS__TUNIT_NPM-NEXT: [[X:%.*]] = load i32, i32* [[P_PRIV]], align 4 ; IS__TUNIT_NPM-NEXT: ret i32 [[X]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@callee -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: br label [[F:%.*]] -; IS__CGSCC____: T: -; IS__CGSCC____-NEXT: unreachable -; IS__CGSCC____: F: -; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4 -; IS__CGSCC____-NEXT: ret i32 [[X]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_OPM-NEXT: br label [[F:%.*]] +; IS__CGSCC_OPM: T: +; IS__CGSCC_OPM-NEXT: unreachable +; IS__CGSCC_OPM: F: +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callee +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_NPM-NEXT: [[P_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[P_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: br label [[F:%.*]] +; IS__CGSCC_NPM: T: +; IS__CGSCC_NPM-NEXT: unreachable +; IS__CGSCC_NPM: F: +; IS__CGSCC_NPM-NEXT: [[X:%.*]] = load i32, i32* [[P_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 [[X]] ; br i1 %C, label %T, label %F @@ -67,13 +79,22 @@ ; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @callee(i1 noundef false, i32 [[TMP1]]) [[ATTR2:#.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[X]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@foo -; IS__CGSCC____-SAME: () [[ATTR1:#.*]] { -; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: store i32 17, i32* [[A]], align 4 -; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @callee(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]]) [[ATTR2:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[X]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo +; IS__CGSCC_OPM-SAME: () [[ATTR1:#.*]] { +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 17, i32* [[A]], align 4 +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = call i32 @callee(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]]) [[ATTR2:#.*]] +; IS__CGSCC_OPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo +; IS__CGSCC_NPM-SAME: () [[ATTR0]] { +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 17, i32* [[A]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @callee(i32 [[TMP1]]) [[ATTR1:#.*]] +; IS__CGSCC_NPM-NEXT: ret i32 [[X]] ; %A = alloca i32 ; [#uses=2] store i32 17, i32* %A 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 @@ -92,7 +92,7 @@ ; 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 4 +; IS__CGSCC____-NEXT: store i32 [[TMP0]], 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: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll @@ -23,7 +23,7 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f -; IS__CGSCC____-SAME: (%struct.ss* inalloca nocapture nofree noundef nonnull align 4 dereferenceable(8) [[S:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC____-SAME: (%struct.ss* inalloca noalias nocapture nofree noundef nonnull align 4 dereferenceable(8) [[S:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[S]], i32 0, i32 0 ; IS__CGSCC____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 @@ -80,7 +80,7 @@ define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca %b) nounwind { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@g -; IS__CGSCC____-SAME: (%struct.ss* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* inalloca nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[B:%.*]]) [[ATTR1]] { +; IS__CGSCC____-SAME: (%struct.ss* noalias nocapture nofree nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* inalloca noalias nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[B:%.*]]) [[ATTR1]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: ret i1 undef ; diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll @@ -48,7 +48,7 @@ ; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[A]], align 4 ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) [[ATTR3:#.*]] -; IS__CGSCC_OPM-NEXT: ret i32 0 +; IS__CGSCC_OPM-NEXT: ret i32 undef ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller @@ -56,7 +56,7 @@ ; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[A]], align 4 ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) [[ATTR2:#.*]] -; IS__CGSCC_NPM-NEXT: ret i32 undef +; IS__CGSCC_NPM-NEXT: unreachable ; %A = alloca i32 store i32 1, i32* %A diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll @@ -11,29 +11,19 @@ } define internal i32 @test(i32* %X, i32* %Y) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly -; IS__TUNIT____-LABEL: define {{[^@]+}}@test -; IS__TUNIT____-SAME: (i32* noalias nocapture nofree noundef writeonly align 4 [[X:%.*]]) [[ATTR0:#.*]] { -; IS__TUNIT____-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] -; IS__TUNIT____: live: -; IS__TUNIT____-NEXT: store i32 0, i32* [[X]], align 4 -; IS__TUNIT____-NEXT: ret i32 undef -; IS__TUNIT____: dead: -; IS__TUNIT____-NEXT: unreachable -; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef writeonly align 4 [[X:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC_OPM-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] -; IS__CGSCC_OPM: live: -; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[X]], align 4 -; IS__CGSCC_OPM-NEXT: ret i32 undef -; IS__CGSCC_OPM: dead: -; IS__CGSCC_OPM-NEXT: unreachable +; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test +; NOT_CGSCC_NPM-SAME: (i32* noalias nocapture nofree noundef writeonly align 4 [[X:%.*]]) [[ATTR0:#.*]] { +; NOT_CGSCC_NPM-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] +; NOT_CGSCC_NPM: live: +; NOT_CGSCC_NPM-NEXT: store i32 0, i32* [[X]], align 4 +; NOT_CGSCC_NPM-NEXT: ret i32 undef +; NOT_CGSCC_NPM: dead: +; NOT_CGSCC_NPM-NEXT: unreachable ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[X:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[X:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC_NPM-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]] ; IS__CGSCC_NPM: live: ; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[X]], align 4 @@ -54,7 +44,7 @@ define internal i32 @caller(i32* %B) { ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@caller -; IS__TUNIT____-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { +; IS__TUNIT____-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0:#.*]] { ; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__TUNIT____-NEXT: store i32 1, i32* [[A]], align 4 ; IS__TUNIT____-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) [[ATTR2:#.*]] @@ -62,19 +52,19 @@ ; ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[A]], align 4 -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) [[ATTR2:#.*]] -; IS__CGSCC_OPM-NEXT: ret i32 0 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) [[ATTR2:#.*]] +; IS__CGSCC_OPM-NEXT: ret i32 undef ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { ; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[A]], align 4 -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) [[ATTR2:#.*]] -; IS__CGSCC_NPM-NEXT: ret i32 undef +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) [[ATTR2:#.*]] +; IS__CGSCC_NPM-NEXT: unreachable ; %A = alloca i32 store i32 1, i32* %A diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll @@ -72,16 +72,10 @@ } define internal i32 @test2(%T* %p, i32 %p2) { -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test2 -; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) [[ATTR0]] { -; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 -; IS__CGSCC____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2 -; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 -; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 -; IS__CGSCC____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] -; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noundef i32 @foo(%T* undef, i32 [[V]]) [[ATTR5:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[CA]] +; IS__CGSCC____-SAME: (%T* noalias nocapture nofree readnone [[P:%.*]], i32 [[P2:%.*]]) [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i32 undef ; %a.gep = getelementptr %T, %T* %p, i64 0, i32 3 %b.gep = getelementptr %T, %T* %p, i64 0, i32 2 @@ -98,11 +92,10 @@ ; IS__TUNIT____-SAME: (%T* nocapture nofree readnone [[G:%.*]]) [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i32 0 ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2 -; IS__CGSCC____-SAME: (%T* nocapture nofree readonly align 4 [[G:%.*]]) [[ATTR0]] { -; IS__CGSCC____-NEXT: [[V:%.*]] = call noundef i32 @test2(%T* nocapture nofree readonly [[G]], i32 noundef 0) [[ATTR4]] -; IS__CGSCC____-NEXT: ret i32 [[V]] +; IS__CGSCC____-SAME: (%T* nocapture nofree readnone [[G:%.*]]) [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i32 0 ; %v = call i32 @test2(%T* %g, i32 0) ret i32 %v @@ -152,7 +145,7 @@ ; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 ; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 ; IS__CGSCC____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] -; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noundef i32 @bar(%T* undef, i32 [[V]]) [[ATTR6:#.*]] +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call i32 @bar(%T* undef, i32 [[V]]) [[ATTR5:#.*]] ; IS__CGSCC____-NEXT: ret i32 [[CA]] ; %a.gep = getelementptr %T, %T* %p, i64 0, i32 3 @@ -173,9 +166,9 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2b -; IS__CGSCC____-SAME: (%T* nocapture nofree readonly align 4 [[G:%.*]]) [[ATTR3]] { -; IS__CGSCC____-NEXT: [[V:%.*]] = call noundef i32 @test2b(%T* nocapture nofree readonly [[G]], i32 noundef 0) [[ATTR7:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[V]] +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[G:%.*]]) [[ATTR3]] { +; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 noundef undef) [[ATTR6:#.*]] +; IS__CGSCC____-NEXT: ret i32 0 ; %v = call i32 @test2b(%T* %g, i32 0) ret i32 %v diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll @@ -8,18 +8,18 @@ ; Checks if !prof metadata is corret in deadargelim. define void @caller() #0 { -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@caller() { -; NOT_TUNIT_NPM-NEXT: [[X:%.*]] = alloca i32, align 4 -; NOT_TUNIT_NPM-NEXT: store i32 42, i32* [[X]], align 4 -; NOT_TUNIT_NPM-NEXT: call void @promote_i32_ptr(i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[X]]), !prof !0 -; NOT_TUNIT_NPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@caller() { +; IS________OPM-NEXT: [[X:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: store i32 42, i32* [[X]], align 4 +; IS________OPM-NEXT: call void @promote_i32_ptr(i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[X]]), !prof !0 +; IS________OPM-NEXT: ret void ; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller() { -; IS__TUNIT_NPM-NEXT: [[X:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[X]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[X]], align 4 -; IS__TUNIT_NPM-NEXT: call void @promote_i32_ptr(i32 [[TMP1]]), !prof !0 -; IS__TUNIT_NPM-NEXT: ret void +; IS________NPM-LABEL: define {{[^@]+}}@caller() { +; IS________NPM-NEXT: [[X:%.*]] = alloca i32, align 4 +; IS________NPM-NEXT: store i32 42, i32* [[X]], align 4 +; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[X]], align 4 +; IS________NPM-NEXT: call void @promote_i32_ptr(i32 [[TMP1]]), !prof !0 +; IS________NPM-NEXT: ret void ; %x = alloca i32 store i32 42, i32* %x @@ -28,25 +28,19 @@ } define internal void @promote_i32_ptr(i32* %xp) { -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@promote_i32_ptr -; IS__TUNIT_OPM-SAME: (i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[XP:%.*]]) { -; IS__TUNIT_OPM-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4 -; IS__TUNIT_OPM-NEXT: call void @use_i32(i32 [[X]]) -; IS__TUNIT_OPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@promote_i32_ptr +; IS________OPM-SAME: (i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[XP:%.*]]) { +; IS________OPM-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4 +; IS________OPM-NEXT: call void @use_i32(i32 [[X]]) +; IS________OPM-NEXT: ret void ; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote_i32_ptr -; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) { -; IS__TUNIT_NPM-NEXT: [[XP_PRIV:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[XP_PRIV]], align 4 -; IS__TUNIT_NPM-NEXT: [[X:%.*]] = load i32, i32* [[XP_PRIV]], align 4 -; IS__TUNIT_NPM-NEXT: call void @use_i32(i32 [[X]]) -; IS__TUNIT_NPM-NEXT: ret void -; -; IS__CGSCC____-LABEL: define {{[^@]+}}@promote_i32_ptr -; IS__CGSCC____-SAME: (i32* nocapture noundef nonnull readonly align 4 dereferenceable(4) [[XP:%.*]]) { -; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4 -; IS__CGSCC____-NEXT: call void @use_i32(i32 [[X]]) -; IS__CGSCC____-NEXT: ret void +; IS________NPM-LABEL: define {{[^@]+}}@promote_i32_ptr +; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { +; IS________NPM-NEXT: [[XP_PRIV:%.*]] = alloca i32, align 4 +; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[XP_PRIV]], align 4 +; IS________NPM-NEXT: [[X:%.*]] = load i32, i32* [[XP_PRIV]], align 4 +; IS________NPM-NEXT: call void @use_i32(i32 [[X]]) +; IS________NPM-NEXT: ret void ; %x = load i32, i32* %xp call void @use_i32(i32 %x) diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll @@ -31,16 +31,27 @@ ; IS__TUNIT_NPM-NEXT: store i32 [[AB]], i32* [[R]], align 4 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@add -; IS__CGSCC____-SAME: ({ i32, i32 }* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* nocapture nofree noundef nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 -; IS__CGSCC____-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1 -; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8 -; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4 -; IS__CGSCC____-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]] -; IS__CGSCC____-NEXT: store i32 [[AB]], i32* [[R]], align 4 -; IS__CGSCC____-NEXT: ret void +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@add +; IS__CGSCC_OPM-SAME: ({ i32, i32 }* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* nocapture nofree noundef nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_OPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1 +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8 +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4 +; IS__CGSCC_OPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC_OPM-NEXT: store i32 [[AB]], i32* [[R]], align 4 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@add +; IS__CGSCC_NPM-SAME: ({ i32, i32 }* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree noundef nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_NPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8 +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4 +; IS__CGSCC_NPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC_NPM-NEXT: store i32 [[AB]], i32* [[R]], align 4 +; IS__CGSCC_NPM-NEXT: ret void ; %ap = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 0 %bp = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 1 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll @@ -31,7 +31,7 @@ ; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) { ; IS__CGSCC_NPM-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[DATA_PRIV_CAST:%.*]] = bitcast %pair* [[DATA_PRIV]] to i32* -; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]], align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]], align 8 ; IS__CGSCC_NPM-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], %pair* [[DATA_PRIV]], i32 0, i32 1 ; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* noundef nonnull align 8 dereferenceable(8) [[DATA_PRIV]]) diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll @@ -31,17 +31,11 @@ ; Function Attrs: nounwind uwtable define internal void @callee_t0f(i8* nocapture readnone %tp13, i8* nocapture readnone %tp14, i8* nocapture readnone %tp15, i8* nocapture readnone %tp16, i8* nocapture readnone %tp17, ...) { -; IS__TUNIT____-LABEL: define {{[^@]+}}@callee_t0f -; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull readnone [[TP13:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP14:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP15:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP16:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP17:%.*]], ...) { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: call void @sink(i32 noundef 0) -; IS__TUNIT____-NEXT: ret void -; -; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_t0f -; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull readnone [[TP13:%.*]], i8* nocapture nofree nonnull readnone [[TP14:%.*]], i8* nocapture nofree nonnull readnone [[TP15:%.*]], i8* nocapture nofree nonnull readnone [[TP16:%.*]], i8* nocapture nofree nonnull readnone [[TP17:%.*]], ...) { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: call void @sink(i32 noundef 0) -; IS__CGSCC____-NEXT: ret void +; CHECK-LABEL: define {{[^@]+}}@callee_t0f +; CHECK-SAME: (i8* noalias nocapture nofree nonnull readnone [[TP13:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP14:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP15:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP16:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP17:%.*]], ...) { +; CHECK-NEXT: entry: +; CHECK-NEXT: call void @sink(i32 noundef 0) +; CHECK-NEXT: ret void ; entry: call void @sink(i32 0) 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 @@ -27,7 +27,7 @@ ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]], align 8 ; 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 1 +; 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: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 @@ -187,7 +187,7 @@ ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]], align 8 ; 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 1 +; 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: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll @@ -15,12 +15,19 @@ ; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) [[ATTR0]], [[RNG0:!range !.*]] ; IS__TUNIT____-NEXT: ret i64 [[CALL2]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2 -; IS__CGSCC____-SAME: () [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) [[ATTR1:#.*]] -; IS__CGSCC____-NEXT: ret i64 [[CALL2]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn2 +; IS__CGSCC_OPM-SAME: () [[ATTR0:#.*]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) [[ATTR1:#.*]] +; IS__CGSCC_OPM-NEXT: ret i64 [[CALL2]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn2 +; IS__CGSCC_NPM-SAME: () [[ATTR0:#.*]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) [[ATTR1:#.*]], [[RNG0:!range !.*]] +; IS__CGSCC_NPM-NEXT: ret i64 [[CALL2]] ; entry: %conv = sext i32 undef to i64 @@ -41,11 +48,11 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2b -; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) [[ATTR0]] { +; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64 ; IS__CGSCC____-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]] -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) [[ATTR1]] +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) [[ATTR1:#.*]], [[RNG0:!range !.*]] ; IS__CGSCC____-NEXT: ret i64 [[CALL2]] ; entry: @@ -67,7 +74,8 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2c ; IS__CGSCC____-SAME: () [[ATTR0]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: ret i64 42 +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 noundef 42) [[ATTR1]] +; IS__CGSCC____-NEXT: ret i64 [[CALL2]] ; entry: %conv = sext i32 undef to i64 diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll @@ -44,8 +44,7 @@ ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo ; IS__CGSCC_NPM-SAME: (i16 [[A:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noundef i16 @bar() [[ATTR1:#.*]] -; IS__CGSCC_NPM-NEXT: ret i16 [[CALL]] +; IS__CGSCC_NPM-NEXT: ret i16 0 ; %call = call i16 bitcast (i16 (i16, i16) * @bar to i16 (i16) *)(i16 %a) ret i16 %call @@ -57,10 +56,15 @@ ; IS__TUNIT____-SAME: () [[ATTR0:#.*]] { ; IS__TUNIT____-NEXT: ret i16 0 ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@bar -; IS__CGSCC____-SAME: () [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: ret i16 0 +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar +; IS__CGSCC_OPM-SAME: () [[ATTR0:#.*]] { +; IS__CGSCC_OPM-NEXT: ret i16 0 +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar +; IS__CGSCC_NPM-SAME: () [[ATTR0]] { +; IS__CGSCC_NPM-NEXT: ret i16 undef ; ret i16 0 } @@ -84,7 +88,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@bar2 -; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) [[ATTR0]] { +; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC____-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]] ; IS__CGSCC____-NEXT: ret i16 [[A]] ; @@ -99,18 +103,11 @@ ; been provided), define dso_local i16 @vararg_tests(i16 %a) { -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@vararg_tests -; NOT_CGSCC_OPM-SAME: (i16 [[A:%.*]]) { -; NOT_CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 noundef 7) -; NOT_CGSCC_OPM-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]] -; NOT_CGSCC_OPM-NEXT: ret i16 [[ADD]] -; -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vararg_tests -; IS__CGSCC_OPM-SAME: (i16 [[A:%.*]]) { -; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i16 (i16, ...) @vararg_prop(i16 noundef 7, i16 noundef 8, i16 [[A]]) [[ATTR1:#.*]] -; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 noundef 7) -; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i16 [[CALL1]], [[CALL2]] -; IS__CGSCC_OPM-NEXT: ret i16 [[ADD]] +; CHECK-LABEL: define {{[^@]+}}@vararg_tests +; CHECK-SAME: (i16 [[A:%.*]]) { +; CHECK-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 noundef 7) +; CHECK-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]] +; CHECK-NEXT: ret i16 [[ADD]] ; %call1 = call i16 (i16, ...) @vararg_prop(i16 7, i16 8, i16 %a) %call2 = call i16 bitcast (i16 (i16, i16, ...) * @vararg_no_prop to i16 (i16) *) (i16 7) diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll @@ -30,16 +30,16 @@ ; IS__CGSCC____-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0 ; IS__CGSCC____-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]] ; IS__CGSCC____: true: -; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noalias noundef align 536870912 i8* @side_effects(i8 [[V]]) +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]]) ; IS__CGSCC____-NEXT: ret i8* [[CA]] ; IS__CGSCC____: false: ; IS__CGSCC____-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1 ; IS__CGSCC____-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]] ; IS__CGSCC____: c2_true: -; IS__CGSCC____-NEXT: [[CA1:%.*]] = musttail call noalias noundef align 536870912 i8* @no_side_effects(i8 [[V]]) +; IS__CGSCC____-NEXT: [[CA1:%.*]] = musttail call i8* @no_side_effects(i8 undef) ; IS__CGSCC____-NEXT: ret i8* [[CA1]] ; IS__CGSCC____: c2_false: -; IS__CGSCC____-NEXT: [[CA2:%.*]] = musttail call noalias noundef align 536870912 i8* @dont_zap_me(i8 [[V]]) +; IS__CGSCC____-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef) ; IS__CGSCC____-NEXT: ret i8* [[CA2]] ; %c1 = icmp eq i8 %v, 0 @@ -61,17 +61,11 @@ } define internal i8* @side_effects(i8 %v) { -; IS__TUNIT____-LABEL: define {{[^@]+}}@side_effects -; IS__TUNIT____-SAME: (i8 [[V:%.*]]) { -; IS__TUNIT____-NEXT: [[I1:%.*]] = call i32 @external() -; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]]) -; IS__TUNIT____-NEXT: ret i8* [[CA]] -; -; IS__CGSCC____-LABEL: define {{[^@]+}}@side_effects -; IS__CGSCC____-SAME: (i8 [[V:%.*]]) { -; IS__CGSCC____-NEXT: [[I1:%.*]] = call i32 @external() -; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noalias noundef align 536870912 i8* @start(i8 [[V]]) -; IS__CGSCC____-NEXT: ret i8* [[CA]] +; CHECK-LABEL: define {{[^@]+}}@side_effects +; CHECK-SAME: (i8 [[V:%.*]]) { +; CHECK-NEXT: [[I1:%.*]] = call i32 @external() +; CHECK-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]]) +; CHECK-NEXT: ret i8* [[CA]] ; %i1 = call i32 @external() @@ -89,21 +83,16 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@no_side_effects ; IS__CGSCC____-SAME: (i8 [[V:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: ret i8* null +; IS__CGSCC____-NEXT: ret i8* undef ; ret i8* null } define internal i8* @dont_zap_me(i8 %v) { -; IS__TUNIT____-LABEL: define {{[^@]+}}@dont_zap_me -; IS__TUNIT____-SAME: (i8 [[V:%.*]]) { -; IS__TUNIT____-NEXT: [[I1:%.*]] = call i32 @external() -; IS__TUNIT____-NEXT: ret i8* undef -; -; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_zap_me -; IS__CGSCC____-SAME: (i8 [[V:%.*]]) { -; IS__CGSCC____-NEXT: [[I1:%.*]] = call i32 @external() -; IS__CGSCC____-NEXT: ret i8* null +; CHECK-LABEL: define {{[^@]+}}@dont_zap_me +; CHECK-SAME: (i8 [[V:%.*]]) { +; CHECK-NEXT: [[I1:%.*]] = call i32 @external() +; CHECK-NEXT: ret i8* undef ; %i1 = call i32 @external() ret i8* null diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll @@ -83,127 +83,127 @@ } define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %N, float* dereferenceable(4) %p, i64 %q) { -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@.omp_outlined. -; NOT_TUNIT_NPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { -; NOT_TUNIT_NPM-NEXT: entry: -; NOT_TUNIT_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 -; NOT_TUNIT_NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 -; NOT_TUNIT_NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* -; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 -; NOT_TUNIT_NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 -; NOT_TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 -; NOT_TUNIT_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] -; NOT_TUNIT_NPM: omp.precond.then: -; NOT_TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 -; NOT_TUNIT_NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 -; NOT_TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; NOT_TUNIT_NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) -; NOT_TUNIT_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] -; NOT_TUNIT_NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; NOT_TUNIT_NPM: cond.true: -; NOT_TUNIT_NPM-NEXT: br label [[COND_END:%.*]] -; NOT_TUNIT_NPM: cond.false: -; NOT_TUNIT_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: br label [[COND_END]] -; NOT_TUNIT_NPM: cond.end: -; NOT_TUNIT_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] -; NOT_TUNIT_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 -; NOT_TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] -; NOT_TUNIT_NPM: omp.inner.for.cond: -; NOT_TUNIT_NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] -; NOT_TUNIT_NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; NOT_TUNIT_NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] -; NOT_TUNIT_NPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] -; NOT_TUNIT_NPM: omp.inner.for.cond.cleanup: -; NOT_TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] -; NOT_TUNIT_NPM: omp.inner.for.body: -; NOT_TUNIT_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 -; NOT_TUNIT_NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 -; NOT_TUNIT_NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) -; NOT_TUNIT_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] -; NOT_TUNIT_NPM: omp.body.continue: -; NOT_TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_INC]] -; NOT_TUNIT_NPM: omp.inner.for.inc: -; NOT_TUNIT_NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 -; NOT_TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND]] -; NOT_TUNIT_NPM: omp.inner.for.end: -; NOT_TUNIT_NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] -; NOT_TUNIT_NPM: omp.loop.exit: -; NOT_TUNIT_NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; NOT_TUNIT_NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]]) -; NOT_TUNIT_NPM-NEXT: br label [[OMP_PRECOND_END]] -; NOT_TUNIT_NPM: omp.precond.end: -; NOT_TUNIT_NPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS________OPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 +; IS________OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +; IS________OPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 +; IS________OPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* +; IS________OPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 +; IS________OPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 +; IS________OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 +; IS________OPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +; IS________OPM: omp.precond.then: +; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS________OPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS________OPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) +; IS________OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] +; IS________OPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS________OPM: cond.true: +; IS________OPM-NEXT: br label [[COND_END:%.*]] +; IS________OPM: cond.false: +; IS________OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: br label [[COND_END]] +; IS________OPM: cond.end: +; IS________OPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] +; IS________OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +; IS________OPM: omp.inner.for.cond: +; IS________OPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] +; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________OPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] +; IS________OPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] +; IS________OPM: omp.inner.for.cond.cleanup: +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] +; IS________OPM: omp.inner.for.body: +; IS________OPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 +; IS________OPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 +; IS________OPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 +; IS________OPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) +; IS________OPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +; IS________OPM: omp.body.continue: +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_INC]] +; IS________OPM: omp.inner.for.inc: +; IS________OPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND]] +; IS________OPM: omp.inner.for.end: +; IS________OPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +; IS________OPM: omp.loop.exit: +; IS________OPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS________OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]]) +; IS________OPM-NEXT: br label [[OMP_PRECOND_END]] +; IS________OPM: omp.precond.end: +; IS________OPM-NEXT: ret void ; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@.omp_outlined. -; IS__TUNIT_NPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 -; IS__TUNIT_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 -; IS__TUNIT_NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 -; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* -; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 -; IS__TUNIT_NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 -; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 -; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] -; IS__TUNIT_NPM: omp.precond.then: -; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 -; IS__TUNIT_NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 -; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__TUNIT_NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) -; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] -; IS__TUNIT_NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; IS__TUNIT_NPM: cond.true: -; IS__TUNIT_NPM-NEXT: br label [[COND_END:%.*]] -; IS__TUNIT_NPM: cond.false: -; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: br label [[COND_END]] -; IS__TUNIT_NPM: cond.end: -; IS__TUNIT_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] -; IS__TUNIT_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 -; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] -; IS__TUNIT_NPM: omp.inner.for.cond: -; IS__TUNIT_NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] -; IS__TUNIT_NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS__TUNIT_NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] -; IS__TUNIT_NPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] -; IS__TUNIT_NPM: omp.inner.for.cond.cleanup: -; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] -; IS__TUNIT_NPM: omp.inner.for.body: -; IS__TUNIT_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 -; IS__TUNIT_NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 -; IS__TUNIT_NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) -; IS__TUNIT_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] -; IS__TUNIT_NPM: omp.body.continue: -; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_INC]] -; IS__TUNIT_NPM: omp.inner.for.inc: -; IS__TUNIT_NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 -; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND]] -; IS__TUNIT_NPM: omp.inner.for.end: -; IS__TUNIT_NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] -; IS__TUNIT_NPM: omp.loop.exit: -; IS__TUNIT_NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 -; IS__TUNIT_NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]]) -; IS__TUNIT_NPM-NEXT: br label [[OMP_PRECOND_END]] -; IS__TUNIT_NPM: omp.precond.end: -; IS__TUNIT_NPM-NEXT: ret void +; IS________NPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS________NPM-SAME: (i32* noalias nocapture readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 +; IS________NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +; IS________NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +; IS________NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +; IS________NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +; IS________NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]], align 8 +; IS________NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double* +; IS________NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4 +; IS________NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3 +; IS________NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2 +; IS________NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +; IS________NPM: omp.precond.then: +; IS________NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS________NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4 +; IS________NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS________NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS________NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS________NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) +; IS________NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]] +; IS________NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS________NPM: cond.true: +; IS________NPM-NEXT: br label [[COND_END:%.*]] +; IS________NPM: cond.false: +; IS________NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________NPM-NEXT: br label [[COND_END]] +; IS________NPM: cond.end: +; IS________NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ] +; IS________NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS________NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS________NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +; IS________NPM: omp.inner.for.cond: +; IS________NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ] +; IS________NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS________NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]] +; IS________NPM-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]] +; IS________NPM: omp.inner.for.cond.cleanup: +; IS________NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] +; IS________NPM: omp.inner.for.body: +; IS________NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 +; IS________NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 +; IS________NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 +; IS________NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) +; IS________NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +; IS________NPM: omp.body.continue: +; IS________NPM-NEXT: br label [[OMP_INNER_FOR_INC]] +; IS________NPM: omp.inner.for.inc: +; IS________NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1 +; IS________NPM-NEXT: br label [[OMP_INNER_FOR_COND]] +; IS________NPM: omp.inner.for.end: +; IS________NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +; IS________NPM: omp.loop.exit: +; IS________NPM-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS________NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 [[TMP12]]) +; IS________NPM-NEXT: br label [[OMP_PRECOND_END]] +; IS________NPM: omp.precond.end: +; IS________NPM-NEXT: ret void ; entry: %q.addr = alloca i64, align 8 diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll @@ -50,7 +50,7 @@ ; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree noundef readnone align 536870912 null) ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*)) ; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]]) -; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC2]]) +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]]) ; IS__CGSCC____-NEXT: ret i32 0 ; entry: @@ -92,7 +92,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@bar -; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[ARG:%.*]]) [[ATTR0]] { +; IS__CGSCC____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]]) [[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*) ; @@ -109,7 +109,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@baz -; IS__CGSCC____-SAME: (i8* nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) [[ATTR0]] { +; IS__CGSCC____-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) [[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: ret i8* [[ARG]] ; @@ -126,7 +126,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@buz -; IS__CGSCC____-SAME: (i8* nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) [[ATTR0]] { +; IS__CGSCC____-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) [[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: ret i8* [[ARG]] ; diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll @@ -38,7 +38,7 @@ ; IS__CGSCC____-NEXT: i64 10, label [[RETURN]] ; IS__CGSCC____-NEXT: ] ; IS__CGSCC____: sw.default: -; IS__CGSCC____-NEXT: ret i32 123 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: return: ; IS__CGSCC____-NEXT: unreachable ; diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll @@ -22,7 +22,7 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@incdec -; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: T: @@ -97,7 +97,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR1]] personality i32 (...)* @__gxx_personality_v0 { ; IS__CGSCC____-NEXT: [[Q:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[Q]]) [[ATTR2:#.*]] +; IS__CGSCC____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) [[ATTR2:#.*]] ; IS__CGSCC____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) [[ATTR3:#.*]] ; IS__CGSCC____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 ; IS__CGSCC____-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) [[ATTR4:#.*]] diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll @@ -52,9 +52,9 @@ ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: T: -; IS__CGSCC____-NEXT: ret i32 52 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: F: -; IS__CGSCC____-NEXT: ret i32 52 +; IS__CGSCC____-NEXT: ret i32 undef ; br i1 %C, label %T, label %F diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll b/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll @@ -15,7 +15,7 @@ ; IS__CGSCC____: if.then: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: ret i32 10 +; IS__CGSCC____-NEXT: ret i32 undef ; entry: br i1 %c, label %if.cond, label %if.end @@ -39,7 +39,7 @@ ; IS__CGSCC____: if.then: ; IS__CGSCC____-NEXT: br label [[RET1:%.*]] ; IS__CGSCC____: ret1: -; IS__CGSCC____-NEXT: ret i32 99 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: ret2: ; IS__CGSCC____-NEXT: unreachable ; diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll --- a/llvm/test/Transforms/Attributor/align.ll +++ b/llvm/test/Transforms/Attributor/align.ll @@ -162,12 +162,12 @@ ; ; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1 -; IS__CGSCC_OPM-SAME: (i8* nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr [[ATTR2:#.*]] { +; IS__CGSCC_OPM-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr [[ATTR2:#.*]] { ; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]] ; IS__CGSCC_OPM: 2: ; IS__CGSCC_OPM-NEXT: unreachable ; IS__CGSCC_OPM: 3: -; IS__CGSCC_OPM-NEXT: ret i8* [[TMP0]] +; IS__CGSCC_OPM-NEXT: ret i8* undef ; ; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1 @@ -176,7 +176,7 @@ ; IS__CGSCC_NPM: 1: ; IS__CGSCC_NPM-NEXT: unreachable ; IS__CGSCC_NPM: 2: -; IS__CGSCC_NPM-NEXT: ret i8* @a1 +; IS__CGSCC_NPM-NEXT: unreachable ; %2 = icmp eq i8* %0, null br i1 %2, label %3, label %5 @@ -233,17 +233,10 @@ ; IS__TUNIT____-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) [[ATTR9:#.*]] ; IS__TUNIT____-NEXT: ret i8* [[C]] ; -; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test7 -; IS__CGSCC_OPM-SAME: () [[ATTR2]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) @a1) [[ATTR12:#.*]] -; IS__CGSCC_OPM-NEXT: ret i8* [[C]] -; -; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test7 -; IS__CGSCC_NPM-SAME: () [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = tail call noundef nonnull align 8 dereferenceable(1) i8* @f1() [[ATTR11:#.*]] -; IS__CGSCC_NPM-NEXT: ret i8* [[C]] +; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test7 +; IS__CGSCC____-SAME: () [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i8* @a1 ; %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1) ret i8* %c @@ -254,12 +247,12 @@ define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 { ; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1b -; IS__CGSCC_OPM-SAME: (i8* nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr [[ATTR2]] { +; IS__CGSCC_OPM-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr [[ATTR2]] { ; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]] ; IS__CGSCC_OPM: 2: ; IS__CGSCC_OPM-NEXT: unreachable ; IS__CGSCC_OPM: 3: -; IS__CGSCC_OPM-NEXT: ret i8* [[TMP0]] +; IS__CGSCC_OPM-NEXT: ret i8* undef ; ; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1b @@ -268,7 +261,7 @@ ; IS__CGSCC_NPM: 1: ; IS__CGSCC_NPM-NEXT: unreachable ; IS__CGSCC_NPM: 2: -; IS__CGSCC_NPM-NEXT: ret i8* undef +; IS__CGSCC_NPM-NEXT: unreachable ; %2 = icmp eq i8* %0, null br i1 %2, label %3, label %5 @@ -366,29 +359,21 @@ declare void @user_i32_ptr(i32* nocapture readnone) nounwind define internal void @test8(i32* %a, i32* %b, i32* %c) { -; IS__TUNIT____: Function Attrs: nounwind -; IS__TUNIT____-LABEL: define {{[^@]+}}@test8 -; IS__TUNIT____-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) [[ATTR2:#.*]] { -; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) [[ATTR2]] -; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) [[ATTR2]] -; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) [[ATTR2]] -; IS__TUNIT____-NEXT: ret void +; NOT_CGSCC_OPM: Function Attrs: nounwind +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test8 +; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) [[ATTR2]] { +; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) [[ATTR2]] +; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) [[ATTR2]] +; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) [[ATTR2]] +; NOT_CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: nounwind ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8 -; IS__CGSCC_OPM-SAME: (i32* nocapture readnone align 4 [[A:%.*]], i32* nocapture readnone align 4 [[B:%.*]], i32* nocapture readnone [[C:%.*]]) [[ATTR3]] { +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) [[ATTR3]] { ; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) [[ATTR3]] ; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) [[ATTR3]] ; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) [[ATTR3]] ; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: nounwind -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test8 -; IS__CGSCC_NPM-SAME: (i32* nocapture readnone align 4 [[A:%.*]], i32* nocapture readnone align 4 [[B:%.*]], i32* nocapture readnone [[C:%.*]]) [[ATTR2:#.*]] { -; IS__CGSCC_NPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) [[ATTR2]] -; IS__CGSCC_NPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) [[ATTR2]] -; IS__CGSCC_NPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) [[ATTR2]] -; IS__CGSCC_NPM-NEXT: ret void ; call void @user_i32_ptr(i32* %a) call void @user_i32_ptr(i32* %b) @@ -982,7 +967,7 @@ ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] ; IS__CGSCC_OPM: mt: -; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR13:#.*]] +; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR12:#.*]] ; IS__CGSCC_OPM-NEXT: ret i32 [[V]] ; IS__CGSCC_OPM: exit: ; IS__CGSCC_OPM-NEXT: ret i32 0 @@ -993,7 +978,7 @@ ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] ; IS__CGSCC_NPM: mt: -; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR12:#.*]] +; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR11:#.*]] ; IS__CGSCC_NPM-NEXT: ret i32 [[V]] ; IS__CGSCC_NPM: exit: ; IS__CGSCC_NPM-NEXT: ret i32 0 diff --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll --- a/llvm/test/Transforms/Attributor/callbacks.ll +++ b/llvm/test/Transforms/Attributor/callbacks.ll @@ -79,23 +79,23 @@ ; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call. define internal void @t0_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { ; -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@t0_callback_callee -; NOT_TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; NOT_TUNIT_NPM-NEXT: entry: -; NOT_TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; NOT_TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; NOT_TUNIT_NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* [[TMP0]]) -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_callback_callee -; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS__TUNIT_NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* [[TMP0]]) -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@t0_callback_callee +; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________OPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* [[TMP0]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@t0_callback_callee +; IS________NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* [[TMP0]]) +; IS________NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 @@ -178,25 +178,25 @@ ; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call. define internal void @t1_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { ; -; NOT_TUNIT_NPM: Function Attrs: nosync -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@t1_callback_callee -; NOT_TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) [[ATTR0:#.*]] { -; NOT_TUNIT_NPM-NEXT: entry: -; NOT_TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; NOT_TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; NOT_TUNIT_NPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM: Function Attrs: nosync -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_callback_callee -; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* noalias nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) [[ATTR0:#.*]] { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS__TUNIT_NPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM: Function Attrs: nosync +; IS________OPM-LABEL: define {{[^@]+}}@t1_callback_callee +; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) [[ATTR0:#.*]] { +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________OPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM: Function Attrs: nosync +; IS________NPM-LABEL: define {{[^@]+}}@t1_callback_callee +; IS________NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* noalias nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) [[ATTR0:#.*]] { +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________NPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS________NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 @@ -280,23 +280,23 @@ ; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls. define internal void @t2_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { ; -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@t2_callback_callee -; NOT_TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; NOT_TUNIT_NPM-NEXT: entry: -; NOT_TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; NOT_TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; NOT_TUNIT_NPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_callback_callee -; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS__TUNIT_NPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@t2_callback_callee +; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________OPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@t2_callback_callee +; IS________NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________NPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS________NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 @@ -385,23 +385,23 @@ ; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls. define internal void @t3_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) { ; -; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@t3_callback_callee -; NOT_TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; NOT_TUNIT_NPM-NEXT: entry: -; NOT_TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; NOT_TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; NOT_TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; NOT_TUNIT_NPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) -; NOT_TUNIT_NPM-NEXT: ret void -; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_callback_callee -; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS__TUNIT_NPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) -; IS__TUNIT_NPM-NEXT: ret void +; IS________OPM-LABEL: define {{[^@]+}}@t3_callback_callee +; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________OPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS________OPM-NEXT: ret void +; +; IS________NPM-LABEL: define {{[^@]+}}@t3_callback_callee +; IS________NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS________NPM-NEXT: entry: +; IS________NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS________NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS________NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS________NPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS________NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 diff --git a/llvm/test/Transforms/Attributor/internal-noalias.ll b/llvm/test/Transforms/Attributor/internal-noalias.ll --- a/llvm/test/Transforms/Attributor/internal-noalias.ll +++ b/llvm/test/Transforms/Attributor/internal-noalias.ll @@ -14,14 +14,23 @@ ; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; IS__TUNIT____-NEXT: ret i32 [[ADD]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@visible -; IS__CGSCC____-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR3:#.*]] -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR3]] -; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] -; IS__CGSCC____-NEXT: ret i32 [[ADD]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@visible +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR3:#.*]] +; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] +; IS__CGSCC_OPM-NEXT: ret i32 [[ADD]] +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@visible +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4:#.*]] +; IS__CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4]] +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[ADD]] ; entry: %call1 = call i32 @noalias_args(i32* %A, i32* %B) @@ -42,16 +51,27 @@ ; IS__TUNIT____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] ; IS__TUNIT____-NEXT: ret i32 [[ADD2]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args -; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 -; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR3]] -; IS__CGSCC____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] -; IS__CGSCC____-NEXT: ret i32 [[ADD2]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@noalias_args +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4:#.*]] +; IS__CGSCC_OPM-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] +; IS__CGSCC_OPM-NEXT: ret i32 [[ADD2]] +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@noalias_args +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR5:#.*]] +; IS__CGSCC_NPM-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] +; IS__CGSCC_NPM-NEXT: ret i32 [[ADD2]] ; entry: %0 = load i32, i32* %A, align 4 @@ -75,7 +95,7 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem -; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 @@ -101,16 +121,27 @@ ; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; IS__TUNIT____-NEXT: ret i32 [[ADD]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local -; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) [[ATTR1:#.*]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4 -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) -; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] -; IS__CGSCC____-NEXT: ret i32 [[ADD]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@visible_local +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) [[ATTR1:#.*]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 5, i32* [[B]], align 4 +; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4]] +; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4]] +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] +; IS__CGSCC_OPM-NEXT: ret i32 [[ADD]] +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@visible_local +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) [[ATTR1:#.*]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 5, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR5]] +; IS__CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR5]] +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[ADD]] ; entry: %B = alloca i32, align 4 @@ -142,13 +173,25 @@ ; IS__TUNIT_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]] ; IS__TUNIT_NPM-NEXT: ret i32 [[ADD]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem_ro -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { -; IS__CGSCC____-NEXT: [[T0:%.*]] = load i32, i32* [[A]], align 4 -; IS__CGSCC____-NEXT: [[T1:%.*]] = load i32, i32* [[B]], align 4 -; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]] -; IS__CGSCC____-NEXT: ret i32 [[ADD]] +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@noalias_args_argmem_ro +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) [[ATTR0]] { +; IS__CGSCC_OPM-NEXT: [[T0:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC_OPM-NEXT: [[T1:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]] +; IS__CGSCC_OPM-NEXT: ret i32 [[ADD]] +; +; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@noalias_args_argmem_ro +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) [[ATTR2:#.*]] { +; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[B_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[T0:%.*]] = load i32, i32* [[A_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[T1:%.*]] = load i32, i32* [[B_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]] +; IS__CGSCC_NPM-NEXT: ret i32 [[ADD]] ; %t0 = load i32, i32* %A, align 4 %t1 = load i32, i32* %B, align 4 @@ -175,13 +218,23 @@ ; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32 [[TMP1]], i32 [[TMP2]]) [[ATTR4:#.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local_2 -; IS__CGSCC____-SAME: () [[ATTR2:#.*]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4 -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR4:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[CALL]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@visible_local_2 +; IS__CGSCC_OPM-SAME: () [[ATTR2:#.*]] { +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 5, i32* [[B]], align 4 +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) [[ATTR5:#.*]] +; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@visible_local_2 +; IS__CGSCC_NPM-SAME: () [[ATTR3:#.*]] { +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 5, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32 [[TMP1]], i32 [[TMP2]]) [[ATTR6:#.*]] +; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; %B = alloca i32, align 4 store i32 5, i32* %B, align 4 @@ -199,7 +252,7 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem_rn -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B:%.*]]) [[ATTR1]] { +; IS__CGSCC____-SAME: (i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B:%.*]]) [[ATTR1:#.*]] { ; IS__CGSCC____-NEXT: [[T0:%.*]] = load i32, i32* [[B]], align 4 ; IS__CGSCC____-NEXT: store i32 0, i32* [[B]], align 4 ; IS__CGSCC____-NEXT: ret i32 [[T0]] @@ -218,13 +271,21 @@ ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B]]) [[ATTR5:#.*]] ; IS__TUNIT____-NEXT: ret i32 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local_3 -; IS__CGSCC____-SAME: () [[ATTR2]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4 -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B]]) [[ATTR5:#.*]] -; IS__CGSCC____-NEXT: ret i32 [[CALL]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@visible_local_3 +; IS__CGSCC_OPM-SAME: () [[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 5, i32* [[B]], align 4 +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B]]) [[ATTR6:#.*]] +; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@visible_local_3 +; IS__CGSCC_NPM-SAME: () [[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 5, i32* [[B]], align 4 +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B]]) [[ATTR7:#.*]] +; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; %B = alloca i32, align 4 store i32 5, i32* %B, align 4 diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll --- a/llvm/test/Transforms/Attributor/liveness.ll +++ b/llvm/test/Transforms/Attributor/liveness.ll @@ -883,22 +883,22 @@ ; IS__CGSCC____-NEXT: call void @non_dead_b3() [[ATTR16]] ; IS__CGSCC____-NEXT: br label [[BB1:%.*]] ; IS__CGSCC____: bb1: -; IS__CGSCC____-NEXT: call void @non_dead_b4() [[ATTR2:#.*]] -; IS__CGSCC____-NEXT: call void @non_dead_b5() [[ATTR2]] -; IS__CGSCC____-NEXT: call void @non_dead_b6() [[ATTR2]] -; IS__CGSCC____-NEXT: call void @non_dead_b7() [[ATTR2]] +; IS__CGSCC____-NEXT: call void @non_dead_b4() [[ATTR16]] +; IS__CGSCC____-NEXT: call void @non_dead_b5() [[ATTR16]] +; IS__CGSCC____-NEXT: call void @non_dead_b6() [[ATTR16]] +; IS__CGSCC____-NEXT: call void @non_dead_b7() [[ATTR16]] ; IS__CGSCC____-NEXT: br label [[BB2:%.*]] ; IS__CGSCC____: bb2: -; IS__CGSCC____-NEXT: call void @non_dead_b8() [[ATTR2]] -; IS__CGSCC____-NEXT: call void @non_dead_b9() [[ATTR2]] -; IS__CGSCC____-NEXT: call void @non_dead_b10() [[ATTR2]] -; IS__CGSCC____-NEXT: call void @non_dead_b11() [[ATTR2]] +; IS__CGSCC____-NEXT: call void @non_dead_b8() [[ATTR16]] +; IS__CGSCC____-NEXT: call void @non_dead_b9() [[ATTR16]] +; IS__CGSCC____-NEXT: call void @non_dead_b10() [[ATTR16]] +; IS__CGSCC____-NEXT: call void @non_dead_b11() [[ATTR16]] ; IS__CGSCC____-NEXT: br label [[BB3:%.*]] ; IS__CGSCC____: bb3: -; IS__CGSCC____-NEXT: call void @non_dead_b12() [[ATTR2]] -; IS__CGSCC____-NEXT: call void @non_dead_b13() [[ATTR2]] -; IS__CGSCC____-NEXT: call void @non_dead_b14() [[ATTR2]] -; IS__CGSCC____-NEXT: call void @non_dead_b15() [[ATTR2]] +; IS__CGSCC____-NEXT: call void @non_dead_b12() [[ATTR16]] +; IS__CGSCC____-NEXT: call void @non_dead_b13() [[ATTR16]] +; IS__CGSCC____-NEXT: call void @non_dead_b14() [[ATTR16]] +; IS__CGSCC____-NEXT: call void @non_dead_b15() [[ATTR16]] ; IS__CGSCC____-NEXT: br label [[BB4:%.*]] ; IS__CGSCC____: bb4: ; IS__CGSCC____-NEXT: call void @non_exact2() @@ -2186,7 +2186,7 @@ ; IS__CGSCC____-NEXT: ] ; IS__CGSCC____: sw.default: ; IS__CGSCC____-NEXT: call void @sink() [[ATTR16]] -; IS__CGSCC____-NEXT: ret i32 123 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: return: ; IS__CGSCC____-NEXT: unreachable ; @@ -2231,7 +2231,7 @@ ; IS__CGSCC____-NEXT: i64 10, label [[RETURN]] ; IS__CGSCC____-NEXT: ] ; IS__CGSCC____: sw.default: -; IS__CGSCC____-NEXT: ret i32 123 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: return: ; IS__CGSCC____-NEXT: unreachable ; diff --git a/llvm/test/Transforms/Attributor/memory_locations.ll b/llvm/test/Transforms/Attributor/memory_locations.ll --- a/llvm/test/Transforms/Attributor/memory_locations.ll +++ b/llvm/test/Transforms/Attributor/memory_locations.ll @@ -558,7 +558,7 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal -; IS__CGSCC____-SAME: (i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) [[ATTR8]] { +; IS__CGSCC____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) [[ATTR8]] { ; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: @@ -616,7 +616,7 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2 -; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) [[ATTR8]] { +; IS__CGSCC____-SAME: (i8* noalias nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) [[ATTR8]] { ; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll --- a/llvm/test/Transforms/Attributor/noalias.ll +++ b/llvm/test/Transforms/Attributor/noalias.ll @@ -512,7 +512,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@p2i -; IS__CGSCC____-SAME: (i32* nofree readnone [[ARG:%.*]]) [[ATTR0]] { +; IS__CGSCC____-SAME: (i32* noalias nofree readnone [[ARG:%.*]]) [[ATTR0]] { ; IS__CGSCC____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32 ; IS__CGSCC____-NEXT: ret i32 [[P2I]] ; @@ -572,17 +572,29 @@ ; Function Attrs: nounwind optsize define internal fastcc double @strtox(i8* %s, i8** %p, i32 %prec) unnamed_addr { -; CHECK-LABEL: define {{[^@]+}}@strtox -; CHECK-SAME: (i8* [[S:%.*]]) unnamed_addr { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 -; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* -; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture noundef nonnull align 8 dereferenceable(240) [[TMP0]]) [[ATTR10:#.*]] -; CHECK-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) -; CHECK-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) -; CHECK-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) -; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture noundef nonnull align 8 dereferenceable(240) [[TMP0]]) -; CHECK-NEXT: ret double [[CALL1]] +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@strtox +; NOT_CGSCC_NPM-SAME: (i8* [[S:%.*]]) unnamed_addr { +; NOT_CGSCC_NPM-NEXT: entry: +; NOT_CGSCC_NPM-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 +; NOT_CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* +; NOT_CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture noundef nonnull align 8 dereferenceable(240) [[TMP0]]) [[ATTR10:#.*]] +; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) +; NOT_CGSCC_NPM-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) +; NOT_CGSCC_NPM-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) +; NOT_CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture noundef nonnull align 8 dereferenceable(240) [[TMP0]]) +; NOT_CGSCC_NPM-NEXT: ret double [[CALL1]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@strtox +; IS__CGSCC____-SAME: (i8* noalias [[S:%.*]]) unnamed_addr { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* +; IS__CGSCC____-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture noundef nonnull align 8 dereferenceable(240) [[TMP0]]) [[ATTR10]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) +; IS__CGSCC____-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) +; IS__CGSCC____-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 144, i8* nocapture noundef nonnull align 8 dereferenceable(240) [[TMP0]]) +; IS__CGSCC____-NEXT: ret double [[CALL1]] ; entry: %f = alloca %struct._IO_FILE, align 8 diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll b/llvm/test/Transforms/Attributor/nocapture-2.ll --- a/llvm/test/Transforms/Attributor/nocapture-2.ll +++ b/llvm/test/Transforms/Attributor/nocapture-2.ll @@ -472,10 +472,10 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_not_captured_but_returned_calls -; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) [[ATTR4]] { +; IS__CGSCC____-SAME: (i64* nocapture nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) [[ATTR4]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]]) [[ATTR9:#.*]] -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]]) [[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) [[ATTR9:#.*]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) [[ATTR9]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -501,9 +501,9 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a -; IS__CGSCC____-SAME: (i64* nofree nonnull returned writeonly align 8 dereferenceable(8) [[A:%.*]]) [[ATTR4]] { +; IS__CGSCC____-SAME: (i64* nofree nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]]) [[ATTR4]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) [[A]]) [[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) [[ATTR9]] ; IS__CGSCC____-NEXT: ret i64* [[CALL]] ; entry: @@ -532,7 +532,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0b ; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) [[ATTR4]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) [[A]]) [[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) [[ATTR9]] ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64 ; IS__CGSCC____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8 ; IS__CGSCC____-NEXT: ret void @@ -561,9 +561,9 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1a -; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) [[ATTR4]] { +; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A:%.*]]) [[ATTR4]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]]) [[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) [[ATTR9]] ; IS__CGSCC____-NEXT: ret i64* [[CALL]] ; entry: @@ -592,7 +592,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1b ; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) [[ATTR5:#.*]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]]) [[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) [[ATTR9]] ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64 ; IS__CGSCC____-NEXT: store i64 [[TMP0]], i64* [[CALL]], align 8 ; IS__CGSCC____-NEXT: ret void diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll --- a/llvm/test/Transforms/Attributor/nonnull.ll +++ b/llvm/test/Transforms/Attributor/nonnull.ll @@ -405,29 +405,21 @@ ret void } define internal void @test13(i8* %a, i8* %b, i8* %c) { -; IS__TUNIT____: Function Attrs: nounwind -; IS__TUNIT____-LABEL: define {{[^@]+}}@test13 -; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) [[ATTR4:#.*]] { -; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) [[ATTR4]] -; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) [[ATTR4]] -; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) [[ATTR4]] -; IS__TUNIT____-NEXT: ret void +; NOT_CGSCC_OPM: Function Attrs: nounwind +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13 +; NOT_CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) [[ATTR4]] { +; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) [[ATTR4]] +; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) [[ATTR4]] +; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) [[ATTR4]] +; NOT_CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: nounwind ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13 -; IS__CGSCC_OPM-SAME: (i8* nocapture nofree readnone [[A:%.*]], i8* nocapture nofree readnone [[B:%.*]], i8* nocapture nofree readnone [[C:%.*]]) [[ATTR5]] { -; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[A]]) [[ATTR5]] +; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) [[ATTR5]] { +; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) [[ATTR5]] ; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) [[ATTR5]] ; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) [[ATTR5]] ; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: nounwind -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test13 -; IS__CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[A:%.*]], i8* nocapture nofree readnone [[B:%.*]], i8* nocapture nofree readnone [[C:%.*]]) [[ATTR4:#.*]] { -; IS__CGSCC_NPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[A]]) [[ATTR4]] -; IS__CGSCC_NPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) [[ATTR4]] -; IS__CGSCC_NPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret void ; call void @use_i8_ptr(i8* %a) call void @use_i8_ptr(i8* %b) @@ -987,7 +979,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@g2 ; IS__CGSCC____-SAME: () [[ATTR1]] { -; IS__CGSCC____-NEXT: ret i32* inttoptr (i64 4 to i32*) +; IS__CGSCC____-NEXT: ret i32* undef ; ret i32* inttoptr (i64 4 to i32*) } @@ -1009,23 +1001,17 @@ declare void @use_i32_ptr(i32* readnone nocapture) nounwind define internal void @called_by_weak(i32* %a) { -; IS__TUNIT____: Function Attrs: nounwind -; IS__TUNIT____-LABEL: define {{[^@]+}}@called_by_weak -; IS__TUNIT____-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) [[ATTR4]] { -; IS__TUNIT____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) [[ATTR4]] -; IS__TUNIT____-NEXT: ret void +; NOT_CGSCC_OPM: Function Attrs: nounwind +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@called_by_weak +; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) [[ATTR4]] { +; NOT_CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) [[ATTR4]] +; NOT_CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: nounwind ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@called_by_weak -; IS__CGSCC_OPM-SAME: (i32* nocapture nonnull readnone [[A:%.*]]) [[ATTR5]] { +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) [[ATTR5]] { ; IS__CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) [[ATTR5]] ; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: nounwind -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@called_by_weak -; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull readnone [[A:%.*]]) [[ATTR4]] { -; IS__CGSCC_NPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret void ; call void @use_i32_ptr(i32* %a) ret void @@ -1049,23 +1035,17 @@ ; Expect nonnull define internal void @control(i32* dereferenceable(4) %a) { -; IS__TUNIT____: Function Attrs: nounwind -; IS__TUNIT____-LABEL: define {{[^@]+}}@control -; IS__TUNIT____-SAME: (i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) [[ATTR4]] { -; IS__TUNIT____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A]]) [[ATTR4]] -; IS__TUNIT____-NEXT: ret void +; NOT_CGSCC_OPM: Function Attrs: nounwind +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@control +; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) [[ATTR4]] { +; NOT_CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A]]) [[ATTR4]] +; NOT_CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: nounwind ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@control -; IS__CGSCC_OPM-SAME: (i32* nocapture nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) [[ATTR5]] { +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) [[ATTR5]] { ; IS__CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A]]) [[ATTR5]] ; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: nounwind -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@control -; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) [[ATTR4]] { -; IS__CGSCC_NPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A]]) [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret void ; call void @use_i32_ptr(i32* %a) ret void diff --git a/llvm/test/Transforms/Attributor/potential.ll b/llvm/test/Transforms/Attributor/potential.ll --- a/llvm/test/Transforms/Attributor/potential.ll +++ b/llvm/test/Transforms/Attributor/potential.ll @@ -13,9 +13,8 @@ define internal i1 @iszero1(i32 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero1 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____-SAME: () [[ATTR0:#.*]] { +; IS__CGSCC____-NEXT: ret i1 undef ; %cmp = icmp eq i32 %c, 0 ret i1 %cmp @@ -27,19 +26,10 @@ ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) [[ATTR0:#.*]] { ; IS__TUNIT____-NEXT: ret i1 false ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test1 -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC_OPM-NEXT: [[ARG:%.*]] = select i1 [[C]], i32 -1, i32 1 -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i1 @iszero1(i32 noundef [[ARG]]) [[ATTR2:#.*]] -; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test1 -; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC_NPM-NEXT: [[ARG:%.*]] = select i1 [[C]], i32 -1, i32 1 -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i1 @iszero1(i32 noundef [[ARG]]) [[ATTR1:#.*]] -; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test1 +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i1 false ; %arg = select i1 %c, i32 -1, i32 1 %ret = call i1 @iszero1(i32 %arg) @@ -58,10 +48,8 @@ define internal i32 @iszero2(i32 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero2 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 -; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 -; IS__CGSCC____-NEXT: ret i32 [[RET]] +; IS__CGSCC____-SAME: () [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i32 undef ; %cmp = icmp eq i32 %c, 0 %ret = zext i1 %cmp to i32 @@ -69,23 +57,10 @@ } define internal i32 @call_with_two_values(i32 %c) { -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@call_with_two_values -; IS__CGSCC_OPM-SAME: (i32 noundef [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 noundef [[C]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[MINUSC:%.*]] = sub i32 0, [[C]] -; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @iszero2(i32 noundef [[MINUSC]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@call_with_two_values -; IS__CGSCC_NPM-SAME: (i32 noundef [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 noundef [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[MINUSC:%.*]] = sub i32 0, [[C]] -; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @iszero2(i32 noundef [[MINUSC]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@call_with_two_values +; IS__CGSCC____-SAME: () [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i32 undef ; %csret1 = call i32 @iszero2(i32 %c) %minusc = sub i32 0, %c @@ -100,21 +75,10 @@ ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { ; IS__TUNIT____-NEXT: ret i32 0 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test2 -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 noundef 1) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 noundef -1) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test2 -; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 noundef 1) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 noundef -1) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test2 +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i32 0 ; %csret1 = call i32 @call_with_two_values(i32 1) %csret2 = call i32 @call_with_two_values(i32 -1) @@ -163,7 +127,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_two -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { +; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) [[ATTR0]] { ; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 2 ; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 ; IS__CGSCC____-NEXT: ret i32 [[RET]] @@ -196,21 +160,21 @@ ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test3 -; IS__CGSCC_OPM-SAME: () [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) [[ATTR2]] +; IS__CGSCC_OPM-SAME: () [[ATTR0:#.*]] { +; IS__CGSCC_OPM-NEXT: [[CMP1:%.*]] = call noundef i32 @iszero3(i32 noundef 0) [[ATTR2:#.*]] +; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) [[ATTR2]], [[RNG0:!range !.*]] +; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = call noundef i32 @iszero3(i32 noundef 1) [[ATTR2]] +; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) [[ATTR2]], [[RNG0]] ; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test3 -; IS__CGSCC_NPM-SAME: () [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) [[ATTR1]] +; IS__CGSCC_NPM-SAME: () [[ATTR0:#.*]] { +; IS__CGSCC_NPM-NEXT: [[CMP1:%.*]] = call noundef i32 @iszero3(i32 noundef 0) [[ATTR1:#.*]], [[RNG0:!range !.*]] +; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 noundef [[CMP1]]) [[ATTR1]], [[RNG0]] +; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = call noundef i32 @iszero3(i32 noundef 1) [[ATTR1]], [[RNG0]] +; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 noundef [[CMP2]]) [[ATTR1]], [[RNG0]] ; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; @@ -239,21 +203,10 @@ ; IS__TUNIT____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { ; IS__TUNIT____-NEXT: ret i32 0 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test4 -; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET]], 2 -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 -; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test4 -; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET]], 2 -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 -; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test4 +; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i32 0 ; %csret = call i32 @return1or3(i32 %c) %false = icmp eq i32 %csret, 2 @@ -267,23 +220,10 @@ ; IS__TUNIT____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { ; IS__TUNIT____-NEXT: ret i32 0 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test5 -; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 -; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test5 -; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 -; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test5 +; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i32 0 ; %csret1 = call i32 @return1or3(i32 %c) %csret2 = call i32 @return2or4(i32 %c) @@ -310,14 +250,14 @@ ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test6 ; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR2]] +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR2]], [[RNG1:!range !.*]] ; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 ; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test6 ; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR1]] +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR1]], [[RNG1:!range !.*]] ; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 ; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] ; @@ -346,16 +286,16 @@ ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test7 ; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR2]] +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR2]], [[RNG1]] +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR2]], [[RNG2:!range !.*]] ; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] ; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test7 ; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR1]] +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) [[ATTR1]], [[RNG1]] +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) [[ATTR1]], [[RNG2:!range !.*]] ; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] ; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] ; @@ -389,9 +329,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@return2or4 ; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 -; IS__CGSCC____-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 2, i32 4 -; IS__CGSCC____-NEXT: ret i32 [[RET]] +; IS__CGSCC____-NEXT: ret i32 undef ; %cmp = icmp eq i32 %c, 0 %ret = select i1 %cmp, i32 2, i32 4 @@ -425,26 +363,18 @@ define internal i1 @cmp_with_four(i32 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cmp_with_four -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 4 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____-SAME: () [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i1 undef ; %cmp = icmp eq i32 %c, 4 ret i1 %cmp } define internal i1 @wrapper(i32 %c) { -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@wrapper -; IS__CGSCC_OPM-SAME: (i32 noundef [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i1 @cmp_with_four(i32 noundef [[C]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@wrapper -; IS__CGSCC_NPM-SAME: (i32 noundef [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i1 @cmp_with_four(i32 noundef [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@wrapper +; IS__CGSCC____-SAME: () [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i1 undef ; %ret = call i1 @cmp_with_four(i32 %c) ret i1 %ret @@ -456,25 +386,10 @@ ; IS__TUNIT____-SAME: () [[ATTR0]] { ; IS__TUNIT____-NEXT: ret i1 false ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test8 -; IS__CGSCC_OPM-SAME: () [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[RES1:%.*]] = call i1 @wrapper(i32 noundef 1) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[RES3:%.*]] = call i1 @wrapper(i32 noundef 3) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[RES5:%.*]] = call i1 @wrapper(i32 noundef 5) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[RES13:%.*]] = or i1 [[RES1]], [[RES3]] -; IS__CGSCC_OPM-NEXT: [[RES135:%.*]] = or i1 [[RES13]], [[RES5]] -; IS__CGSCC_OPM-NEXT: ret i1 [[RES135]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test8 -; IS__CGSCC_NPM-SAME: () [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[RES1:%.*]] = call i1 @wrapper(i32 noundef 1) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[RES3:%.*]] = call i1 @wrapper(i32 noundef 3) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[RES5:%.*]] = call i1 @wrapper(i32 noundef 5) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[RES13:%.*]] = or i1 [[RES1]], [[RES3]] -; IS__CGSCC_NPM-NEXT: [[RES135:%.*]] = or i1 [[RES13]], [[RES5]] -; IS__CGSCC_NPM-NEXT: ret i1 [[RES135]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test8 +; IS__CGSCC____-SAME: () [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i1 false ; %res1 = call i1 @wrapper(i32 1) %res3 = call i1 @wrapper(i32 3) @@ -584,20 +499,6 @@ ; and returned value of @potential_test10 can be simplified to 0(false) define internal i32 @may_return_undef(i32 %c) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@may_return_undef -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ -; IS__CGSCC____-NEXT: i32 1, label [[A:%.*]] -; IS__CGSCC____-NEXT: i32 -1, label [[B:%.*]] -; IS__CGSCC____-NEXT: ] -; IS__CGSCC____: a: -; IS__CGSCC____-NEXT: ret i32 1 -; IS__CGSCC____: b: -; IS__CGSCC____-NEXT: ret i32 -1 -; IS__CGSCC____: otherwise: -; IS__CGSCC____-NEXT: ret i32 undef -; switch i32 %c, label %otherwise [i32 1, label %a i32 -1, label %b] a: @@ -614,19 +515,10 @@ ; IS__TUNIT____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { ; IS__TUNIT____-NEXT: ret i1 false ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test10 -; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0 -; IS__CGSCC_OPM-NEXT: ret i1 [[CMP]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test10 -; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0 -; IS__CGSCC_NPM-NEXT: ret i1 [[CMP]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test10 +; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR0]] { +; IS__CGSCC____-NEXT: ret i1 false ; %ret = call i32 @may_return_undef(i32 %c) %cmp = icmp eq i32 %ret, 0 @@ -739,9 +631,9 @@ ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test11 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR2]] -; IS__CGSCC_OPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) [[ATTR2]] +; IS__CGSCC_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR2]], [[RNG0]] +; IS__CGSCC_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR2]], [[RNG3:!range !.*]] +; IS__CGSCC_OPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) [[ATTR2]], [[RNG0]] ; IS__CGSCC_OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] ; IS__CGSCC_OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] ; IS__CGSCC_OPM-NEXT: ret i32 [[ACC2]] @@ -749,9 +641,9 @@ ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test11 ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) [[ATTR1]] +; IS__CGSCC_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) [[ATTR1]], [[RNG0]] +; IS__CGSCC_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) [[ATTR1]], [[RNG3:!range !.*]] +; IS__CGSCC_NPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) [[ATTR1]], [[RNG0]] ; IS__CGSCC_NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] ; IS__CGSCC_NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] ; IS__CGSCC_NPM-NEXT: ret i32 [[ACC2]] @@ -825,14 +717,13 @@ ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test12 ; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) [[ATTR2]] +; IS__CGSCC_OPM-NEXT: [[ZERO:%.*]] = call i32 @optimize_poison_1(i1 [[C]]) [[ATTR2]], [[RNG3]] ; IS__CGSCC_OPM-NEXT: ret i32 [[ZERO]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test12 ; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) [[ATTR1]] -; IS__CGSCC_NPM-NEXT: ret i32 [[ZERO]] +; IS__CGSCC_NPM-NEXT: ret i32 0 ; %zero = call i32 @optimize_poison_1(i1 %c) ret i32 %zero @@ -876,13 +767,13 @@ ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 ; IS__CGSCC_OPM-SAME: () [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR2]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR2]], [[RNG0]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 ; IS__CGSCC_NPM-SAME: () [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR1]] +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) [[ATTR1]], [[RNG0]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = call i32 @potential_test13_callee(i32 0) @@ -905,13 +796,13 @@ ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 ; IS__CGSCC_OPM-SAME: () [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR2]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR2]], [[RNG0]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 ; IS__CGSCC_NPM-SAME: () [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR1]] +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) [[ATTR1]], [[RNG0]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = call i32 @potential_test13_callee(i32 1) @@ -934,13 +825,13 @@ ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3 ; IS__CGSCC_OPM-SAME: () [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR2]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR2]], [[RNG0]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3 ; IS__CGSCC_NPM-SAME: () [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR1]] +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) [[ATTR1]], [[RNG0]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = call i32 @potential_test13_callee(i32 undef) @@ -1021,5 +912,3 @@ ; IS__TUNIT_OPM: !2 = !{i32 0, i32 2} ; IS__TUNIT_OPM: !3 = !{i32 -1, i32 1} ; IS__TUNIT_OPM-NOT: !4 - -; IS__CGSCC____-NOT: !0 diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll --- a/llvm/test/Transforms/Attributor/range.ll +++ b/llvm/test/Transforms/Attributor/range.ll @@ -39,13 +39,13 @@ ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test0-range-check ; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC_OPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR3:#.*]] +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR3:#.*]], [[RNG0:!range !.*]] ; IS__CGSCC_OPM-NEXT: ret i32 [[A]] ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test0-range-check ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) [[ATTR0:#.*]] { -; IS__CGSCC_NPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR2:#.*]] +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR2:#.*]], [[RNG0:!range !.*]] ; IS__CGSCC_NPM-NEXT: ret i32 [[A]] ; %a = tail call i32 @test0(i32* %p) @@ -162,136 +162,96 @@ ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test0-icmp-check ; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) { -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR3]] -; IS__CGSCC_OPM-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10 +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR3]], [[RNG0]] ; IS__CGSCC_OPM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9 ; IS__CGSCC_OPM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8 ; IS__CGSCC_OPM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1 ; IS__CGSCC_OPM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0 -; IS__CGSCC_OPM-NEXT: [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1 -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]]) -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]]) -; IS__CGSCC_OPM-NEXT: [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10 +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 noundef false) ; IS__CGSCC_OPM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9 ; IS__CGSCC_OPM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8 ; IS__CGSCC_OPM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1 ; IS__CGSCC_OPM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0 -; IS__CGSCC_OPM-NEXT: [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1 -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]]) -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]]) -; IS__CGSCC_OPM-NEXT: [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10 -; IS__CGSCC_OPM-NEXT: [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9 +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 noundef true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 noundef true) ; IS__CGSCC_OPM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8 ; IS__CGSCC_OPM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1 ; IS__CGSCC_OPM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0 -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 noundef false, i1 noundef false, i1 [[CMP_UGT_3]]) ; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false) -; IS__CGSCC_OPM-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10 ; IS__CGSCC_OPM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9 ; IS__CGSCC_OPM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8 ; IS__CGSCC_OPM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1 -; IS__CGSCC_OPM-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1 -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]]) -; IS__CGSCC_OPM-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10 -; IS__CGSCC_OPM-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9 +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 noundef false) ; IS__CGSCC_OPM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8 ; IS__CGSCC_OPM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1 ; IS__CGSCC_OPM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0 -; IS__CGSCC_OPM-NEXT: [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1 -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]]) -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]]) -; IS__CGSCC_OPM-NEXT: [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10 +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 noundef false, i1 noundef false, i1 [[CMP_SGT_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 noundef true) ; IS__CGSCC_OPM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9 ; IS__CGSCC_OPM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8 ; IS__CGSCC_OPM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1 -; IS__CGSCC_OPM-NEXT: [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0 -; IS__CGSCC_OPM-NEXT: [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1 -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]]) -; IS__CGSCC_OPM-NEXT: [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10 +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 noundef true, i1 noundef true) ; IS__CGSCC_OPM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9 ; IS__CGSCC_OPM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8 ; IS__CGSCC_OPM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1 -; IS__CGSCC_OPM-NEXT: [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0 -; IS__CGSCC_OPM-NEXT: [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1 -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]]) -; IS__CGSCC_OPM-NEXT: [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10 -; IS__CGSCC_OPM-NEXT: [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9 +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 noundef true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 noundef false, i1 noundef false) ; IS__CGSCC_OPM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8 ; IS__CGSCC_OPM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1 ; IS__CGSCC_OPM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0 -; IS__CGSCC_OPM-NEXT: [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1 -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]]) -; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 noundef true, i1 noundef true, i1 [[CMP_LTE_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 noundef false) ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test0-icmp-check ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) { -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR2]] -; IS__CGSCC_NPM-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10 +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR2]], [[RNG0]] ; IS__CGSCC_NPM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9 ; IS__CGSCC_NPM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8 ; IS__CGSCC_NPM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1 ; IS__CGSCC_NPM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0 -; IS__CGSCC_NPM-NEXT: [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1 -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]]) -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]]) -; IS__CGSCC_NPM-NEXT: [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10 +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 noundef false) ; IS__CGSCC_NPM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9 ; IS__CGSCC_NPM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8 ; IS__CGSCC_NPM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1 ; IS__CGSCC_NPM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0 -; IS__CGSCC_NPM-NEXT: [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1 -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]]) -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]]) -; IS__CGSCC_NPM-NEXT: [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10 -; IS__CGSCC_NPM-NEXT: [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9 +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 noundef true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 noundef true) ; IS__CGSCC_NPM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8 ; IS__CGSCC_NPM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1 ; IS__CGSCC_NPM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0 -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 noundef false, i1 noundef false, i1 [[CMP_UGT_3]]) ; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 noundef false) -; IS__CGSCC_NPM-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10 ; IS__CGSCC_NPM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9 ; IS__CGSCC_NPM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8 ; IS__CGSCC_NPM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1 -; IS__CGSCC_NPM-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1 -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 [[CMP_UGE_6]]) -; IS__CGSCC_NPM-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10 -; IS__CGSCC_NPM-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9 +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 noundef false) ; IS__CGSCC_NPM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8 ; IS__CGSCC_NPM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1 ; IS__CGSCC_NPM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0 -; IS__CGSCC_NPM-NEXT: [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1 -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]]) -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]]) -; IS__CGSCC_NPM-NEXT: [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10 +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 noundef false, i1 noundef false, i1 [[CMP_SGT_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 noundef true) ; IS__CGSCC_NPM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9 ; IS__CGSCC_NPM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8 ; IS__CGSCC_NPM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1 -; IS__CGSCC_NPM-NEXT: [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0 -; IS__CGSCC_NPM-NEXT: [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1 -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]]) -; IS__CGSCC_NPM-NEXT: [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10 +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 noundef false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 noundef true, i1 noundef true) ; IS__CGSCC_NPM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9 ; IS__CGSCC_NPM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8 ; IS__CGSCC_NPM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1 -; IS__CGSCC_NPM-NEXT: [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0 -; IS__CGSCC_NPM-NEXT: [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1 -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]]) -; IS__CGSCC_NPM-NEXT: [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10 -; IS__CGSCC_NPM-NEXT: [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9 +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 noundef true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 noundef false, i1 noundef false) ; IS__CGSCC_NPM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8 ; IS__CGSCC_NPM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1 ; IS__CGSCC_NPM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0 -; IS__CGSCC_NPM-NEXT: [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1 -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]]) -; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 noundef true, i1 noundef true, i1 [[CMP_LTE_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 noundef false) ; IS__CGSCC_NPM-NEXT: ret void ; %ret = tail call i32 @test0(i32 *%p) @@ -420,14 +380,14 @@ ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test1-check ; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR3]], [[RNG2:!range !.*]] ; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 ; IS__CGSCC_OPM-NEXT: ret i1 [[CMP]] ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test1-check ; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR2]], [[RNG2:!range !.*]] ; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 ; IS__CGSCC_NPM-NEXT: ret i1 [[CMP]] ; @@ -487,35 +447,17 @@ ; IS__TUNIT____: return: ; IS__TUNIT____-NEXT: ret i32 2 ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2_check -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) [[ATTR0]] { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test2(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR3]] -; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5 -; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; IS__CGSCC_OPM: if.then: -; IS__CGSCC_OPM-NEXT: br label [[RETURN:%.*]] -; IS__CGSCC_OPM: if.end: -; IS__CGSCC_OPM-NEXT: br label [[RETURN]] -; IS__CGSCC_OPM: return: -; IS__CGSCC_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ] -; IS__CGSCC_OPM-NEXT: ret i32 [[RETVAL_0]] -; -; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2_check -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) [[ATTR0]] { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test2(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) [[ATTR2]] -; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5 -; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; IS__CGSCC_NPM: if.then: -; IS__CGSCC_NPM-NEXT: br label [[RETURN:%.*]] -; IS__CGSCC_NPM: if.end: -; IS__CGSCC_NPM-NEXT: br label [[RETURN]] -; IS__CGSCC_NPM: return: -; IS__CGSCC_NPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ] -; IS__CGSCC_NPM-NEXT: ret i32 [[RETVAL_0]] +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_check +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) [[ATTR0]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: br label [[IF_THEN:%.*]] +; IS__CGSCC____: if.then: +; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: return: +; IS__CGSCC____-NEXT: ret i32 2 ; entry: %call = tail call i32 @test2(i32* %p) @@ -608,7 +550,7 @@ ; IS__CGSCC_NPM: 2: ; IS__CGSCC_NPM-NEXT: unreachable ; IS__CGSCC_NPM: f: -; IS__CGSCC_NPM-NEXT: ret i32 10 +; IS__CGSCC_NPM-NEXT: ret i32 undef ; IS__CGSCC_NPM: 3: ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP7:%.*]], [[TMP3]] ] ; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP6:%.*]], [[TMP3]] ] @@ -658,7 +600,7 @@ ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1 ; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) { -; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1() +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1(), [[RNG3:!range !.*]] ; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15 ; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] ; IS__CGSCC_OPM: 4: @@ -855,7 +797,7 @@ ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4-g2 ; IS__CGSCC_NPM-SAME: (i32 [[U:%.*]]) [[ATTR1]] { ; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) [[ATTR3]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) [[ATTR3]], [[RNG3:!range !.*]] ; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; entry: @@ -869,15 +811,10 @@ ; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 noundef 0), [[RNG3:!range !.*]] ; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]] ; -; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test-5() { -; IS__TUNIT_NPM-NEXT: entry: -; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 noundef 0), [[RNG4:!range !.*]] -; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]] -; -; IS__CGSCC____-LABEL: define {{[^@]+}}@test-5() { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0) -; IS__CGSCC____-NEXT: ret i32 [[CALL]] +; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test-5() { +; NOT_TUNIT_OPM-NEXT: entry: +; NOT_TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 noundef 0), [[RNG4:!range !.*]] +; NOT_TUNIT_OPM-NEXT: ret i32 [[CALL]] ; entry: %call = call i32 @rec(i32 0) @@ -1316,21 +1253,10 @@ ; IS__TUNIT____-SAME: () [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 0 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@undef_collapse_caller -; IS__CGSCC_OPM-SAME: () [[ATTR2]] { -; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]] -; IS__CGSCC_OPM-NEXT: ret i8 [[A]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@undef_collapse_caller -; IS__CGSCC_NPM-SAME: () [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]] -; IS__CGSCC_NPM-NEXT: ret i8 [[A]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_collapse_caller +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i8 0 ; %c1 = call i8 @undef_collapse_1() %c2 = call i8 @undef_collapse_2() @@ -1361,29 +1287,10 @@ ; IS__TUNIT____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i1 true ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee_range_1 -; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) [[ATTR2]] { -; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]] -; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]] -; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4 -; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 -; IS__CGSCC_OPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] -; IS__CGSCC_OPM-NEXT: ret i1 [[F]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callee_range_1 -; IS__CGSCC_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]] -; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]] -; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4 -; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 -; IS__CGSCC_NPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] -; IS__CGSCC_NPM-NEXT: ret i1 [[F]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_range_1 +; IS__CGSCC____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i1 true ; %r1 = call i32 @ret1or2(i1 %c1) %r2 = call i32 @ret1or2(i1 %c2) @@ -1422,8 +1329,8 @@ ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee_range_2 ; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) [[ATTR2]] { -; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR4]] +; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR4]], [[RNG5:!range !.*]] +; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR4]], [[RNG5]] ; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 @@ -1433,8 +1340,8 @@ ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callee_range_2 ; IS__CGSCC_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR3]] +; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR3]], [[RNG5:!range !.*]] +; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR3]], [[RNG5]] ; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] ; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 ; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 @@ -1569,7 +1476,7 @@ ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false ; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT_NPM: t: -; IS__TUNIT_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef true) [[ATTR1]], [[RNG4]] +; IS__TUNIT_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef true) [[ATTR1]], [[RNG4:!range !.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[RET1]] ; IS__TUNIT_NPM: f: ; IS__TUNIT_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) [[ATTR1]], [[RNG4]] @@ -1581,10 +1488,10 @@ ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_OPM: t: -; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) [[ATTR4]] +; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) [[ATTR4]], [[RNG4:!range !.*]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET1]] ; IS__CGSCC_OPM: f: -; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) [[ATTR4]] +; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) [[ATTR4]], [[RNG4]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn @@ -1593,10 +1500,10 @@ ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_NPM: t: -; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef true) [[ATTR3]] +; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef true) [[ATTR3]], [[RNG4:!range !.*]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RET1]] ; IS__CGSCC_NPM: f: -; IS__CGSCC_NPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) [[ATTR3]] +; IS__CGSCC_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) [[ATTR3]], [[RNG4]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RET2]] ; %c = select i1 %d, i1 true, i1 false @@ -1678,8 +1585,8 @@ ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@check_divided_range ; IS__CGSCC_NPM-SAME: (i32 [[ARG:%.*]]) [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) [[ATTR3]] +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) [[ATTR3]], [[RNG6:!range !.*]] +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) [[ATTR3]], [[RNG6]] ; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) [[ATTR3]] ; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) [[ATTR3]] ; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]] @@ -1703,8 +1610,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cast_and_return ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR1]] { -; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[C]] to i32 -; IS__CGSCC____-NEXT: ret i32 [[RET]] +; IS__CGSCC____-NEXT: ret i32 undef ; %ret = zext i1 %c to i32 ret i32 %ret @@ -1719,9 +1625,8 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_3 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR1]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 3 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i1 undef ; %cmp = icmp slt i32 %c, 3 ret i1 %cmp @@ -1743,23 +1648,10 @@ ; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) [[ATTR1]] { ; IS__TUNIT_NPM-NEXT: ret i1 true ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@check_casted_range -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) [[ATTR2]] { -; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@check_casted_range -; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@check_casted_range +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i1 true ; %csret1 = call i32 @cast_and_return(i1 true) %csret2 = call i32 @cast_and_return(i1 %c) @@ -1782,21 +1674,21 @@ ; IS__CGSCC____-NEXT: i32 6, label [[ONSIX:%.*]] ; IS__CGSCC____-NEXT: ] ; IS__CGSCC____: onzero: -; IS__CGSCC____-NEXT: ret i32 0 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: onone: -; IS__CGSCC____-NEXT: ret i32 1 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: ontwo: -; IS__CGSCC____-NEXT: ret i32 2 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: onthree: -; IS__CGSCC____-NEXT: ret i32 3 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: onfour: -; IS__CGSCC____-NEXT: ret i32 4 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: onfive: -; IS__CGSCC____-NEXT: ret i32 5 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: onsix: -; IS__CGSCC____-NEXT: ret i32 6 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: otherwise: -; IS__CGSCC____-NEXT: ret i32 99 +; IS__CGSCC____-NEXT: ret i32 undef ; switch i32 %c, label %otherwise [ i32 0, label %onzero i32 1, label %onone @@ -1826,9 +1718,8 @@ define internal i1 @is_less_than_100_1(i32 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_1 -; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) [[ATTR1]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i1 undef ; %cmp = icmp slt i32 %c, 100 ret i1 %cmp @@ -1840,19 +1731,10 @@ ; IS__TUNIT____-SAME: (i32 [[C:%.*]]) [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i1 true ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@propagate_range1 -; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) [[ATTR2]] { -; IS__CGSCC_OPM-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 [[C]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: ret i1 [[TRUE]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@propagate_range1 -; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 [[C]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: ret i1 [[TRUE]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@propagate_range1 +; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i1 true ; %csret = call i32 @less_than_100_1(i32 %c) %true = call i1 @is_less_than_100_1(i32 %csret) @@ -1953,8 +1835,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_2 ; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) [[ATTR1]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____-NEXT: ret i1 true ; %cmp = icmp slt i32 %c, 100 ret i1 %cmp @@ -1982,25 +1863,10 @@ ; IS__TUNIT_NPM-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]] ; IS__TUNIT_NPM-NEXT: ret i1 [[TRUE]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@propagate_range2 -; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) [[ATTR2]] { -; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) [[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]] -; IS__CGSCC_OPM-NEXT: ret i1 [[TRUE]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@propagate_range2 -; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) [[ATTR3]] -; IS__CGSCC_NPM-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]] -; IS__CGSCC_NPM-NEXT: ret i1 [[TRUE]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@propagate_range2 +; IS__CGSCC____-SAME: (i32 [[C:%.*]]) [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i1 true ; %csret1 = call i32 @less_than_100_2(i32 0) %true1 = call i1 @is_less_than_100_2(i32 %csret1) diff --git a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll --- a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll +++ b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll @@ -47,12 +47,12 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@external_ret2_nrw -; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree align 4 [[R0:%.*]], i32* nofree returned [[W0:%.*]]) [[ATTR0:#.*]] { +; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[W0:%.*]]) [[ATTR0:#.*]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree [[W0]]) [[ATTR2:#.*]] -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree align 4 [[R0]], i32* nofree align 4 [[R0]], i32* nofree [[W0]]) [[ATTR2]] -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly align 4 [[R0]], i32* nofree writeonly [[W0]]) [[ATTR3:#.*]] -; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]]) [[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) [[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) [[ATTR3:#.*]] +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: ret i32* [[CALL3]] ; entry: @@ -106,8 +106,8 @@ ; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] -; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) [[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) [[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[W0]]) [[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[W0]]) [[ATTR3]] ; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: return: @@ -171,7 +171,7 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret1_rrw -; IS__CGSCC____-SAME: (i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[R1:%.*]], i32* nofree [[W0:%.*]]) [[ATTR0]] { +; IS__CGSCC____-SAME: (i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree nonnull returned align 4 dereferenceable(4) [[R1:%.*]], i32* nofree [[W0:%.*]]) [[ATTR0]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4 ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 @@ -179,7 +179,7 @@ ; IS__CGSCC____: if.then: ; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] ; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) [[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[R0]], align 4 ; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* [[R1]], align 4 ; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[TMP2]] @@ -189,8 +189,8 @@ ; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[W0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @external_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] -; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) [[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) [[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[W0]]) [[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[W0]]) [[ATTR3]] ; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: return: @@ -306,12 +306,12 @@ ; IS__CGSCC____: if.then: ; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] ; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) [[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[R0]], align 4 ; IS__CGSCC____-NEXT: store i32 [[TMP1]], i32* [[W0]], align 4 ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[W0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] -; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) [[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[W0]]) [[ATTR3]] ; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) [[ATTR2]] ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: return: @@ -354,7 +354,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@external_source_ret2_nrw ; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree align 4 [[R0:%.*]], i32* nofree returned [[W0:%.*]]) [[ATTR0]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly align 4 [[R0]], i32* nofree writeonly [[W0]]) [[ATTR4:#.*]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly align 4 [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) [[ATTR4:#.*]] ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree align 4 [[R0]], i32* nofree [[W0]]) [[ATTR3]] ; IS__CGSCC____-NEXT: ret i32* [[CALL1]] ; diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -145,9 +145,9 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_2 -; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]]) [[ATTR3]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) [[ATTR3]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 4 i32* @test8_1(i32* noalias nofree readnone [[P]]) [[ATTR11:#.*]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 4 i32* @test8_1(i32* noalias nofree readnone "no-capture-maybe-returned" [[P]]) [[ATTR11:#.*]] ; IS__CGSCC____-NEXT: store i32 10, i32* [[CALL]], align 4 ; IS__CGSCC____-NEXT: ret void ; diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll --- a/llvm/test/Transforms/Attributor/returned.ll +++ b/llvm/test/Transforms/Attributor/returned.ll @@ -249,13 +249,12 @@ ; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] ; IS__CGSCC____: if.then3: ; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) -; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) ; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) -; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 [[R]]) -; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) +; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) +; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) ; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) -; IS__CGSCC____-NEXT: [[CALL10:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) -; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 [[CALL10]]) +; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: if.end12: ; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] @@ -367,7 +366,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r1 ; IS__CGSCC____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) [[ATTR1]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone [[R]]) [[ATTR6]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) [[ATTR6]] ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) [[ATTR7]] ; IS__CGSCC____-NEXT: ret double* [[CALL1]] ; @@ -422,14 +421,14 @@ ; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]] ; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone [[R]]) [[ATTR6]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) [[ATTR6]] ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[B]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) [[ATTR7]] ; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] ; IS__CGSCC____: if.end: ; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]] ; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] ; IS__CGSCC____: if.then3: -; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone [[B]]) +; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[B]]) ; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nocapture nofree readnone undef) [[ATTR7]] ; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]]) [[ATTR7]] ; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL6]], double* noalias nocapture nofree readnone undef) [[ATTR7]] @@ -1475,35 +1474,20 @@ ; We can use the return information of the weak function non_exact_4. ; FIXME: %c2 and %c3 should be replaced but not %c0 or %c1! define i32 @exact(i32* align 8 %a, i32* align 8 %b) { -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@exact -; NOT_CGSCC_NPM-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) { -; NOT_CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @non_exact_0() -; NOT_CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1) -; NOT_CGSCC_NPM-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2) -; NOT_CGSCC_NPM-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) -; NOT_CGSCC_NPM-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) -; NOT_CGSCC_NPM-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32 -; NOT_CGSCC_NPM-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 -; NOT_CGSCC_NPM-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] -; NOT_CGSCC_NPM-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[C2]] -; NOT_CGSCC_NPM-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] -; NOT_CGSCC_NPM-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] -; NOT_CGSCC_NPM-NEXT: ret i32 [[ADD4]] -; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@exact -; IS__CGSCC_NPM-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) { -; IS__CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @non_exact_0() -; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1) -; IS__CGSCC_NPM-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2) -; IS__CGSCC_NPM-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) -; IS__CGSCC_NPM-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) -; IS__CGSCC_NPM-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32 -; IS__CGSCC_NPM-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 -; IS__CGSCC_NPM-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] -; IS__CGSCC_NPM-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2 -; IS__CGSCC_NPM-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] -; IS__CGSCC_NPM-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] -; IS__CGSCC_NPM-NEXT: ret i32 [[ADD4]] +; CHECK-LABEL: define {{[^@]+}}@exact +; CHECK-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) { +; CHECK-NEXT: [[C0:%.*]] = call i32 @non_exact_0() +; CHECK-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1) +; CHECK-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2) +; CHECK-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) +; CHECK-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) +; CHECK-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32 +; CHECK-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 +; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] +; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[C2]] +; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] +; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] +; CHECK-NEXT: ret i32 [[ADD4]] ; %c0 = call i32 @non_exact_0() %c1 = call i32 @non_exact_1(i32 1) @@ -1560,7 +1544,7 @@ ; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_use_const ; IS__CGSCC____-SAME: () [[ATTR0]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = musttail call noundef nonnull dereferenceable(1) i32* @ret_const() [[ATTR6]] +; IS__CGSCC____-NEXT: [[C:%.*]] = musttail call i32* @ret_const() [[ATTR6]] ; IS__CGSCC____-NEXT: ret i32* [[C]] ; %c = musttail call i32* @ret_const() diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll --- a/llvm/test/Transforms/Attributor/undefined_behavior.ll +++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -92,7 +92,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_null ; IS__CGSCC____-SAME: () [[ATTR0]] { -; IS__CGSCC____-NEXT: ret i32* null +; IS__CGSCC____-NEXT: ret i32* undef ; ret i32* null } @@ -596,7 +596,7 @@ ; IS__CGSCC____: T: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: F: -; IS__CGSCC____-NEXT: ret i32 1 +; IS__CGSCC____-NEXT: ret i32 undef ; entry: %A.0 = load i32, i32* null 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 @@ -233,7 +233,7 @@ ; IS__CGSCC____-SAME: () [[ATTR1]] { ; IS__CGSCC____-NEXT: br label [[T:%.*]] ; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: ret i1 true +; IS__CGSCC____-NEXT: ret i1 undef ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable ; @@ -251,17 +251,10 @@ ; IS__TUNIT____-SAME: () [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i1 true ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp2 -; IS__CGSCC_OPM-SAME: () [[ATTR1:#.*]] { -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2i() [[ATTR5:#.*]] -; IS__CGSCC_OPM-NEXT: ret i1 [[R]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp2 -; IS__CGSCC_NPM-SAME: () [[ATTR1:#.*]] { -; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2i() [[ATTR4:#.*]] -; IS__CGSCC_NPM-NEXT: ret i1 [[R]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2 +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i1 true ; %r = call i1 @ipccp2i(i1 true) ret i1 %r @@ -273,7 +266,7 @@ ; IS__CGSCC____-SAME: () [[ATTR1]] { ; IS__CGSCC____-NEXT: br label [[T:%.*]] ; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: ret i1 true +; IS__CGSCC____-NEXT: ret i1 undef ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable ; @@ -306,7 +299,7 @@ ; IS__CGSCC____-SAME: () [[ATTR1]] { ; IS__CGSCC____-NEXT: br label [[T:%.*]] ; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: ret i32 7 +; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable ; @@ -325,17 +318,10 @@ ; IS__TUNIT____-SAME: () [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i32 7 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp3 -; IS__CGSCC_OPM-SAME: () [[ATTR1]] { -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp3i() [[ATTR5]] -; IS__CGSCC_OPM-NEXT: ret i32 [[R]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp3 -; IS__CGSCC_NPM-SAME: () [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp3i() [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret i32 [[R]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp3 +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i32 7 ; %r = call i32 @ipccp3i(i32 7) ret i32 %r @@ -365,14 +351,14 @@ ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_inalloca -; IS__CGSCC_OPM-SAME: () [[ATTR1]] { -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nocapture nofree noundef writeonly align 536870912 null) [[ATTR5]] +; IS__CGSCC_OPM-SAME: () [[ATTR1:#.*]] { +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nocapture nofree noundef writeonly align 536870912 null) [[ATTR5:#.*]] ; IS__CGSCC_OPM-NEXT: ret i32* [[CALL]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_inalloca -; IS__CGSCC_NPM-SAME: () [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nocapture nofree noundef writeonly align 536870912 null) [[ATTR4]] +; IS__CGSCC_NPM-SAME: () [[ATTR1:#.*]] { +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nocapture nofree noundef writeonly align 536870912 null) [[ATTR4:#.*]] ; IS__CGSCC_NPM-NEXT: ret i32* [[CALL]] ; %call = call i32* @test_inalloca(i32* null) @@ -514,7 +500,7 @@ ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_byval -; IS__CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[TMP0:%.*]]) [[ATTR1]] { +; 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 @@ -714,17 +700,10 @@ ; IS__TUNIT____-SAME: () [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller0 -; IS__CGSCC_OPM-SAME: () [[ATTR1]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR5]] -; IS__CGSCC_OPM-NEXT: ret i8 [[C]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller0 -; IS__CGSCC_NPM-SAME: () [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret i8 [[C]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller0 +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -735,17 +714,10 @@ ; IS__TUNIT____-SAME: () [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller1 -; IS__CGSCC_OPM-SAME: () [[ATTR1]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR5]] -; IS__CGSCC_OPM-NEXT: ret i8 [[C]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller1 -; IS__CGSCC_NPM-SAME: () [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret i8 [[C]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller1 +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -756,17 +728,10 @@ ; IS__TUNIT____-SAME: () [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller2 -; IS__CGSCC_OPM-SAME: () [[ATTR1]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR5]] -; IS__CGSCC_OPM-NEXT: ret i8 [[C]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller2 -; IS__CGSCC_NPM-SAME: () [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret i8 [[C]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2 +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -777,17 +742,10 @@ ; IS__TUNIT____-SAME: () [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller_middle -; IS__CGSCC_OPM-SAME: () [[ATTR1]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR5]] -; IS__CGSCC_OPM-NEXT: ret i8 [[C]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller_middle -; IS__CGSCC_NPM-SAME: () [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret i8 [[C]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller_middle +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 42) ret i8 %c @@ -798,17 +756,10 @@ ; IS__TUNIT____-SAME: () [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller3 -; IS__CGSCC_OPM-SAME: () [[ATTR1]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR5]] -; IS__CGSCC_OPM-NEXT: ret i8 [[C]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller3 -; IS__CGSCC_NPM-SAME: () [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret i8 [[C]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller3 +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -819,17 +770,10 @@ ; IS__TUNIT____-SAME: () [[ATTR1]] { ; IS__TUNIT____-NEXT: ret i8 49 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller4 -; IS__CGSCC_OPM-SAME: () [[ATTR1]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR5]] -; IS__CGSCC_OPM-NEXT: ret i8 [[C]] -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller4 -; IS__CGSCC_NPM-SAME: () [[ATTR1]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() [[ATTR4]] -; IS__CGSCC_NPM-NEXT: ret i8 [[C]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller4 +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -838,7 +782,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@callee ; IS__CGSCC____-SAME: () [[ATTR1]] { -; IS__CGSCC____-NEXT: ret i8 49 +; IS__CGSCC____-NEXT: ret i8 undef ; %c = add i8 %a, 7 ret i8 %c