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; @@ -1016,8 +1081,10 @@ // not call update because that would again spawn new abstract attributes in // potentially unconnected code regions (=SCCs). if (FnScope && !Functions.count(const_cast(FnScope))) { - AA.getState().indicatePessimisticFixpoint(); - return AA; + if (!getInfoCache().ModuleSlice.count(const_cast(FnScope))) { + AA.getState().indicatePessimisticFixpoint(); + return AA; + } } // Allow seeded attributes to declare dependencies. 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 @@ -1280,6 +1280,7 @@ continue; ToBeDeletedFunctions.insert(F); + InternalFns[u] = nullptr; FoundDeadFn = true; } @@ -1291,8 +1292,11 @@ for (Function *Fn : CGModifiedFunctions) CGUpdater.reanalyzeFunction(*Fn); - for (Function *Fn : ToBeDeletedFunctions) + for (Function *Fn : ToBeDeletedFunctions) { + if (!Functions.count(Fn)) + continue; CGUpdater.removeFunction(*Fn); + } NumFnDeleted += ToBeDeletedFunctions.size(); @@ -1583,7 +1587,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 @@ -3036,8 +3036,12 @@ void initialize(Attributor &A) override { const Function *F = getAnchorScope(); if (F && !F->isDeclaration()) { - ToBeExploredFrom.insert(&F->getEntryBlock().front()); - assumeLive(A, F->getEntryBlock()); + 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 @@ -1695,9 +1695,9 @@ OMPInformationCache InfoCache(*(Functions.back()->getParent()), AG, Allocator, /*CGSCC*/ Functions, OMPInModule.getKernels()); - SetVector ModuleSlice(InfoCache.ModuleSlice.begin(), - InfoCache.ModuleSlice.end()); - Attributor A(ModuleSlice, InfoCache, CGUpdater); + // SetVector ModuleSlice(InfoCache.ModuleSlice.begin(), + // InfoCache.ModuleSlice.end()); + Attributor A(Functions, InfoCache, CGUpdater); // TODO: Compute the module slice we are allowed to look at. OpenMPOpt OMPOpt(SCC, CGUpdater, OREGetter, InfoCache, A); @@ -1774,9 +1774,9 @@ *(Functions.back()->getParent()), AG, Allocator, /*CGSCC*/ Functions, OMPInModule.getKernels()); - SetVector ModuleSlice(InfoCache.ModuleSlice.begin(), - InfoCache.ModuleSlice.end()); - Attributor A(ModuleSlice, InfoCache, CGUpdater); + // SetVector ModuleSlice(InfoCache.ModuleSlice.begin(), + // InfoCache.ModuleSlice.end()); + Attributor A(Functions, InfoCache, CGUpdater); // TODO: Compute the module slice we are allowed to look at. OpenMPOpt OMPOpt(SCC, CGUpdater, OREGetter, InfoCache, A); 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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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]]) ; 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:%.*]]) -; 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]]) -; 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:%.*]]) +; 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]]) +; 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:%.*]]) +; 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]]) +; 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:%.*]]) ; 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 @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM @@ -9,19 +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-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:%.*]]) -; 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:%.*]]) +; 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-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:%.*]]) -; 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:%.*]]) +; 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 @@ -30,6 +32,7 @@ } define void @no_promote(<4 x i64>* %arg) #1 { +; IS__TUNIT_OPM: Function Attrs: argmemonly nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@no_promote ; IS__TUNIT_OPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -42,6 +45,7 @@ ; IS__TUNIT_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote ; IS__TUNIT_NPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -54,6 +58,7 @@ ; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@no_promote ; IS__CGSCC_OPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -66,6 +71,7 @@ ; IS__CGSCC_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@no_promote ; IS__CGSCC_NPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -90,21 +96,23 @@ } define internal fastcc void @promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 { -; 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:%.*]]) -; 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:%.*]]) +; 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-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:%.*]]) -; 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:%.*]]) +; 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 @@ -113,6 +121,7 @@ } define void @promote(<4 x i64>* %arg) #0 { +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@promote ; IS__TUNIT_OPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -125,6 +134,7 @@ ; IS__TUNIT_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote ; IS__TUNIT_NPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -138,6 +148,7 @@ ; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@promote ; IS__CGSCC_OPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -150,6 +161,7 @@ ; IS__CGSCC_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@promote ; IS__CGSCC_NPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -157,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 0, i64 32, i1 false) -; 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]]) +; 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]]) ; 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 @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM @@ -11,21 +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-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:%.*]]) -; 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-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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -35,6 +37,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg) #0 { ; +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -47,6 +50,7 @@ ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -60,6 +64,7 @@ ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -72,6 +77,7 @@ ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -79,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 0, i64 32, i1 false) -; 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]]) +; 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]]) ; 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 @@ -98,21 +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-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:%.*]]) -; 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-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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -122,6 +131,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg) #1 { ; +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -134,6 +144,7 @@ ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -147,6 +158,7 @@ ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -159,6 +171,7 @@ ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -166,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 0, i64 32, i1 false) -; 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]]) +; 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]]) ; 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 @@ -185,21 +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-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:%.*]]) -; 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-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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -209,6 +225,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %arg) #0 { ; +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -221,6 +238,7 @@ ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -234,6 +252,7 @@ ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -246,6 +265,7 @@ ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -253,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 0, i64 32, i1 false) -; 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]]) +; 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]]) ; 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 @@ -272,21 +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-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:%.*]]) -; 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-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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -296,6 +319,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* %arg) #1 { ; +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -308,6 +332,7 @@ ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -321,6 +346,7 @@ ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -333,6 +359,7 @@ ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -340,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 0, i64 32, i1 false) -; 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]]) +; 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]]) ; 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 @@ -359,19 +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-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:%.*]]) -; 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-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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -381,6 +411,7 @@ define void @avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg) #2 { ; +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -393,6 +424,7 @@ ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -405,6 +437,7 @@ ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -417,6 +450,7 @@ ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -443,19 +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-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:%.*]]) -; 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-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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -465,6 +501,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>* %arg) #1 { ; +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -477,6 +514,7 @@ ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -489,6 +527,7 @@ ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -501,6 +540,7 @@ ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -527,21 +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-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:%.*]]) -; 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-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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -551,6 +593,7 @@ define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %arg) #4 { ; +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -563,6 +606,7 @@ ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -576,6 +620,7 @@ ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -588,6 +633,7 @@ ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -595,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 0, i64 32, i1 false) -; 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]]) +; 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]]) ; 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 @@ -614,21 +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-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:%.*]]) -; 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-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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -638,6 +687,7 @@ define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %arg) #3 { ; +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_OPM-NEXT: bb: @@ -650,6 +700,7 @@ ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]]) ; IS__TUNIT_NPM-NEXT: bb: @@ -663,6 +714,7 @@ ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_OPM-NEXT: bb: @@ -675,6 +727,7 @@ ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint norecurse nosync nounwind uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) ; IS__CGSCC_NPM-NEXT: bb: @@ -682,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 0, i64 32, i1 false) -; 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]]) +; 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]]) ; 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 @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes ; In PR41658, argpromotion put an inalloca in a position that per the ; calling convention is passed in a register. This test verifies that ; we don't do that anymore. It also verifies that the combination of @@ -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 noundef 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* noundef [[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 noundef 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* noundef [[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 noundef 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* noundef [[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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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]]) ; 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:%.*]]) -; 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]]) -; 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:%.*]]) +; 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]]) +; 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:%.*]]) +; 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]]) +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] ; %B = alloca i64 store i64 1, i64* %B @@ -164,12 +196,20 @@ ; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]]) ; IS__TUNIT_NPM-NEXT: ret i32 [[X]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller() -; 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]]) -; 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-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]]) +; 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-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]]) +; 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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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]]) ; 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:%.*]]) -; 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]]) -; 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:%.*]]) +; 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]]) +; 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:%.*]]) +; 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]]) +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] ; %A = alloca i32 store i32 1, i32* %A @@ -91,12 +115,20 @@ ; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]]) ; IS__TUNIT_NPM-NEXT: ret i32 [[X]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller() -; 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]]) -; 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-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]]) +; 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-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]]) +; 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:%.*]]) +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull byval align 32 dereferenceable(12) [[B:%.*]]) ; 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 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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -65,12 +77,20 @@ ; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32 [[TMP1]]) ; IS__TUNIT_NPM-NEXT: ret i32 [[X]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@foo() -; 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]]) -; 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-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]]) +; 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-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]]) +; 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 @@ -87,7 +87,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:%.*]]) +; IS__CGSCC____-SAME: (%struct.ss* inalloca noalias nocapture nofree noundef nonnull align 4 dereferenceable(8) [[S:%.*]]) ; 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 @@ -78,7 +78,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 noundef nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* inalloca nocapture nofree noundef nonnull writeonly align 4 dereferenceable(8) [[B:%.*]]) +; IS__CGSCC____-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* inalloca noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(8) [[B:%.*]]) ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: ret i1 undef ; 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:%.*]]) -; 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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[X:%.*]]) ; 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 @@ -62,18 +52,18 @@ ; ; 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:%.*]]) +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) ; 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]]) -; 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]]) +; 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:%.*]]) +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B:%.*]]) ; 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]]) +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) ; IS__CGSCC_NPM-NEXT: ret i32 undef ; %A = alloca i32 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,17 +72,6 @@ } define internal i32 @test2(%T* %p, i32 %p2) { -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@test2 -; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) -; 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 i32 @foo(%T* undef, i32 [[V]]) -; IS__CGSCC____-NEXT: ret i32 [[CA]] -; %a.gep = getelementptr %T, %T* %p, i64 0, i32 3 %b.gep = getelementptr %T, %T* %p, i64 0, i32 2 %a = load i32, i32* %a.gep @@ -98,11 +87,10 @@ ; IS__TUNIT____-SAME: (%T* nocapture nofree readnone [[G:%.*]]) ; 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:%.*]]) -; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2(%T* nocapture nofree readonly [[G]], i32 0) -; IS__CGSCC____-NEXT: ret i32 [[V]] +; IS__CGSCC____-SAME: (%T* nocapture nofree readnone [[G:%.*]]) +; IS__CGSCC____-NEXT: ret i32 0 ; %v = call i32 @test2(%T* %g, i32 0) ret i32 %v @@ -173,9 +161,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:%.*]]) -; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 0) -; IS__CGSCC____-NEXT: ret i32 [[V]] +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[G:%.*]]) +; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 undef) +; 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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 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 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 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 @@ -183,7 +183,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 @@ -14,11 +14,17 @@ ; 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____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) -; 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-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) +; 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-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 @@ -43,7 +49,7 @@ ; 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]]) +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) [[ATTR1:#.*]], [[RNG0:!range !.*]] ; IS__CGSCC____-NEXT: ret i64 [[CALL2]] ; entry: @@ -63,7 +69,8 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2c() ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: ret i64 42 +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) +; 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:%.*]]) -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i16 @bar() -; 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 @@ -56,9 +55,13 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@bar() ; IS__TUNIT____-NEXT: ret i16 0 ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@bar() -; 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-NEXT: ret i16 0 +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar() +; IS__CGSCC_NPM-NEXT: ret i16 undef ; ret i16 0 } @@ -97,18 +100,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 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 7, i16 8, i16 [[A]]) -; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 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 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 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 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 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 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,7 +83,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@no_side_effects ; IS__CGSCC____-SAME: (i8 [[V:%.*]]) -; IS__CGSCC____-NEXT: ret i8* null +; IS__CGSCC____-NEXT: unreachable ; ret i8* null } @@ -103,7 +97,7 @@ ; 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 +; IS__CGSCC____-NEXT: unreachable ; %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 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 1, i32 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 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 1, i32 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 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 1, i32 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 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 1, i32 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 noundef readnone returned "no-capture-maybe-returned" [[ARG:%.*]]) +; IS__CGSCC____-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]]) ; 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:%.*]]) +; IS__CGSCC____-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) ; 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:%.*]]) +; IS__CGSCC____-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) ; 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 @@ -35,7 +35,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:%.*]]) +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) ; 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]]) +; 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]]) ; IS__CGSCC____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2) ; IS__CGSCC____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 ; IS__CGSCC____-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 3, i32 4) 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:%.*]]) ; 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 @@ -147,29 +147,17 @@ ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 { -; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@f1 -; IS__TUNIT____-SAME: (i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr -; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null -; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] -; IS__TUNIT____: 3: -; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2() -; IS__TUNIT____-NEXT: br label [[TMP5]] -; IS__TUNIT____: 5: -; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] -; IS__TUNIT____-NEXT: ret i8* [[TMP6]] -; -; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; IS__CGSCC____-LABEL: define {{[^@]+}}@f1 -; IS__CGSCC____-SAME: (i8* nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr -; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null -; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] -; IS__CGSCC____: 3: -; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2() -; IS__CGSCC____-NEXT: br label [[TMP5]] -; IS__CGSCC____: 5: -; IS__CGSCC____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] -; IS__CGSCC____-NEXT: ret i8* [[TMP6]] +; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CHECK-LABEL: define {{[^@]+}}@f1 +; CHECK-SAME: (i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] +; CHECK: 3: +; CHECK-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2() +; CHECK-NEXT: br label [[TMP5]] +; CHECK: 5: +; CHECK-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] +; CHECK-NEXT: ret i8* [[TMP6]] ; %2 = icmp eq i8* %0, null br i1 %2, label %3, label %5 @@ -245,15 +233,10 @@ ; TEST 7 ; Better than IR information define align 4 i8* @test7() #0 { -; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@test7() -; IS__TUNIT____-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) -; IS__TUNIT____-NEXT: ret i8* [[C]] -; -; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; IS__CGSCC____-LABEL: define {{[^@]+}}@test7() -; IS__CGSCC____-NEXT: [[C:%.*]] = tail call nonnull align 8 dereferenceable(1) i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) @a1) -; IS__CGSCC____-NEXT: ret i8* [[C]] +; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CHECK-LABEL: define {{[^@]+}}@test7() +; CHECK-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) +; CHECK-NEXT: ret i8* [[C]] ; %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1) ret i8* %c @@ -262,33 +245,19 @@ ; TEST 7b ; Function Attrs: nounwind readnone ssp uwtable define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 { -; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@f1b -; IS__TUNIT____-SAME: (i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr -; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null -; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] -; IS__TUNIT____: 3: -; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() -; IS__TUNIT____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 -; IS__TUNIT____-NEXT: store i8 [[L]], i8* @a1, align 8 -; IS__TUNIT____-NEXT: br label [[TMP5]] -; IS__TUNIT____: 5: -; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] -; IS__TUNIT____-NEXT: ret i8* [[TMP6]] -; -; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind uwtable -; IS__CGSCC____-LABEL: define {{[^@]+}}@f1b -; IS__CGSCC____-SAME: (i8* nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr -; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null -; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] -; IS__CGSCC____: 3: -; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() -; IS__CGSCC____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 -; IS__CGSCC____-NEXT: store i8 [[L]], i8* @a1, align 8 -; IS__CGSCC____-NEXT: br label [[TMP5]] -; IS__CGSCC____: 5: -; IS__CGSCC____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] -; IS__CGSCC____-NEXT: ret i8* [[TMP6]] +; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@f1b +; CHECK-SAME: (i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] +; CHECK: 3: +; CHECK-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() +; CHECK-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 +; CHECK-NEXT: store i8 [[L]], i8* @a1, align 8 +; CHECK-NEXT: br label [[TMP5]] +; CHECK: 5: +; CHECK-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] +; CHECK-NEXT: ret i8* [[TMP6]] ; %2 = icmp eq i8* %0, null br i1 %2, label %3, label %5 @@ -365,17 +334,11 @@ } define align 4 i32* @test7b(i32* align 32 %p) #0 { -; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@test7b -; IS__TUNIT____-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) -; IS__TUNIT____-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) -; IS__TUNIT____-NEXT: ret i32* [[P]] -; -; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind uwtable -; IS__CGSCC____-LABEL: define {{[^@]+}}@test7b -; IS__CGSCC____-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) @a1) -; IS__CGSCC____-NEXT: ret i32* [[P]] +; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable +; CHECK-LABEL: define {{[^@]+}}@test7b +; CHECK-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) +; CHECK-NEXT: ret i32* [[P]] ; tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1) ret i32* %p @@ -404,21 +367,13 @@ 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 noundef readnone align 4 [[A:%.*]], i32* noalias nocapture noundef readnone align 4 [[B:%.*]], i32* noalias nocapture noundef readnone [[C:%.*]]) -; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture noundef readnone align 4 [[A]]) -; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture noundef readnone align 4 [[B]]) -; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture noundef readnone [[C]]) -; IS__TUNIT____-NEXT: ret void -; -; IS__CGSCC____: Function Attrs: nounwind -; IS__CGSCC____-LABEL: define {{[^@]+}}@test8 -; IS__CGSCC____-SAME: (i32* nocapture readnone align 4 [[A:%.*]], i32* nocapture readnone align 4 [[B:%.*]], i32* nocapture readnone [[C:%.*]]) -; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) -; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) -; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) -; IS__CGSCC____-NEXT: ret void +; CHECK: Function Attrs: nounwind +; CHECK-LABEL: define {{[^@]+}}@test8 +; CHECK-SAME: (i32* noalias nocapture noundef readnone align 4 [[A:%.*]], i32* noalias nocapture noundef readnone align 4 [[B:%.*]], i32* noalias nocapture noundef readnone [[C:%.*]]) +; CHECK-NEXT: call void @user_i32_ptr(i32* noalias nocapture noundef readnone align 4 [[A]]) +; CHECK-NEXT: call void @user_i32_ptr(i32* noalias nocapture noundef readnone align 4 [[B]]) +; CHECK-NEXT: call void @user_i32_ptr(i32* noalias nocapture noundef readnone [[C]]) +; CHECK-NEXT: ret void ; call void @user_i32_ptr(i32* %a) call void @user_i32_ptr(i32* %b) 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 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 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 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 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:%.*]]) -; 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 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:%.*]]) -; 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 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:%.*]]) +; 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 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:%.*]]) +; 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 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 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 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 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 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 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 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 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 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 @@ -44,12 +44,12 @@ ; ; 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:%.*]]) +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) ; 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]]) +; IS__CGSCC____-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]]) ; IS__CGSCC____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] ; IS__CGSCC____-NEXT: ret i32 [[ADD2]] ; @@ -75,7 +75,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:%.*]]) +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 @@ -142,13 +142,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:%.*]]) -; 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:%.*]]) +; 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:%.*]]) +; 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 @@ -173,12 +185,21 @@ ; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32 [[TMP1]], i32 [[TMP2]]) ; 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____-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]]) -; 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-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]]) +; 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-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]]) +; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; %B = alloca i32, align 4 store i32 5, i32* %B, align 4 @@ -196,7 +217,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:%.*]]) +; IS__CGSCC____-SAME: (i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B:%.*]]) ; 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]] 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 @@ -1657,31 +1657,18 @@ ; FIXME: We should fold terminators. define internal i32 @switch_default(i64 %i) nounwind { -; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@switch_default() -; NOT_CGSCC_NPM-NEXT: entry: -; NOT_CGSCC_NPM-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [ -; NOT_CGSCC_NPM-NEXT: i64 3, label [[RETURN:%.*]] -; NOT_CGSCC_NPM-NEXT: i64 10, label [[RETURN]] -; NOT_CGSCC_NPM-NEXT: ] -; NOT_CGSCC_NPM: sw.default: -; NOT_CGSCC_NPM-NEXT: call void @sink() -; NOT_CGSCC_NPM-NEXT: ret i32 undef -; NOT_CGSCC_NPM: return: -; NOT_CGSCC_NPM-NEXT: unreachable -; -; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@switch_default() -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [ -; IS__CGSCC____-NEXT: i64 3, label [[RETURN:%.*]] -; IS__CGSCC____-NEXT: i64 10, label [[RETURN]] -; IS__CGSCC____-NEXT: ] -; IS__CGSCC____: sw.default: -; IS__CGSCC____-NEXT: call void @sink() -; IS__CGSCC____-NEXT: ret i32 123 -; IS__CGSCC____: return: -; IS__CGSCC____-NEXT: unreachable +; CHECK: Function Attrs: nofree nosync nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@switch_default() +; CHECK-NEXT: entry: +; CHECK-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [ +; CHECK-NEXT: i64 3, label [[RETURN:%.*]] +; CHECK-NEXT: i64 10, label [[RETURN]] +; CHECK-NEXT: ] +; CHECK: sw.default: +; CHECK-NEXT: call void @sink() +; CHECK-NEXT: ret i32 undef +; CHECK: return: +; CHECK-NEXT: unreachable ; entry: switch i64 %i, label %sw.default [ @@ -1716,7 +1703,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 @@ -528,31 +528,18 @@ } define internal i8 @recursive_not_readnone_internal(i8* %ptr, i1 %c) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind -; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal -; IS__TUNIT____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) -; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 -; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__TUNIT____: t: -; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false) -; IS__TUNIT____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1 -; IS__TUNIT____-NEXT: ret i8 [[R]] -; IS__TUNIT____: f: -; IS__TUNIT____-NEXT: store i8 1, i8* [[PTR]], align 1 -; IS__TUNIT____-NEXT: ret i8 0 -; -; 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:%.*]]) -; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 -; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false) -; IS__CGSCC____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1 -; IS__CGSCC____-NEXT: ret i8 [[R]] -; IS__CGSCC____: f: -; IS__CGSCC____-NEXT: store i8 1, i8* [[PTR]], align 1 -; IS__CGSCC____-NEXT: ret i8 0 +; CHECK: Function Attrs: argmemonly nofree nosync nounwind +; CHECK-LABEL: define {{[^@]+}}@recursive_not_readnone_internal +; CHECK-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) +; CHECK-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 +; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; CHECK: t: +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false) +; CHECK-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1 +; CHECK-NEXT: ret i8 [[R]] +; CHECK: f: +; CHECK-NEXT: store i8 1, i8* [[PTR]], align 1 +; CHECK-NEXT: ret i8 0 ; %alloc = alloca i8 br i1 %c, label %t, label %f @@ -579,31 +566,18 @@ } define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind -; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2 -; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) -; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 -; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__TUNIT____: t: -; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal2(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false) -; IS__TUNIT____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1 -; IS__TUNIT____-NEXT: ret i8 [[R]] -; IS__TUNIT____: f: -; IS__TUNIT____-NEXT: store i8 1, i8* [[PTR]], align 1 -; IS__TUNIT____-NEXT: ret i8 0 -; -; 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:%.*]]) -; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 -; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal2(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false) -; IS__CGSCC____-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1 -; IS__CGSCC____-NEXT: ret i8 [[R]] -; IS__CGSCC____: f: -; IS__CGSCC____-NEXT: store i8 1, i8* [[PTR]], align 1 -; IS__CGSCC____-NEXT: ret i8 0 +; CHECK: Function Attrs: argmemonly nofree nosync nounwind +; CHECK-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2 +; CHECK-SAME: (i8* noalias nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) +; CHECK-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 +; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; CHECK: t: +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @recursive_not_readnone_internal2(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 false) +; CHECK-NEXT: [[R:%.*]] = load i8, i8* [[ALLOC]], align 1 +; CHECK-NEXT: ret i8 [[R]] +; CHECK: f: +; CHECK-NEXT: store i8 1, i8* [[PTR]], align 1 +; CHECK-NEXT: ret i8 0 ; %alloc = alloca i8 br i1 %c, label %t, label %f 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 @@ -550,7 +550,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@p2i -; IS__CGSCC____-SAME: (i32* nofree readnone [[ARG:%.*]]) +; IS__CGSCC____-SAME: (i32* noalias nofree readnone [[ARG:%.*]]) ; IS__CGSCC____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32 ; IS__CGSCC____-NEXT: ret i32 [[P2I]] ; @@ -610,17 +610,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 144, i8* nocapture noundef nonnull align 8 dereferenceable(240) [[TMP0]]) -; 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 0) -; CHECK-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 1, i32 1) -; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 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 144, i8* nocapture noundef nonnull align 8 dereferenceable(240) [[TMP0]]) +; 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 0) +; NOT_CGSCC_NPM-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 1, i32 1) +; NOT_CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 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 144, i8* nocapture noundef nonnull align 8 dereferenceable(240) [[TMP0]]) +; 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 0) +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 1, i32 1) +; IS__CGSCC____-NEXT: call void @llvm.lifetime.end.p0i8(i64 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:%.*]]) +; IS__CGSCC____-SAME: (i64* nocapture nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]]) -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A]]) +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) ; 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:%.*]]) +; IS__CGSCC____-SAME: (i64* nofree nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]]) ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) [[A]]) +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) ; 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:%.*]]) ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) [[A]]) +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) ; 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:%.*]]) +; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A:%.*]]) ; 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]]) +; 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]]) ; 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:%.*]]) ; 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]]) +; 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]]) ; 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 @@ -377,21 +377,13 @@ 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 noundef nonnull readnone [[A:%.*]], i8* noalias nocapture nofree noundef readnone [[B:%.*]], i8* noalias nocapture nofree noundef readnone [[C:%.*]]) -; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree noundef nonnull readnone [[A]]) -; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree noundef readnone [[B]]) -; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree noundef readnone [[C]]) -; IS__TUNIT____-NEXT: ret void -; -; IS__CGSCC____: Function Attrs: nounwind -; IS__CGSCC____-LABEL: define {{[^@]+}}@test13 -; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[A:%.*]], i8* nocapture nofree readnone [[B:%.*]], i8* nocapture nofree readnone [[C:%.*]]) -; IS__CGSCC____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[A]]) -; IS__CGSCC____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) -; IS__CGSCC____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) -; IS__CGSCC____-NEXT: ret void +; CHECK: Function Attrs: nounwind +; CHECK-LABEL: define {{[^@]+}}@test13 +; CHECK-SAME: (i8* noalias nocapture nofree noundef nonnull readnone [[A:%.*]], i8* noalias nocapture nofree noundef readnone [[B:%.*]], i8* noalias nocapture nofree noundef readnone [[C:%.*]]) +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree noundef nonnull readnone [[A]]) +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree noundef readnone [[B]]) +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree noundef readnone [[C]]) +; CHECK-NEXT: ret void ; call void @use_i8_ptr(i8* %a) call void @use_i8_ptr(i8* %b) @@ -894,7 +886,7 @@ define internal i32* @g2() { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@g2() -; IS__CGSCC____-NEXT: ret i32* inttoptr (i64 4 to i32*) +; IS__CGSCC____-NEXT: unreachable ; ret i32* inttoptr (i64 4 to i32*) } @@ -914,17 +906,11 @@ 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:%.*]]) -; IS__TUNIT____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) -; IS__TUNIT____-NEXT: ret void -; -; IS__CGSCC____: Function Attrs: nounwind -; IS__CGSCC____-LABEL: define {{[^@]+}}@called_by_weak -; IS__CGSCC____-SAME: (i32* nocapture nonnull readnone [[A:%.*]]) -; IS__CGSCC____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) -; IS__CGSCC____-NEXT: ret void +; CHECK: Function Attrs: nounwind +; CHECK-LABEL: define {{[^@]+}}@called_by_weak +; CHECK-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) +; CHECK-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) +; CHECK-NEXT: ret void ; call void @use_i32_ptr(i32* %a) ret void @@ -943,17 +929,11 @@ ; 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:%.*]]) -; IS__TUNIT____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A]]) -; IS__TUNIT____-NEXT: ret void -; -; IS__CGSCC____: Function Attrs: nounwind -; IS__CGSCC____-LABEL: define {{[^@]+}}@control -; IS__CGSCC____-SAME: (i32* nocapture nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) -; IS__CGSCC____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A]]) -; IS__CGSCC____-NEXT: ret void +; CHECK: Function Attrs: nounwind +; CHECK-LABEL: define {{[^@]+}}@control +; CHECK-SAME: (i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) +; CHECK-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A]]) +; CHECK-NEXT: ret void ; call void @use_i32_ptr(i32* %a) ret void diff --git a/llvm/test/Transforms/Attributor/noundef.ll b/llvm/test/Transforms/Attributor/noundef.ll --- a/llvm/test/Transforms/Attributor/noundef.ll +++ b/llvm/test/Transforms/Attributor/noundef.ll @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM @@ -9,7 +9,7 @@ declare void @bar(i32*) define void @foo() { -; CHECK-LABEL: @foo( +; CHECK-LABEL: define {{[^@]+}}@foo() ; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 ; CHECK-NEXT: call void @unknown() ; CHECK-NEXT: call void @bar(i32* noundef nonnull align 4 dereferenceable(4) [[X]]) 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 @@ -12,10 +12,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:%.*]]) -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero1() +; IS__CGSCC____-NEXT: ret i1 undef ; %cmp = icmp eq i32 %c, 0 ret i1 %cmp @@ -30,9 +28,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test1 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[ARG:%.*]] = select i1 [[C]], i32 -1, i32 1 -; IS__CGSCC____-NEXT: [[RET:%.*]] = call i1 @iszero1(i32 [[ARG]]) -; IS__CGSCC____-NEXT: ret i1 [[RET]] +; IS__CGSCC____-NEXT: ret i1 false ; %arg = select i1 %c, i32 -1, i32 1 %ret = call i1 @iszero1(i32 %arg) @@ -50,11 +46,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:%.*]]) -; 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____-LABEL: define {{[^@]+}}@iszero2() +; IS__CGSCC____-NEXT: ret i32 undef ; %cmp = icmp eq i32 %c, 0 %ret = zext i1 %cmp to i32 @@ -63,13 +56,8 @@ define internal i32 @call_with_two_values(i32 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@call_with_two_values -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 [[C]]) -; IS__CGSCC____-NEXT: [[MINUSC:%.*]] = sub i32 0, [[C]] -; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @iszero2(i32 [[MINUSC]]) -; IS__CGSCC____-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC____-NEXT: ret i32 [[RET]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@call_with_two_values() +; IS__CGSCC____-NEXT: ret i32 undef ; %csret1 = call i32 @iszero2(i32 %c) %minusc = sub i32 0, %c @@ -87,10 +75,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test2 ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 1) -; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 -1) -; IS__CGSCC____-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC____-NEXT: ret i32 [[RET]] +; IS__CGSCC____-NEXT: ret i32 0 ; %csret1 = call i32 @call_with_two_values(i32 1) %csret2 = call i32 @call_with_two_values(i32 -1) @@ -168,14 +153,23 @@ ; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] ; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test3() -; IS__CGSCC____-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 0) -; IS__CGSCC____-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) -; IS__CGSCC____-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 1) -; IS__CGSCC____-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) -; IS__CGSCC____-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] -; IS__CGSCC____-NEXT: ret i32 [[RET]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test3() +; IS__CGSCC_OPM-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 0) +; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) [[ATTR2:#.*]], [[RNG0:!range !.*]] +; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 1) +; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[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-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 0) [[ATTR1:#.*]], [[RNG0:!range !.*]] +; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) [[ATTR1]], [[RNG0]] +; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 1) [[ATTR1]], [[RNG0]] +; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) [[ATTR1]], [[RNG0]] +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %cmp1 = call i32 @iszero3(i32 0) %true1 = call i32 @less_than_two(i32 %cmp1) @@ -205,10 +199,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test4 ; IS__CGSCC____-SAME: (i32 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) -; IS__CGSCC____-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET]], 2 -; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 -; IS__CGSCC____-NEXT: ret i32 [[RET]] +; IS__CGSCC____-NEXT: ret i32 0 ; %csret = call i32 @return1or3(i32 %c) %false = icmp eq i32 %csret, 2 @@ -225,11 +216,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test5 ; IS__CGSCC____-SAME: (i32 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) -; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) -; IS__CGSCC____-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 -; IS__CGSCC____-NEXT: ret i32 [[RET]] +; IS__CGSCC____-NEXT: ret i32 0 ; %csret1 = call i32 @return1or3(i32 %c) %csret2 = call i32 @return2or4(i32 %c) @@ -253,12 +240,19 @@ ; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 ; IS__TUNIT_NPM-NEXT: ret i1 [[RET]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test6 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) -; IS__CGSCC____-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 -; IS__CGSCC____-NEXT: ret i1 [[RET]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test6 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) +; 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:%.*]]) +; 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]] ; %csret1 = call i32 @return1or3(i32 %c) %ret = icmp eq i32 %csret1, 3 @@ -282,13 +276,21 @@ ; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] ; IS__TUNIT_NPM-NEXT: ret i1 [[RET]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test7 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) -; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) -; IS__CGSCC____-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC____-NEXT: ret i1 [[RET]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test7 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) +; 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:%.*]]) +; 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]] ; %csret1 = call i32 @return1or3(i32 %c) %csret2 = call i32 @return3or4(i32 %c) @@ -320,9 +322,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@return2or4 ; IS__CGSCC____-SAME: (i32 [[C:%.*]]) -; 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 @@ -355,10 +355,8 @@ 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:%.*]]) -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 4 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@cmp_with_four() +; IS__CGSCC____-NEXT: ret i1 undef ; %cmp = icmp eq i32 %c, 4 ret i1 %cmp @@ -366,10 +364,8 @@ define internal i1 @wrapper(i32 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@wrapper -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[RET:%.*]] = call i1 @cmp_with_four(i32 [[C]]) -; IS__CGSCC____-NEXT: ret i1 [[RET]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@wrapper() +; IS__CGSCC____-NEXT: ret i1 undef ; %ret = call i1 @cmp_with_four(i32 %c) ret i1 %ret @@ -382,12 +378,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@potential_test8() -; IS__CGSCC____-NEXT: [[RES1:%.*]] = call i1 @wrapper(i32 1) -; IS__CGSCC____-NEXT: [[RES3:%.*]] = call i1 @wrapper(i32 3) -; IS__CGSCC____-NEXT: [[RES5:%.*]] = call i1 @wrapper(i32 5) -; IS__CGSCC____-NEXT: [[RES13:%.*]] = or i1 [[RES1]], [[RES3]] -; IS__CGSCC____-NEXT: [[RES135:%.*]] = or i1 [[RES13]], [[RES5]] -; IS__CGSCC____-NEXT: ret i1 [[RES135]] +; IS__CGSCC____-NEXT: ret i1 false ; %res1 = call i1 @wrapper(i32 1) %res3 = call i1 @wrapper(i32 3) @@ -546,12 +537,19 @@ ; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0 ; IS__TUNIT_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:%.*]]) -; IS__CGSCC____-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test10 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) [[ATTR2]], [[RNG3:!range !.*]] +; 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:%.*]]) +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) [[ATTR1]], [[RNG3:!range !.*]] +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0 +; IS__CGSCC_NPM-NEXT: ret i1 [[CMP]] ; %ret = call i32 @may_return_undef(i32 %c) %cmp = icmp eq i32 %ret, 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 @@ -36,11 +36,17 @@ ; IS__TUNIT_NPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) [[ATTR2:#.*]], [[RNG0:!range !.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[A]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-range-check -; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) -; IS__CGSCC____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) -; IS__CGSCC____-NEXT: ret i32 [[A]] +; 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:%.*]]) +; 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:%.*]]) +; 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) ret i32 %a @@ -154,72 +160,99 @@ ; IS__TUNIT_NPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 false) ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-icmp-check -; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) -; IS__CGSCC____-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) -; IS__CGSCC____-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10 -; IS__CGSCC____-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9 -; IS__CGSCC____-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8 -; IS__CGSCC____-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1 -; IS__CGSCC____-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0 -; IS__CGSCC____-NEXT: [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1 -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_EQ_1]], i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 [[CMP_EQ_6]]) -; IS__CGSCC____-NEXT: [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10 -; IS__CGSCC____-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9 -; IS__CGSCC____-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8 -; IS__CGSCC____-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1 -; IS__CGSCC____-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0 -; IS__CGSCC____-NEXT: [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1 -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_NE_1]], i1 [[CMP_NE_2]], i1 [[CMP_NE_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 [[CMP_NE_6]]) -; IS__CGSCC____-NEXT: [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10 -; IS__CGSCC____-NEXT: [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9 -; IS__CGSCC____-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8 -; IS__CGSCC____-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1 -; IS__CGSCC____-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0 -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1 [[CMP_UGT_2]], i1 [[CMP_UGT_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false) -; IS__CGSCC____-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10 -; IS__CGSCC____-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9 -; IS__CGSCC____-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8 -; IS__CGSCC____-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1 -; IS__CGSCC____-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1 -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 [[CMP_UGE_6]]) -; IS__CGSCC____-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10 -; IS__CGSCC____-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9 -; IS__CGSCC____-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8 -; IS__CGSCC____-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1 -; IS__CGSCC____-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0 -; IS__CGSCC____-NEXT: [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1 -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SGT_1]], i1 [[CMP_SGT_2]], i1 [[CMP_SGT_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 [[CMP_SGT_6]]) -; IS__CGSCC____-NEXT: [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10 -; IS__CGSCC____-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9 -; IS__CGSCC____-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8 -; IS__CGSCC____-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1 -; IS__CGSCC____-NEXT: [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0 -; IS__CGSCC____-NEXT: [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1 -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_GTE_1]], i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 [[CMP_GTE_5]], i1 [[CMP_GTE_6]]) -; IS__CGSCC____-NEXT: [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10 -; IS__CGSCC____-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9 -; IS__CGSCC____-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8 -; IS__CGSCC____-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1 -; IS__CGSCC____-NEXT: [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0 -; IS__CGSCC____-NEXT: [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1 -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SLT_1]], i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 [[CMP_SLT_5]], i1 [[CMP_SLT_6]]) -; IS__CGSCC____-NEXT: [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10 -; IS__CGSCC____-NEXT: [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9 -; IS__CGSCC____-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8 -; IS__CGSCC____-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1 -; IS__CGSCC____-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0 -; IS__CGSCC____-NEXT: [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1 -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_LTE_1]], i1 [[CMP_LTE_2]], i1 [[CMP_LTE_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 [[CMP_LTE_6]]) -; IS__CGSCC____-NEXT: ret void +; 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]], [[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: tail call void @use3(i1 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 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: tail call void @use3(i1 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 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 false, i1 false, i1 [[CMP_UGT_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false) +; 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: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 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: tail call void @use3(i1 false, i1 false, i1 [[CMP_SGT_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 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: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 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: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1 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: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]]) +; IS__CGSCC_OPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 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]], [[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: tail call void @use3(i1 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 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: tail call void @use3(i1 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 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 false, i1 false, i1 [[CMP_UGT_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1 [[CMP_UGT_5]], i1 false) +; 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: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1 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: tail call void @use3(i1 false, i1 false, i1 [[CMP_SGT_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 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: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 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: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1 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: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]]) +; IS__CGSCC_NPM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 false) +; IS__CGSCC_NPM-NEXT: ret void ; %ret = tail call i32 @test0(i32 *%p) @@ -344,12 +377,19 @@ ; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 ; IS__TUNIT_NPM-NEXT: ret i1 [[CMP]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@test1-check -; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) -; IS__CGSCC____-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; 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:%.*]]) +; 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:%.*]]) +; 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]] ; %res = tail call i32 @test1(i32* %p) %cmp = icmp eq i32 %res, 500 @@ -411,16 +451,13 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_check ; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = tail call i32 @test2(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]]) -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5 -; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__CGSCC____-NEXT: br label [[IF_THEN:%.*]] ; IS__CGSCC____: if.then: ; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] ; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: br label [[RETURN]] +; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: return: -; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ] -; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]] +; IS__CGSCC____-NEXT: ret i32 2 ; entry: %call = tail call i32 @test2(i32* %p) @@ -510,7 +547,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]] ] @@ -538,16 +575,16 @@ } define void @f1(i32){ -; IS________OPM-LABEL: define {{[^@]+}}@f1 -; IS________OPM-SAME: (i32 [[TMP0:%.*]]) -; IS________OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1() -; IS________OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15 -; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] -; IS________OPM: 4: -; IS________OPM-NEXT: tail call void @unkown() -; IS________OPM-NEXT: br label [[TMP5]] -; IS________OPM: 5: -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f1 +; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]]) +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1() +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15 +; IS__TUNIT_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] +; IS__TUNIT_OPM: 4: +; IS__TUNIT_OPM-NEXT: tail call void @unkown() +; IS__TUNIT_OPM-NEXT: br label [[TMP5]] +; IS__TUNIT_OPM: 5: +; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f1 @@ -558,6 +595,17 @@ ; IS__TUNIT_NPM: 3: ; IS__TUNIT_NPM-NEXT: ret void ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1 +; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) +; 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: +; IS__CGSCC_OPM-NEXT: tail call void @unkown() +; IS__CGSCC_OPM-NEXT: br label [[TMP5]] +; IS__CGSCC_OPM: 5: +; IS__CGSCC_OPM-NEXT: ret void +; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1 ; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) @@ -721,12 +769,19 @@ ; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) [[ATTR1:#.*]], [[RNG3:!range !.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@test4-g2 -; IS__CGSCC____-SAME: (i32 [[U:%.*]]) -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) -; IS__CGSCC____-NEXT: ret i32 [[CALL]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g2 +; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) +; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4-g2 +; IS__CGSCC_NPM-SAME: (i32 [[U:%.*]]) +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) [[ATTR3:#.*]], [[RNG3:!range !.*]] +; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; entry: %call = tail call i32 @test4-f2(i32 %u) @@ -739,15 +794,10 @@ ; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 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 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 i32 @rec(i32 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 0), [[RNG4:!range !.*]] +; NOT_TUNIT_OPM-NEXT: ret i32 [[CALL]] ; entry: %call = call i32 @rec(i32 0) @@ -1155,10 +1205,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_collapse_caller() -; IS__CGSCC____-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() -; IS__CGSCC____-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() -; IS__CGSCC____-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]] -; IS__CGSCC____-NEXT: ret i8 [[A]] +; IS__CGSCC____-NEXT: ret i8 0 ; %c1 = call i8 @undef_collapse_1() %c2 = call i8 @undef_collapse_2() @@ -1192,14 +1239,7 @@ ; 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:%.*]]) -; IS__CGSCC____-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) -; IS__CGSCC____-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) -; IS__CGSCC____-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]] -; IS__CGSCC____-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]] -; IS__CGSCC____-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4 -; IS__CGSCC____-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 -; IS__CGSCC____-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] -; IS__CGSCC____-NEXT: ret i1 [[F]] +; IS__CGSCC____-NEXT: ret i1 true ; %r1 = call i32 @ret1or2(i1 %c1) %r2 = call i32 @ret1or2(i1 %c2) @@ -1235,16 +1275,27 @@ ; IS__TUNIT_NPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] ; IS__TUNIT_NPM-NEXT: ret i1 [[F]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_range_2 -; IS__CGSCC____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) -; IS__CGSCC____-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) -; IS__CGSCC____-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) -; IS__CGSCC____-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] -; IS__CGSCC____-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 -; IS__CGSCC____-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 -; IS__CGSCC____-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] -; IS__CGSCC____-NEXT: ret i1 [[F]] +; 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:%.*]]) +; 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 +; 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_2 +; IS__CGSCC_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) +; 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 +; IS__CGSCC_NPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] +; IS__CGSCC_NPM-NEXT: ret i1 [[F]] ; %r1 = call i32 @ret1or2(i1 %c1) %r2 = call i32 @ret1or2(i1 %c2) @@ -1372,7 +1423,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 true) [[ATTR1]], [[RNG4]] +; IS__TUNIT_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 true) [[ATTR1]], [[RNG4:!range !.*]] ; IS__TUNIT_NPM-NEXT: ret i32 [[RET1]] ; IS__TUNIT_NPM: f: ; IS__TUNIT_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) [[ATTR1]], [[RNG4]] @@ -1384,10 +1435,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 i32 @func(i1 [[C]]) +; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 [[C]]) [[ATTR4]], [[RNG4:!range !.*]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET1]] ; IS__CGSCC_OPM: f: -; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) +; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) [[ATTR4]], [[RNG4]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn @@ -1396,10 +1447,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 i32 @func(i1 true) +; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 true) [[ATTR3]], [[RNG4:!range !.*]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RET1]] ; IS__CGSCC_NPM: f: -; IS__CGSCC_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) +; IS__CGSCC_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) [[ATTR3]], [[RNG4]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RET2]] ; %c = select i1 %d, i1 true, i1 false @@ -1468,15 +1519,25 @@ ; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]] ; IS__TUNIT_NPM-NEXT: ret i1 [[RET]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@check_divided_range -; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 0) -; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) -; IS__CGSCC____-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) -; IS__CGSCC____-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) -; IS__CGSCC____-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]] -; IS__CGSCC____-NEXT: ret i1 [[RET]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@check_divided_range +; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 0) +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) +; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) +; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]] +; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] +; +; 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:%.*]]) +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 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]]) +; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]] +; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] ; %csret1 = call i32 @less_than_65536(i32 0) %csret2 = call i32 @less_than_65536(i32 %arg) @@ -1496,8 +1557,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cast_and_return ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) -; 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 @@ -1511,10 +1571,8 @@ ; IS__TUNIT_OPM-NEXT: ret i1 [[CMP]] ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_3 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 3 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_3() +; IS__CGSCC____-NEXT: ret i1 undef ; %cmp = icmp slt i32 %c, 3 ret i1 %cmp @@ -1539,11 +1597,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@check_casted_range ; IS__CGSCC____-SAME: (i1 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 true) -; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) -; IS__CGSCC____-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]] -; IS__CGSCC____-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) -; IS__CGSCC____-NEXT: ret i1 [[RET]] +; IS__CGSCC____-NEXT: ret i1 true ; %csret1 = call i32 @cast_and_return(i1 true) %csret2 = call i32 @cast_and_return(i1 %c) @@ -1643,11 +1697,16 @@ ; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 ; IS__TUNIT____-NEXT: ret i1 [[CMP]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_1 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@is_less_than_100_1 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) +; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 +; IS__CGSCC_OPM-NEXT: ret i1 [[CMP]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@is_less_than_100_1 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) +; IS__CGSCC_NPM-NEXT: ret i1 true ; %cmp = icmp slt i32 %c, 100 ret i1 %cmp @@ -1669,12 +1728,17 @@ ; IS__TUNIT_NPM-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 [[CSRET]]) ; IS__TUNIT_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:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 [[C]]) -; IS__CGSCC____-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 [[CSRET]]) -; IS__CGSCC____-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:%.*]]) +; IS__CGSCC_OPM-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 [[C]]) [[ATTR4]], [[RNG6:!range !.*]] +; IS__CGSCC_OPM-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 [[CSRET]]) +; 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:%.*]]) +; IS__CGSCC_NPM-NEXT: ret i1 true ; %csret = call i32 @less_than_100_1(i32 %c) %true = call i1 @is_less_than_100_1(i32 %csret) @@ -1804,15 +1868,25 @@ ; IS__TUNIT_NPM-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]] ; IS__TUNIT_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:%.*]]) -; IS__CGSCC____-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 0) -; IS__CGSCC____-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET1]]) -; IS__CGSCC____-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) -; IS__CGSCC____-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET2]]) -; IS__CGSCC____-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]] -; IS__CGSCC____-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:%.*]]) +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 0) [[ATTR4]], [[RNG6]] +; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET1]]) +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) [[ATTR4]], [[RNG6]] +; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET2]]) +; 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:%.*]]) +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 0) [[ATTR3]], [[RNG7:!range !.*]] +; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET1]]) +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) [[ATTR3]], [[RNG7]] +; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 [[CSRET2]]) +; IS__CGSCC_NPM-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]] +; IS__CGSCC_NPM-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:%.*]]) +; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[W0:%.*]]) ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree [[W0]]) -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree align 4 [[R0]], i32* nofree align 4 [[R0]], i32* nofree [[W0]]) -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly align 4 [[R0]], i32* nofree writeonly [[W0]]) -; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]]) +; 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]]) +; 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]]) +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) ; IS__CGSCC____-NEXT: ret i32* [[CALL3]] ; entry: @@ -64,55 +64,30 @@ } define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind -; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_ret0_nw -; IS__TUNIT____-SAME: (i32* nofree returned [[N0:%.*]], i32* nofree [[W0:%.*]]) -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[R0:%.*]] = alloca i32, align 4 -; IS__TUNIT____-NEXT: [[R1:%.*]] = alloca i32, align 4 -; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[N0]], null -; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; IS__TUNIT____: if.then: -; IS__TUNIT____-NEXT: br label [[RETURN:%.*]] -; IS__TUNIT____: if.end: -; IS__TUNIT____-NEXT: store i32 3, i32* [[R0]], align 4 -; IS__TUNIT____-NEXT: store i32 5, i32* [[R1]], align 4 -; IS__TUNIT____-NEXT: store i32 1, i32* [[W0]], align 4 -; IS__TUNIT____-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]]) -; IS__TUNIT____-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]]) -; IS__TUNIT____-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]]) -; IS__TUNIT____-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]]) -; IS__TUNIT____-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]]) -; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) -; IS__TUNIT____-NEXT: br label [[RETURN]] -; IS__TUNIT____: return: -; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ] -; IS__TUNIT____-NEXT: ret i32* [[RETVAL_0]] -; -; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind -; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret0_nw -; IS__CGSCC____-SAME: (i32* nofree returned [[N0:%.*]], i32* nofree [[W0:%.*]]) -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[R0:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: [[R1:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[N0]], null -; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] -; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: store i32 3, i32* [[R0]], align 4 -; IS__CGSCC____-NEXT: store i32 5, i32* [[R1]], align 4 -; IS__CGSCC____-NEXT: store i32 1, i32* [[W0]], align 4 -; 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]]) -; 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]]) -; 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]]) -; 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]]) -; 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]]) -; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) -; IS__CGSCC____-NEXT: br label [[RETURN]] -; IS__CGSCC____: return: -; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ] -; IS__CGSCC____-NEXT: ret i32* [[RETVAL_0]] +; CHECK: Function Attrs: argmemonly nofree nosync nounwind +; CHECK-LABEL: define {{[^@]+}}@internal_ret0_nw +; CHECK-SAME: (i32* nofree returned [[N0:%.*]], i32* nofree [[W0:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[R0:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[R1:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[N0]], null +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: br label [[RETURN:%.*]] +; CHECK: if.end: +; CHECK-NEXT: store i32 3, i32* [[R0]], align 4 +; CHECK-NEXT: store i32 5, i32* [[R1]], align 4 +; CHECK-NEXT: store i32 1, i32* [[W0]], align 4 +; CHECK-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]]) +; CHECK-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]]) +; CHECK-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]]) +; CHECK-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]]) +; CHECK-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]]) +; CHECK-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) +; CHECK-NEXT: br label [[RETURN]] +; CHECK: return: +; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ] +; CHECK-NEXT: ret i32* [[RETVAL_0]] ; entry: %r0 = alloca i32, align 4 @@ -171,7 +146,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:%.*]]) +; IS__CGSCC____-SAME: (i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree nonnull returned align 4 dereferenceable(4) [[R1:%.*]], i32* nofree [[W0:%.*]]) ; 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 +154,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]]) +; 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]]) ; 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 +164,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]]) ; 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]]) ; 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]]) -; 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]]) -; 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]]) +; 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]]) +; 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]]) ; 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]]) ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: return: @@ -306,12 +281,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]]) +; 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]]) ; 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]]) ; 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]]) -; 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]]) +; 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]]) ; 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]]) ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: return: @@ -354,7 +329,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@external_source_ret2_nrw ; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree align 4 [[R0:%.*]], i32* nofree returned [[W0:%.*]]) ; 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]]) +; 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]]) ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree align 4 [[R0]], i32* nofree [[W0]]) ; 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:%.*]]) +; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 4 i32* @test8_1(i32* noalias nofree readnone [[P]]) +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 4 i32* @test8_1(i32* noalias nofree readnone "no-capture-maybe-returned" [[P]]) ; 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 @@ -152,80 +152,42 @@ } define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 { -; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_rX -; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] -; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; IS__TUNIT____: if.then: -; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) -; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) -; IS__TUNIT____-NEXT: br label [[RETURN:%.*]] -; IS__TUNIT____: if.end: -; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] -; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] -; IS__TUNIT____: if.then3: -; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) -; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) -; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) -; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) -; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) -; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) -; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) -; IS__TUNIT____-NEXT: br label [[RETURN]] -; IS__TUNIT____: if.end12: -; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] -; IS__TUNIT____-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; IS__TUNIT____: cond.true: -; IS__TUNIT____-NEXT: br label [[COND_END:%.*]] -; IS__TUNIT____: cond.false: -; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) -; IS__TUNIT____-NEXT: br label [[COND_END]] -; IS__TUNIT____: cond.end: -; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] -; IS__TUNIT____-NEXT: br label [[RETURN]] -; IS__TUNIT____: return: -; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] -; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]] -; -; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_rX -; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] -; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) -; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] -; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] -; 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: [[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: [[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: br label [[RETURN]] -; IS__CGSCC____: if.end12: -; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] -; IS__CGSCC____-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; IS__CGSCC____: cond.true: -; IS__CGSCC____-NEXT: br label [[COND_END:%.*]] -; IS__CGSCC____: cond.false: -; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) -; IS__CGSCC____-NEXT: br label [[COND_END]] -; IS__CGSCC____: cond.end: -; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] -; IS__CGSCC____-NEXT: br label [[RETURN]] -; IS__CGSCC____: return: -; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] -; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]] +; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; CHECK-LABEL: define {{[^@]+}}@scc_rX +; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]] +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) +; CHECK-NEXT: br label [[RETURN:%.*]] +; CHECK: if.end: +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]] +; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] +; CHECK: if.then3: +; CHECK-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) +; CHECK-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) +; CHECK-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) +; CHECK-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) +; CHECK-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) +; CHECK-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) +; CHECK-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) +; CHECK-NEXT: br label [[RETURN]] +; CHECK: if.end12: +; CHECK-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] +; CHECK-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; CHECK: cond.true: +; CHECK-NEXT: br label [[COND_END:%.*]] +; CHECK: cond.false: +; CHECK-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) +; CHECK-NEXT: br label [[COND_END]] +; CHECK: cond.end: +; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ] +; CHECK-NEXT: br label [[RETURN]] +; CHECK: return: +; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; CHECK-NEXT: ret i32 [[RETVAL_0]] ; entry: %cmp = icmp sgt i32 %a, %b @@ -322,7 +284,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:%.*]]) ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone [[R]]) +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[A]], double* noalias nofree noundef readnone [[CALL]]) ; IS__CGSCC____-NEXT: ret double* [[CALL1]] ; @@ -377,14 +339,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]]) +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[B]], double* noalias nofree readnone [[A]], double* noalias nofree noundef readnone [[CALL]]) ; 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 noundef double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nocapture nofree readnone undef) ; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call noundef double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]]) ; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call noundef double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree noundef readnone [[CALL6]], double* noalias nocapture nofree readnone undef) @@ -1354,35 +1316,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 1) -; NOT_CGSCC_NPM-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 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 1) -; IS__CGSCC_NPM-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 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 1) +; CHECK-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 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) @@ -1433,7 +1380,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_use_const() -; IS__CGSCC____-NEXT: [[C:%.*]] = musttail call nonnull dereferenceable(1) i32* @ret_const() +; IS__CGSCC____-NEXT: [[C:%.*]] = musttail call i32* @ret_const() ; 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 @@ -83,9 +83,9 @@ } define internal i32* @ret_null() { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_null() -; IS__CGSCC____-NEXT: ret i32* null +; IS__CGSCC____-NEXT: unreachable ; ret i32* null } @@ -95,9 +95,13 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@load_null_propagated() ; IS__TUNIT____-NEXT: unreachable ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@load_null_propagated() -; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@load_null_propagated() +; IS__CGSCC_OPM-NEXT: unreachable +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@load_null_propagated() +; IS__CGSCC_NPM-NEXT: unreachable ; %ptr = call i32* @ret_null() %a = load i32, i32* %ptr @@ -169,7 +173,7 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_propagated() ; IS__TUNIT____-NEXT: unreachable ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_propagated() ; IS__CGSCC____-NEXT: unreachable ; @@ -243,7 +247,7 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated() ; IS__TUNIT____-NEXT: unreachable ; -; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated() ; IS__CGSCC____-NEXT: unreachable ; @@ -317,9 +321,13 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated() ; IS__TUNIT____-NEXT: unreachable ; -; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated() -; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC_OPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated() +; IS__CGSCC_OPM-NEXT: unreachable +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated() +; IS__CGSCC_NPM-NEXT: unreachable ; %ptr = call i32* @ret_null() %a = cmpxchg i32* %ptr, i32 2, i32 3 acq_rel monotonic @@ -554,7 +562,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 @@ -228,7 +228,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2i() ; 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 ; @@ -247,8 +247,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2() -; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @ipccp2i() -; IS__CGSCC____-NEXT: ret i1 [[R]] +; IS__CGSCC____-NEXT: ret i1 true ; %r = call i1 @ipccp2i(i1 true) ret i1 %r @@ -259,7 +258,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2ib() ; 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 ; @@ -289,7 +288,7 @@ ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp3i() ; 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 ; @@ -309,8 +308,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp3() -; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @ipccp3i() -; IS__CGSCC____-NEXT: ret i32 [[R]] +; IS__CGSCC____-NEXT: ret i32 7 ; %r = call i32 @ipccp3i(i32 7) ret i32 %r @@ -463,7 +461,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:%.*]]) +; IS__CGSCC_NPM-SAME: (i8* noalias nocapture nofree readnone [[TMP0:%.*]]) ; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** ; IS__CGSCC_NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8 @@ -653,8 +651,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller0() -; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee() -; IS__CGSCC____-NEXT: ret i8 [[C]] +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -667,8 +664,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller1() -; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee() -; IS__CGSCC____-NEXT: ret i8 [[C]] +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -681,8 +677,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2() -; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee() -; IS__CGSCC____-NEXT: ret i8 [[C]] +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -695,8 +690,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller_middle() -; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee() -; IS__CGSCC____-NEXT: ret i8 [[C]] +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 42) ret i8 %c @@ -709,8 +703,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller3() -; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee() -; IS__CGSCC____-NEXT: ret i8 [[C]] +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -723,8 +716,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller4() -; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee() -; IS__CGSCC____-NEXT: ret i8 [[C]] +; IS__CGSCC____-NEXT: ret i8 49 ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -737,8 +729,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@callee() -; IS__CGSCC____-NEXT: [[C:%.*]] = add i8 42, 7 -; IS__CGSCC____-NEXT: ret i8 [[C]] +; IS__CGSCC____-NEXT: ret i8 undef ; %c = add i8 %a, 7 ret i8 %c