From e87f10a771f958def2f9bbdd0d572fc86aee1410 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Tue, 12 Apr 2022 16:24:37 -0500 Subject: [PATCH] [Attributor] CGSCC pass should not recompute results outside the SCC (reapply) When we run the CGSCC pass we should only invest time on the SCC. We can initialize AAs with information from the module slice but we should not update those AAs. We make an exception for are call site of the SCC as they are helpful providing information for the SCC. Minor modifications to pointer privatization allow us to perform it even in the CGSCC pass, similar to ArgumentPromotion. --- llvm/include/llvm/Transforms/IPO/Attributor.h | 24 +- .../Transforms/IPO/AttributorAttributes.cpp | 29 +- .../2008-02-01-ReturnAttrs.ll | 41 +- .../2008-07-02-array-indexing.ll | 9 +- .../ArgumentPromotion/2008-09-07-CGUpdate.ll | 21 +- .../ArgumentPromotion/X86/attributes.ll | 3 +- .../X86/min-legal-vector-width.ll | 18 +- .../ArgumentPromotion/aggregate-promote.ll | 23 +- .../Attributor/ArgumentPromotion/alignment.ll | 124 +- .../Attributor/ArgumentPromotion/attrs.ll | 22 +- .../Attributor/ArgumentPromotion/basictest.ll | 73 +- .../Attributor/ArgumentPromotion/byval-2.ll | 20 +- .../Attributor/ArgumentPromotion/byval.ll | 19 +- .../Attributor/ArgumentPromotion/chained.ll | 23 +- .../ArgumentPromotion/control-flow.ll | 22 +- .../ArgumentPromotion/control-flow2.ll | 59 +- .../Attributor/ArgumentPromotion/crash.ll | 39 +- .../Attributor/ArgumentPromotion/fp80.ll | 4 +- .../Attributor/ArgumentPromotion/inalloca.ll | 57 +- .../live_called_from_dead.ll | 13 +- .../live_called_from_dead_2.ll | 9 +- .../Attributor/ArgumentPromotion/musttail.ll | 127 +- .../Attributor/ArgumentPromotion/pr32917.ll | 31 +- .../Attributor/ArgumentPromotion/profile.ll | 40 +- .../ArgumentPromotion/reserve-tbaa.ll | 36 +- .../Attributor/ArgumentPromotion/sret.ll | 54 +- .../IPConstantProp/2008-06-09-WeakProp.ll | 25 +- .../IPConstantProp/2009-09-24-byval-ptr.ll | 3 +- .../Attributor/IPConstantProp/PR16052.ll | 61 +- .../Attributor/IPConstantProp/PR26044.ll | 11 +- .../Attributor/IPConstantProp/PR43857.ll | 23 +- .../IPConstantProp/arg-count-mismatch.ll | 8 +- .../Attributor/IPConstantProp/comdat-ipo.ll | 28 +- .../IPConstantProp/multiple_callbacks.ll | 21 +- .../IPConstantProp/musttail-call.ll | 46 +- .../IPConstantProp/openmp_parallel_for.ll | 41 +- .../Attributor/IPConstantProp/pthreads.ll | 2 +- .../Attributor/IPConstantProp/recursion.ll | 5 +- .../IPConstantProp/remove-call-inst.ll | 20 +- .../IPConstantProp/return-argument.ll | 67 +- .../IPConstantProp/return-constant.ll | 55 +- .../IPConstantProp/return-constants.ll | 59 +- ...fter-each-resolving-undefs-for-function.ll | 30 +- .../IPConstantProp/thread_local_acs.ll | 2 +- llvm/test/Transforms/Attributor/align.ll | 946 +++++----- .../Transforms/Attributor/alwaysinline.ll | 94 +- .../Transforms/Attributor/assumes_info.ll | 76 +- llvm/test/Transforms/Attributor/callbacks.ll | 268 +-- .../Attributor/cb_liveness_disabled.ll | 125 +- .../Attributor/cb_liveness_enabled.ll | 125 +- .../Attributor/cb_range_disabled.ll | 126 +- .../Transforms/Attributor/cb_range_enabled.ll | 105 +- .../Attributor/dereferenceable-1.ll | 54 +- .../Transforms/Attributor/internal-noalias.ll | 119 +- llvm/test/Transforms/Attributor/liveness.ll | 50 +- .../Transforms/Attributor/memory_locations.ll | 241 ++- llvm/test/Transforms/Attributor/noalias.ll | 273 +-- .../test/Transforms/Attributor/nocapture-1.ll | 583 ++++--- .../test/Transforms/Attributor/nocapture-2.ll | 157 +- llvm/test/Transforms/Attributor/nodelete.ll | 19 +- llvm/test/Transforms/Attributor/nofree.ll | 16 +- llvm/test/Transforms/Attributor/nonnull.ll | 251 ++- llvm/test/Transforms/Attributor/norecurse.ll | 16 +- llvm/test/Transforms/Attributor/noreturn.ll | 90 +- llvm/test/Transforms/Attributor/nounwind.ll | 10 +- .../Transforms/Attributor/openmp_parallel.ll | 381 ++-- llvm/test/Transforms/Attributor/potential.ll | 563 ++++-- llvm/test/Transforms/Attributor/range.ll | 1542 ++++++++++++----- .../read_write_returned_arguments_scc.ll | 63 +- llvm/test/Transforms/Attributor/readattrs.ll | 186 +- llvm/test/Transforms/Attributor/returned.ll | 698 +++++--- .../Attributor/undefined_behavior.ll | 552 ++++-- .../Attributor/value-simplify-assume.ll | 1132 ++++++++---- .../Attributor/value-simplify-gpu.ll | 195 +-- .../Attributor/value-simplify-instances.ll | 197 ++- .../Attributor/value-simplify-pointer-info.ll | 1470 ++++++++++------ .../Transforms/Attributor/value-simplify.ll | 835 ++++++--- llvm/test/Transforms/Attributor/willreturn.ll | 364 ++-- llvm/test/Transforms/OpenMP/icv_tracking.ll | 3 +- 79 files changed, 8757 insertions(+), 4615 deletions(-) diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index a3109bcb5863..b786554aa486 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -1359,10 +1359,13 @@ struct Attributor { // For now we ignore naked and optnone functions. bool Invalidate = Configuration.Allowed && !Configuration.Allowed->count(&AAType::ID); - const Function *FnScope = IRP.getAnchorScope(); - if (FnScope) - Invalidate |= FnScope->hasFnAttribute(Attribute::Naked) || - FnScope->hasFnAttribute(Attribute::OptimizeNone); + const Function *AnchorFn = IRP.getAnchorScope(); + if (AnchorFn) { + Invalidate |= + AnchorFn->hasFnAttribute(Attribute::Naked) || + AnchorFn->hasFnAttribute(Attribute::OptimizeNone) || + (!isModulePass() && !getInfoCache().isInModuleSlice(*AnchorFn)); + } // Avoid too many nested initializations to prevent a stack overflow. Invalidate |= InitializationChainLength > MaxInitializationChainLength; @@ -1382,13 +1385,12 @@ struct Attributor { --InitializationChainLength; } - // Initialize and update is allowed for code outside of the current function - // set, but only if it is part of module slice we are allowed to look at. - if (FnScope && !Functions.count(const_cast(FnScope))) { - if (!getInfoCache().isInModuleSlice(*FnScope)) { - AA.getState().indicatePessimisticFixpoint(); - return AA; - } + // We update only AAs associated with functions in the Functions set or + // call sites of them. + if ((AnchorFn && !Functions.count(const_cast(AnchorFn))) && + !Functions.count(IRP.getAssociatedFunction())) { + AA.getState().indicatePessimisticFixpoint(); + return AA; } // If this is queried in the manifest stage, we force the AA to indicate diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index b8f3e124eb02..b6196d717c61 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -43,7 +43,7 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/NoFolder.h" #include "llvm/IR/Value.h" -#include "llvm/IR/ValueHandle.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/Support/Alignment.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" @@ -3289,14 +3289,20 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl { return false; } + auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) { + const auto &DerefAA = A.getAAFor( + *this, IRPosition::value(*O), DepClassTy::OPTIONAL); + return DerefAA.getAssumedDereferenceableBytes(); + }; + A.recordDependence(NoAliasAA, *this, DepClassTy::OPTIONAL); const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); const Function *ScopeFn = VIRP.getAnchorScope(); auto &NoCaptureAA = A.getAAFor(*this, VIRP, DepClassTy::NONE); // Check whether the value is captured in the scope using AANoCapture. - // Look at CFG and check only uses possibly executed before this - // callsite. + // Look at CFG and check only uses possibly executed before this + // callsite. auto UsePred = [&](const Use &U, bool &Follow) -> bool { Instruction *UserI = cast(U.getUser()); @@ -3326,15 +3332,20 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl { return true; } - // For cases which can potentially have more users - if (isa(U) || isa(U) || isa(U) || - isa(U)) { + // TODO: We should track the capturing uses in AANoCapture but the problem + // is CGSCC runs. For those we would need to "allow" AANoCapture for + // a value in the module slice. + switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) { + case UseCaptureKind::NO_CAPTURE: + return true; + case UseCaptureKind::MAY_CAPTURE: + LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI + << "\n"); + return false; + case UseCaptureKind::PASSTHROUGH: Follow = true; return true; } - - LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *U << "\n"); - return false; }; if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) { diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll index 1b346ab8502f..5212a5c63245 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll @@ -27,14 +27,14 @@ entry: } define i32 @f(i32 %x) { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@f -; IS________OPM-SAME: (i32 [[X:%.*]]) #[[ATTR1:[0-9]+]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 -; IS________OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X_ADDR]]) #[[ATTR2:[0-9]+]] -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X_ADDR]]) #[[ATTR2:[0-9]+]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f @@ -46,13 +46,23 @@ define i32 @f(i32 %x) { ; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[TMP0]]) #[[ATTR2:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP1]] ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X_ADDR]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f -; IS__CGSCC_NPM-SAME: (i32 returned [[X:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) #[[ATTR1:[0-9]+]] { ; 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: ret i32 [[X]] +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[X]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP1]] ; entry: %x_addr = alloca i32 @@ -65,10 +75,7 @@ entry: ; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readonly willreturn } ;. -; IS__CGSCC_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nounwind readonly willreturn } -;. -; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nounwind readonly willreturn } ;. 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 index 4585c2437306..fce455cf4a31 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll @@ -44,10 +44,10 @@ define i32 @foo(i32* %A) { ; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree readonly align 4 [[A]]) #[[ATTR1:[0-9]+]] ; IS__TUNIT____-NEXT: ret i32 [[X]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR0]] { -; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]]) #[[ATTR1:[0-9]+]] +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 [[X]] ; %X = call i32 @callee(i1 false, i32* %A) ; [#uses=1] @@ -59,5 +59,6 @@ define i32 @foo(i32* %A) { ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readonly willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { readonly willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll index dd21bd2bb1d9..e62a186a729a 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll @@ -16,16 +16,25 @@ entry: } define void @encode(i32* %m, i32* %ts, i32* %new) nounwind { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@encode -; CHECK-SAME: (i32* nocapture nofree readnone [[M:%.*]], i32* nocapture nofree readnone [[TS:%.*]], i32* nocapture nofree readnone [[NEW:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@encode +; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[M:%.*]], i32* nocapture nofree readnone [[TS:%.*]], i32* nocapture nofree readnone [[NEW:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@encode +; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[M:%.*]], i32* nocapture nofree readnone [[TS:%.*]], i32* nocapture nofree readnone [[NEW:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: unreachable ; entry: %0 = call fastcc i32 @hash( i32* %ts, i32 0 ) nounwind ; [#uses=0] unreachable } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noreturn nosync nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll index 1cb9fa7cd95b..14605c1d9e65 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll @@ -171,7 +171,8 @@ define void @promote(<4 x i64>* %arg) #0 { ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR3]] ; 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]]) #[[ATTR4]] -; IS__CGSCC_NPM-NEXT: store <4 x i64> [[TMP0]], <4 x i64>* [[ARG]], align 2 +; 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 ; bb: 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 index 10db34f70e49..718ae4afb107 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll @@ -87,7 +87,8 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR6:[0-9]+]] ; 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]]) #[[ATTR7:[0-9]+]] -; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG]], align 2 +; 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 ; bb: @@ -180,7 +181,8 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR6]] ; 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]]) #[[ATTR7]] -; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG]], align 2 +; 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 ; bb: @@ -273,7 +275,8 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR6]] ; 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]]) #[[ATTR7]] -; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG]], align 2 +; 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 ; bb: @@ -366,7 +369,8 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>* ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR6]] ; 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]]) #[[ATTR7]] -; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG]], align 2 +; 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 ; bb: @@ -639,7 +643,8 @@ define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>* %ar ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR6]] ; 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]]) #[[ATTR7]] -; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG]], align 2 +; 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 ; bb: @@ -732,7 +737,8 @@ define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>* %ar ; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[TMP3]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR6]] ; 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]]) #[[ATTR7]] -; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG]], align 2 +; 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 ; bb: diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll index 648319d998d9..9ef8a2eddbcc 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll @@ -27,16 +27,27 @@ entry: } define i32 @caller() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller -; CHECK-SAME: () #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i32 42 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller +; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i32 42 +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller +; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[V:%.*]] = call noundef i32 @test() #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[V]] ; entry: %v = call i32 @test(%T* @G) ret i32 %v } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll index f7b17fc796c5..218ab83b01b6 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll @@ -10,11 +10,16 @@ define void @f() { ; IS__TUNIT____-NEXT: call void @g() ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____-LABEL: define {{[^@]+}}@f() { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 1 -; IS__CGSCC____-NEXT: call void @g() -; IS__CGSCC____-NEXT: ret void +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f() { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 1 +; IS__CGSCC_OPM-NEXT: call void @g(i32* noalias nocapture nofree noundef nonnull readonly dereferenceable(4) [[A]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f() { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: call void @g(i32 undef) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %a = alloca i32, align 1 @@ -23,9 +28,23 @@ entry: } define internal void @g(i32* %a) { -; CHECK-LABEL: define {{[^@]+}}@g() { -; CHECK-NEXT: call void @z(i32 undef) -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@g() { +; IS__TUNIT____-NEXT: call void @z(i32 undef) +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly dereferenceable(4) [[A:%.*]]) { +; IS__CGSCC_OPM-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1 +; IS__CGSCC_OPM-NEXT: call void @z(i32 [[AA]]) +; IS__CGSCC_OPM-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 1 +; 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) @@ -37,14 +56,35 @@ declare void @z(i32) ; Test2 ; Different alignemnt privatizable arguments define internal i32 @test(i32* %X, i64* %Y) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@test -; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { -; IS__CGSCC____-NEXT: br label [[RETURN1:%.*]] -; IS__CGSCC____: Return1: -; IS__CGSCC____-NEXT: ret i32 3 -; IS__CGSCC____: Return2: -; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i64* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[Y:%.*]]) #[[ATTR0:[0-9]+]] { +; 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: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i64 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[Y_PRIV:%.*]] = alloca i64, align 8 +; IS__CGSCC_NPM-NEXT: store i64 [[TMP0]], i64* [[Y_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = load i32, i32* [[X]], 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 @@ -59,11 +99,21 @@ Return2: } define internal i32 @caller(i32* %A) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@caller -; IS__CGSCC____-SAME: () #[[ATTR0]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i64, align 8 -; IS__CGSCC____-NEXT: ret i32 3 +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i64, align 8 +; IS__CGSCC_OPM-NEXT: store i64 1, i64* [[B]], align 8 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i64* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { +; 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: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_PRIV]], i64 noundef 1) #[[ATTR3:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] ; %B = alloca i64 store i64 1, i64* %B @@ -72,11 +122,25 @@ define internal i32 @caller(i32* %A) { } define i32 @callercaller() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@callercaller -; CHECK-SAME: () #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 -; CHECK-NEXT: ret i32 3 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@callercaller +; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__TUNIT____-NEXT: ret i32 3 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callercaller +; IS__CGSCC_OPM-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 2, i32* [[B]], align 4 +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR4:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callercaller +; IS__CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 noundef 2) #[[ATTR4:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32 [[X]] ; %B = alloca i32 store i32 2, i32* %B @@ -84,5 +148,11 @@ define i32 @callercaller() { ret i32 %X } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3:[0-9]+]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR4:[0-9]+]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll index 2f84bc577ec7..49dbc04cf813 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll @@ -85,25 +85,28 @@ define i32 @test(i32* %X) { ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]]) #[[ATTR1:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret i32 [[C]] ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0]] { +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 ; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 ; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8 ; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_SS]]) align 8 dereferenceable(12) [[S]], i32* noalias nocapture nofree noundef nonnull readonly byval(i32) align 4 dereferenceable(4) [[X]]) #[[ATTR1:[0-9]+]] +; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_SS]]) align 8 dereferenceable(12) [[S]], i32* noalias nocapture nofree noundef nonnull readonly byval(i32) align 4 dereferenceable(4) [[X]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i32 [[C]] ; -; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0]] { +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; IS__CGSCC_NPM-NEXT: ret i32 2 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X]], align 4 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 noundef 1, i64 noundef 2, i32 [[TMP0]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] ; entry: %S = alloca %struct.ss @@ -120,8 +123,7 @@ entry: ; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn } ; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn } ;. -; IS__CGSCC_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nounwind willreturn } -;. -; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll index 498f0d04e2b5..ba1e3668403b 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll @@ -6,10 +6,23 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define internal i32 @test(i32* %X, i32* %Y) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@test -; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { -; IS__CGSCC____-NEXT: ret i32 3 +; 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* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[Y:%.*]]) #[[ATTR0:[0-9]+]] { +; 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: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[Y:%.*]]) #[[ATTR0:[0-9]+]] { +; 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]], 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 @@ -18,11 +31,21 @@ define internal i32 @test(i32* %X, i32* %Y) { } define internal i32 @caller(i32* %B) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@caller -; IS__CGSCC____-SAME: () #[[ATTR0]] { -; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: ret i32 3 +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[A]], align 4 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { +; 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: [[C:%.*]] = call i32 @test(i32 noundef 1, i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B_PRIV]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32 [[C]] ; %A = alloca i32 store i32 1, i32* %A @@ -31,11 +54,25 @@ define internal i32 @caller(i32* %B) { } define i32 @callercaller() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@callercaller -; CHECK-SAME: () #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 -; CHECK-NEXT: ret i32 3 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@callercaller +; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__TUNIT____-NEXT: ret i32 3 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callercaller +; IS__CGSCC_OPM-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 2, i32* [[B]], align 4 +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR4:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callercaller +; IS__CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 noundef 2) #[[ATTR4:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32 [[X]] ; %B = alloca i32 store i32 2, i32* %B @@ -44,5 +81,11 @@ define i32 @callercaller() { } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3:[0-9]+]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR4:[0-9]+]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll index 40230f7fd8d6..463b3656d567 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll @@ -75,24 +75,27 @@ define i32 @test(i32* %X) { ; IS__TUNIT_NPM-NEXT: call void @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]]) #[[ATTR1:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret i32 0 ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0]] { +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 ; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 ; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8 ; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; IS__CGSCC_OPM-NEXT: call void @f(%struct.ss* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_SS]]) align 8 dereferenceable(12) [[S]], i32* noalias nocapture nofree noundef nonnull readonly byval(i32) align 4 dereferenceable(4) [[X]]) #[[ATTR1:[0-9]+]] +; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4 +; IS__CGSCC_OPM-NEXT: call void @f(%struct.ss* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_SS]]) align 8 dereferenceable(12) [[S]], i32* noalias nocapture nofree noundef nonnull readonly byval(i32) align 4 dereferenceable(4) [[X]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i32 0 ; -; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0]] { +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X]], align 4 +; IS__CGSCC_NPM-NEXT: call void @f(i32 noundef 1, i64 noundef 2, i32 [[TMP0]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret i32 0 ; entry: @@ -108,8 +111,7 @@ entry: ; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn } ; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn } ;. -; IS__CGSCC_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nounwind willreturn } -;. -; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll index 8610e4a63401..ecec7776754f 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll @@ -113,7 +113,7 @@ define i32 @main() nounwind { ; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] ; IS__TUNIT_NPM-NEXT: ret i32 [[A]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@main ; IS__CGSCC_OPM-SAME: () #[[ATTR1:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: @@ -121,19 +121,23 @@ define i32 @main() nounwind { ; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 ; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 32 ; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4 ; IS__CGSCC_OPM-NEXT: [[C0:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_SS]]) align 32 dereferenceable(12) [[S]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = call i32 @g(%struct.ss* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_SS]]) align 32 dereferenceable(12) [[S]]) #[[ATTR2]] ; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] ; IS__CGSCC_OPM-NEXT: ret i32 [[A]] ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@main ; IS__CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; IS__CGSCC_NPM-NEXT: ret i32 3 +; IS__CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 noundef 1, i64 noundef 2) #[[ATTR2:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 noundef 1, i64 noundef 2) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]] +; IS__CGSCC_NPM-NEXT: ret i32 [[A]] ; entry: %S = alloca %struct.ss @@ -153,10 +157,7 @@ entry: ; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind willreturn } ;. -; IS__CGSCC_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nounwind willreturn } -;. -; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll index d55ea9e3786a..6c617e914190 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll @@ -26,11 +26,18 @@ entry: } define i32 @caller() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller -; CHECK-SAME: () #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller +; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller +; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[X:%.*]] = call noundef i32 @test() #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[X]] ; entry: %x = call i32 @test(i32** @G2) @@ -38,5 +45,9 @@ entry: } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll index a22fbb66e0c5..5e01c3b28ad3 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll @@ -29,12 +29,19 @@ F: } define i32 @foo(i1 %C, i32* %P) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 [[C]], i32* nocapture nofree readonly [[P]]) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: ret i32 [[X]] +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @callee(i1 [[C]], i32* nocapture nofree readonly [[P]]) #[[ATTR1:[0-9]+]] +; IS__TUNIT____-NEXT: ret i32 [[X]] +; +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @callee(i1 [[C]], i32* nocapture nofree readonly [[P]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[X]] ; entry: %X = call i32 @callee(i1 %C, i32* %P) @@ -46,5 +53,6 @@ entry: ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readonly willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { readonly willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll index a6a25219b38c..112f70c824d4 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll @@ -7,14 +7,27 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" define internal i32 @callee(i1 %C, i32* %P) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@callee -; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { -; IS__CGSCC____-NEXT: br label [[F:%.*]] -; IS__CGSCC____: T: -; IS__CGSCC____-NEXT: unreachable -; IS__CGSCC____: F: -; IS__CGSCC____-NEXT: ret i32 17 +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0:[0-9]+]] { +; 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: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callee +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { +; 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 @@ -27,11 +40,25 @@ F: ; preds = %0 } define i32 @foo() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: () #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 -; CHECK-NEXT: ret i32 17 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo +; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__TUNIT____-NEXT: ret i32 17 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo +; IS__CGSCC_OPM-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 17, i32* [[A]], align 4 +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = call i32 @callee(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32 [[X]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo +; IS__CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @callee(i32 noundef 17) #[[ATTR2:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32 [[X]] ; %A = alloca i32 ; [#uses=2] store i32 17, i32* %A @@ -40,5 +67,9 @@ define i32 @foo() { } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { readonly willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll index 096992eb9eb1..2e22611fcea6 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll @@ -20,11 +20,11 @@ define void @zot() personality i32 (...)* @wibble { ; IS__TUNIT____: bb2: ; IS__TUNIT____-NEXT: unreachable ; -; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@zot ; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] personality i32 (...)* @wibble { ; IS__CGSCC____-NEXT: bb: -; IS__CGSCC____-NEXT: call void @hoge() #[[ATTR3:[0-9]+]] +; IS__CGSCC____-NEXT: call void @hoge() #[[ATTR4:[0-9]+]] ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: bb1: ; IS__CGSCC____-NEXT: unreachable @@ -45,11 +45,17 @@ bb2: } define internal void @hoge() { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@hoge -; CHECK-SAME: () #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: bb: -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@hoge +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: bb: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@hoge +; IS__CGSCC____-SAME: () #[[ATTR0]] { +; IS__CGSCC____-NEXT: bb: +; IS__CGSCC____-NEXT: unreachable ; bb: %tmp = call fastcc i8* @spam(i1 (i8*)* @eggs) @@ -60,7 +66,7 @@ bb: define internal fastcc i8* @spam(i1 (i8*)* %arg) { ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@spam -; IS__CGSCC____-SAME: () #[[ATTR0]] { +; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { ; IS__CGSCC____-NEXT: bb: ; IS__CGSCC____-NEXT: unreachable ; @@ -83,7 +89,7 @@ bb: define internal i1 @barney(i8* %arg) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@barney -; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { ; IS__CGSCC____-NEXT: bb: ; IS__CGSCC____-NEXT: ret i1 undef ; @@ -98,9 +104,9 @@ define i32 @test_inf_promote_caller(i32 %arg) { ; IS__TUNIT____-NEXT: bb: ; IS__TUNIT____-NEXT: ret i32 0 ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inf_promote_caller -; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR3:[0-9]+]] { ; IS__CGSCC____-NEXT: bb: ; IS__CGSCC____-NEXT: [[TMP:%.*]] = alloca [[S:%.*]], align 8 ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = alloca [[S]], align 8 @@ -117,7 +123,7 @@ bb: define internal i32 @test_inf_promote_callee(%S* %arg, %S* %arg1) { ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inf_promote_callee -; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-SAME: () #[[ATTR3]] { ; IS__CGSCC____-NEXT: bb: ; IS__CGSCC____-NEXT: ret i32 undef ; @@ -137,8 +143,9 @@ declare i32 @wibble(...) ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR2]] = { noreturn nounwind readnone } ;. -; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR3]] = { noreturn nounwind readnone } +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR4]] = { noreturn nounwind readnone } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll index 349be1809464..1f4efd6a7190 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll @@ -28,7 +28,7 @@ define void @run() { ; NOT_CGSCC_NPM-NEXT: entry: ; NOT_CGSCC_NPM-NEXT: unreachable ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@run ; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: @@ -124,7 +124,7 @@ loop: ;. ; NOT_CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ;. -; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nosync nounwind readonly willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll index 3f9583674d0e..841a0de5be3d 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll @@ -31,17 +31,29 @@ entry: } define i32 @main() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@main -; CHECK-SAME: () #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]], align 4 -; CHECK-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 -; CHECK-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 -; CHECK-NEXT: store i32 1, i32* [[F0]], align 4 -; CHECK-NEXT: store i32 2, i32* [[F1]], align 4 -; CHECK-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull inalloca([[STRUCT_SS]]) align 4 dereferenceable(8) [[S]]) #[[ATTR2:[0-9]+]] -; CHECK-NEXT: ret i32 [[R]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@main +; IS__TUNIT____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]], align 4 +; IS__TUNIT____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 +; IS__TUNIT____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 +; IS__TUNIT____-NEXT: store i32 1, i32* [[F0]], align 4 +; IS__TUNIT____-NEXT: store i32 2, i32* [[F1]], align 4 +; IS__TUNIT____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull inalloca([[STRUCT_SS]]) align 4 dereferenceable(8) [[S]]) #[[ATTR2:[0-9]+]] +; IS__TUNIT____-NEXT: ret i32 [[R]] +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@main +; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]], align 4 +; 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 +; IS__CGSCC____-NEXT: store i32 1, i32* [[F0]], align 4 +; IS__CGSCC____-NEXT: store i32 2, i32* [[F1]], align 4 +; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull inalloca([[STRUCT_SS]]) align 4 dereferenceable(8) [[S]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: %S = alloca inalloca %struct.ss @@ -57,7 +69,7 @@ entry: define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca(%struct.ss) %b) nounwind { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@g -; IS__CGSCC____-SAME: (%struct.ss* noalias nocapture nofree nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* noalias nocapture nofree nonnull writeonly inalloca([[STRUCT_SS:%.*]]) align 4 dereferenceable(8) [[B:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-SAME: (%struct.ss* noalias nocapture nofree nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* noalias nocapture nofree nonnull writeonly inalloca([[STRUCT_SS:%.*]]) align 4 dereferenceable(8) [[B:%.*]]) #[[ATTR2:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: ret i1 undef ; @@ -67,11 +79,17 @@ entry: } define i32 @test() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@test -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test +; IS__CGSCC____-SAME: () #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i32 0 ; entry: %S = alloca inalloca %struct.ss @@ -84,6 +102,7 @@ entry: ; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind readonly willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { readonly willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll index 36fcb456845f..14b0a6f55574 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll @@ -40,7 +40,7 @@ define internal i32 @caller(i32* %B) { ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller ; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { ; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR3:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 0 ; %A = alloca i32 @@ -56,11 +56,12 @@ define i32 @callercaller() { ; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32, align 4 ; IS__TUNIT____-NEXT: ret i32 0 ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller -; IS__CGSCC____-SAME: () #[[ATTR1]] { +; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { ; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: ret i32 0 +; IS__CGSCC____-NEXT: [[X:%.*]] = call noundef i32 @caller() #[[ATTR4:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[X]] ; %B = alloca i32 store i32 2, i32* %B @@ -73,5 +74,7 @@ define i32 @callercaller() { ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR4]] = { readnone willreturn } ;. 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 index b9ac40c71c04..b2efc9e89bfb 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll @@ -64,12 +64,13 @@ define i32 @callercaller() { ; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR2]] ; IS__TUNIT____-NEXT: ret i32 0 ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller ; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { ; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR3:[0-9]+]] -; IS__CGSCC____-NEXT: ret i32 0 +; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: [[X:%.*]] = call noundef i32 @caller(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[X]] ; %B = alloca i32 store i32 2, i32* %B @@ -83,7 +84,7 @@ define i32 @callercaller() { ; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll index 2389bb69d53c..2be05748ad10 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll @@ -29,11 +29,17 @@ define internal i32 @test(%T* %p) { } define i32 @caller(%T* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; CHECK-LABEL: define {{[^@]+}}@caller -; CHECK-SAME: (%T* nocapture nofree readonly [[P:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[V:%.*]] = musttail call i32 @test(%T* nocapture nofree readonly [[P]]) #[[ATTR4:[0-9]+]] -; CHECK-NEXT: ret i32 [[V]] +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller +; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[P:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[V:%.*]] = musttail call i32 @test(%T* nocapture nofree readonly [[P]]) #[[ATTR4:[0-9]+]] +; IS__TUNIT____-NEXT: ret i32 [[V]] +; +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[V:%.*]] = musttail call i32 @test(%T* nocapture nofree readonly [[P]]) #[[ATTR5:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[V]] ; %v = musttail call i32 @test(%T* %p) ret i32 %v @@ -42,19 +48,30 @@ define i32 @caller(%T* %p) { ; Don't promote arguments of musttail caller define i32 @foo(%T* %p, i32 %v) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: (%T* nocapture nofree readnone [[P:%.*]], i32 [[V:%.*]]) #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo +; IS__TUNIT____-SAME: (%T* nocapture nofree readnone [[P:%.*]], i32 [[V:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo +; IS__CGSCC____-SAME: (%T* nocapture nofree readnone [[P:%.*]], i32 [[V:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-NEXT: ret i32 0 ; ret i32 0 } define internal i32 @test2(%T* %p, i32 %p2) { -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test2 -; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) #[[ATTR0]] { -; IS__CGSCC____-NEXT: ret i32 0 +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 +; IS__CGSCC____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2 +; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 +; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 +; IS__CGSCC____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noundef i32 @foo(%T* undef, i32 [[V]]) #[[ATTR6:[0-9]+]] +; 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 @@ -66,10 +83,16 @@ define internal i32 @test2(%T* %p, i32 %p2) { } define i32 @caller2(%T* %g) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller2 -; CHECK-SAME: (%T* nocapture nofree readnone [[G:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2 +; IS__TUNIT____-SAME: (%T* nocapture nofree readnone [[G:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2 +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly align 4 [[G:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[V:%.*]] = call noundef i32 @test2(%T* nocapture nofree readonly [[G]], i32 noundef 0) #[[ATTR5]] +; IS__CGSCC____-NEXT: ret i32 [[V]] ; %v = call i32 @test2(%T* %g, i32 0) ret i32 %v @@ -80,12 +103,19 @@ define i32 @caller2(%T* %g) { ; is kept as well. define i32 @bar(%T* %p, i32 %v) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@bar -; CHECK-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR2:[0-9]+]] { -; CHECK-NEXT: [[I32PTR:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 0 -; CHECK-NEXT: store i32 [[V]], i32* [[I32PTR]], align 4 -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@bar +; IS__TUNIT____-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__TUNIT____-NEXT: [[I32PTR:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 0 +; IS__TUNIT____-NEXT: store i32 [[V]], i32* [[I32PTR]], align 4 +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@bar +; IS__CGSCC____-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-NEXT: [[I32PTR:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 0 +; IS__CGSCC____-NEXT: store i32 [[V]], i32* [[I32PTR]], align 4 +; IS__CGSCC____-NEXT: ret i32 0 ; %i32ptr = getelementptr %T, %T* %p, i64 0, i32 0 store i32 %v, i32* %i32ptr @@ -93,16 +123,27 @@ define i32 @bar(%T* %p, i32 %v) { } define internal i32 @test2b(%T* %p, i32 %p2) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@test2b -; CHECK-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 -; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2 -; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 -; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 -; CHECK-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] -; CHECK-NEXT: [[CA:%.*]] = musttail call i32 @bar(%T* undef, i32 [[V]]) #[[ATTR5:[0-9]+]] -; CHECK-NEXT: ret i32 [[CA]] +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2b +; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 +; IS__TUNIT____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2 +; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 +; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 +; IS__TUNIT____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] +; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i32 @bar(%T* undef, i32 [[V]]) #[[ATTR5:[0-9]+]] +; IS__TUNIT____-NEXT: ret i32 [[CA]] +; +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2b +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 +; IS__CGSCC____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2 +; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 +; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 +; IS__CGSCC____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noundef i32 @bar(%T* undef, i32 [[V]]) #[[ATTR7:[0-9]+]] +; 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 @@ -120,11 +161,11 @@ define i32 @caller2b(%T* %g) { ; IS__TUNIT____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 undef) #[[ATTR6:[0-9]+]] ; IS__TUNIT____-NEXT: ret i32 0 ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2b -; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[G:%.*]]) #[[ATTR3]] { -; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 noundef 0) #[[ATTR6:[0-9]+]] -; IS__CGSCC____-NEXT: ret i32 0 +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly align 4 [[G:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: [[V:%.*]] = call noundef i32 @test2b(%T* nocapture nofree readonly [[G]], i32 noundef 0) #[[ATTR8:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[V]] ; %v = call i32 @test2b(%T* %g, i32 0) ret i32 %v @@ -139,10 +180,12 @@ define i32 @caller2b(%T* %g) { ; IS__TUNIT____: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR4]] = { readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR5]] = { nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR6]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR5]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR6]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR7]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll index 552c2500265f..913bc6263cbe 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll @@ -22,13 +22,13 @@ define i32 @fn2() local_unnamed_addr { ; IS__TUNIT____-NEXT: call fastcc void @fn1(i32* nocapture nofree readonly align 4 [[TMP3]]) #[[ATTR1:[0-9]+]] ; IS__TUNIT____-NEXT: ret i32 undef ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2 ; IS__CGSCC____-SAME: () local_unnamed_addr #[[ATTR0:[0-9]+]] { ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 ; IS__CGSCC____-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 ; IS__CGSCC____-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32* -; IS__CGSCC____-NEXT: call fastcc void @fn1(i32* nocapture nofree nonnull readonly align 4 [[TMP3]]) #[[ATTR1:[0-9]+]] +; IS__CGSCC____-NEXT: call fastcc void @fn1(i32* nocapture nofree nonnull readonly align 4 [[TMP3]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 undef ; %1 = load i32, i32* @b, align 4 @@ -39,13 +39,21 @@ define i32 @fn2() local_unnamed_addr { } define internal fastcc void @fn1(i32* nocapture readonly) unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@fn1 -; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 [[TMP0:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 -1 -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; CHECK-NEXT: store i32 [[TMP3]], i32* @a, align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn1 +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 [[TMP0:%.*]]) unnamed_addr #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 -1 +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__TUNIT____-NEXT: store i32 [[TMP3]], i32* @a, align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 [[TMP0:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 -1 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: store i32 [[TMP3]], i32* @a, align 4 +; IS__CGSCC____-NEXT: ret void ; %2 = getelementptr inbounds i32, i32* %0, i64 -1 %3 = load i32, i32* %2, align 4 @@ -56,6 +64,7 @@ define internal fastcc void @fn1(i32* nocapture readonly) unnamed_addr { ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn } ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. -; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll index 916f9dc42fd0..583cd5d1f789 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll @@ -8,10 +8,20 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1 ; Checks if !prof metadata is corret in deadargelim. define void @caller() #0 { -; CHECK-LABEL: define {{[^@]+}}@caller() { -; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 -; CHECK-NEXT: call void @promote_i32_ptr(), !prof [[PROF0:![0-9]+]] -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller() { +; IS__TUNIT____-NEXT: [[X:%.*]] = alloca i32, align 4 +; IS__TUNIT____-NEXT: call void @promote_i32_ptr(), !prof [[PROF0:![0-9]+]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller() { +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[X]], align 4 +; IS__CGSCC_OPM-NEXT: call void @promote_i32_ptr(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X]]), !prof [[PROF0:![0-9]+]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller() { +; IS__CGSCC_NPM-NEXT: call void @promote_i32_ptr(i32 noundef 42), !prof [[PROF0:![0-9]+]] +; IS__CGSCC_NPM-NEXT: ret void ; %x = alloca i32 store i32 42, i32* %x @@ -20,9 +30,23 @@ define void @caller() #0 { } define internal void @promote_i32_ptr(i32* %xp) { -; CHECK-LABEL: define {{[^@]+}}@promote_i32_ptr() { -; CHECK-NEXT: call void @use_i32(i32 noundef 42) -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@promote_i32_ptr() { +; IS__TUNIT____-NEXT: call void @use_i32(i32 noundef 42) +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@promote_i32_ptr +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[XP:%.*]]) { +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4 +; IS__CGSCC_OPM-NEXT: call void @use_i32(i32 [[X]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@promote_i32_ptr +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) { +; IS__CGSCC_NPM-NEXT: [[XP_PRIV:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[XP_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[X:%.*]] = load i32, i32* [[XP_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: call void @use_i32(i32 [[X]]) +; IS__CGSCC_NPM-NEXT: ret void ; %x = load i32, i32* %xp call void @use_i32(i32 %x) @@ -33,5 +57,5 @@ declare void @use_i32(i32) !0 = !{!"branch_weights", i32 30} ;. -; CHECK: [[PROF0]] = !{!"branch_weights", i32 30} +; CHECK: [[META0:![0-9]+]] = !{!"branch_weights", i32 30} ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll index 7b83fb6e992d..ffff8d71b3cc 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll @@ -43,16 +43,27 @@ entry: } define i32 @main() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@main -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa [[TBAA5:![0-9]+]] -; CHECK-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa [[TBAA5]] -; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa [[TBAA5]] -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa [[TBAA0]] -; CHECK-NEXT: call fastcc void @fn() #[[ATTR1:[0-9]+]] -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@main +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa [[TBAA5:![0-9]+]] +; IS__TUNIT____-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa [[TBAA5]] +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa [[TBAA5]] +; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa [[TBAA0]] +; IS__TUNIT____-NEXT: call fastcc void @fn() #[[ATTR1:[0-9]+]] +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@main +; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa [[TBAA5:![0-9]+]] +; IS__CGSCC____-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa [[TBAA5]] +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa [[TBAA5]] +; IS__CGSCC____-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa [[TBAA0]] +; IS__CGSCC____-NEXT: call fastcc void @fn() #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 0 ; entry: %0 = load i32**, i32*** @e, align 8, !tbaa !8 @@ -79,13 +90,14 @@ entry: ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind willreturn } ;. ; CHECK: [[TBAA0]] = !{!1, !1, i64 0} ; CHECK: [[META1:![0-9]+]] = !{!"int", !2, i64 0} ; CHECK: [[META2:![0-9]+]] = !{!"omnipotent char", !3, i64 0} ; CHECK: [[META3:![0-9]+]] = !{!"Simple C/C++ TBAA"} ; CHECK: [[TBAA4]] = !{!2, !2, i64 0} -; CHECK: [[TBAA5]] = !{!6, !6, i64 0} +; CHECK: [[META5:![0-9]+]] = !{!6, !6, i64 0} ; CHECK: [[META6:![0-9]+]] = !{!"any pointer", !2, i64 0} ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll index 8a62474a97eb..2b422b513802 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll @@ -9,10 +9,32 @@ target triple = "x86_64-pc-windows-msvc" define internal void @add({i32, i32}* %this, i32* sret(i32) %r) { ; -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@add -; CHECK-SAME: ({ i32, i32 }* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@add +; IS__TUNIT____-SAME: ({ i32, i32 }* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-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 writeonly sret(i32) align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0:[0-9]+]] { +; 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 writeonly sret(i32) align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0:[0-9]+]] { +; 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 @@ -31,10 +53,21 @@ define void @f() { ; IS__TUNIT____-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) undef, i32* noalias nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R]]) #[[ATTR2:[0-9]+]] ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@f -; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { -; IS__CGSCC____-NEXT: ret void +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_OPM-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }, align 8 +; IS__CGSCC_OPM-NEXT: call void @add({ i32, i32 }* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }, align 8 +; IS__CGSCC_NPM-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* noalias nocapture nofree noundef nonnull writeonly sret(i32) align 4 dereferenceable(4) [[R]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret void ; %r = alloca i32 %pair = alloca {i32, i32} @@ -47,6 +80,7 @@ define void @f() { ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } ;. -; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll index 8bcd7a541ce0..418abc334ba1 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll @@ -19,12 +19,19 @@ entry: } define i32 @main() nounwind { -; CHECK: Function Attrs: norecurse nounwind -; CHECK-LABEL: define {{[^@]+}}@main -; CHECK-SAME: () #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[R:%.*]] = call i32 @foo() #[[ATTR0]] -; CHECK-NEXT: ret i32 [[R]] +; IS__TUNIT____: Function Attrs: norecurse nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@main +; IS__TUNIT____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[R:%.*]] = call i32 @foo() #[[ATTR0]] +; IS__TUNIT____-NEXT: ret i32 [[R]] +; +; IS__CGSCC____: Function Attrs: nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@main +; IS__CGSCC____-SAME: () #[[ATTR0]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @foo() #[[ATTR0]] +; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: %r = call i32 @foo( ) nounwind @@ -32,6 +39,8 @@ entry: } ;. -; CHECK: attributes #[[ATTR0]] = { nounwind } -; CHECK: attributes #[[ATTR1]] = { norecurse nounwind } +; IS__TUNIT____: attributes #[[ATTR0]] = { nounwind } +; IS__TUNIT____: attributes #[[ATTR1]] = { norecurse nounwind } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nounwind } ;. 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 index b5db1f0a43b1..c8b82ab60afe 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll @@ -237,7 +237,8 @@ define i32 @unions_v2() nounwind { ; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: call void @vfu1(i8 noundef 0, i32 noundef 0) #[[ATTR0]] -; IS__CGSCC_NPM-NEXT: ret i32 99 +; IS__CGSCC_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 noundef 0, i32 noundef 0) #[[ATTR0]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RESULT]] ; entry: call void @vfu1(%struct.MYstr* byval(%struct.MYstr) align 4 @mystr) nounwind diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll index 5c0cba609ce0..f35a37a3c1a6 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll @@ -9,11 +9,17 @@ target triple = "x86_64-unknown-linux-gnu" define i64 @fn2() { ; -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@fn2 -; CHECK-SAME: () #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i64 poison +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2 +; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i64 poison +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2 +; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i64 poison ; entry: %conv = sext i32 undef to i64 @@ -24,13 +30,21 @@ entry: define i64 @fn2b(i32 %arg) { ; -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@fn2b -; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]] -; CHECK-NEXT: ret i64 [[DIV]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2b +; IS__TUNIT____-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64 +; IS__TUNIT____-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]] +; IS__TUNIT____-NEXT: ret i64 [[DIV]] +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2b +; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64 +; IS__CGSCC____-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]] +; IS__CGSCC____-NEXT: ret i64 [[DIV]] ; entry: %conv = sext i32 %arg to i64 @@ -40,11 +54,17 @@ entry: } define i64 @fn2c() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@fn2c -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i64 42 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2c +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i64 42 +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2c +; IS__CGSCC____-SAME: () #[[ATTR0]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i64 42 ; entry: %conv = sext i32 undef to i64 @@ -56,7 +76,7 @@ entry: define internal i64 @fn1(i64 %p1) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1 -; IS__CGSCC____-SAME: (i64 returned [[P1:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i64 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0 ; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]] @@ -68,5 +88,8 @@ entry: ret i64 %cond } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll index 9a836016dc00..aa8fabb94a5e 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll @@ -23,7 +23,7 @@ define void @fn2(i32* %P, i1 %C) { ; IS__TUNIT____: exit: ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2 ; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: @@ -86,7 +86,7 @@ define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid { ; IS__TUNIT____: exit: ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid +; IS__CGSCC____: Function Attrs: nofree nosync nounwind null_pointer_is_valid ; IS__CGSCC____-LABEL: define {{[^@]+}}@fn_no_null_opt ; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: @@ -95,7 +95,8 @@ define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]] ; IS__CGSCC____: if.end: ; IS__CGSCC____-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ] -; IS__CGSCC____-NEXT: store i32 undef, i32* [[P]], align 4 +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4294967296 +; IS__CGSCC____-NEXT: store i32 [[TMP0]], i32* [[P]], align 4 ; IS__CGSCC____-NEXT: br label [[FOR_COND1]] ; IS__CGSCC____: exit: ; IS__CGSCC____-NEXT: ret void @@ -134,7 +135,7 @@ entry: ; IS__TUNIT____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind } ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid } ;. -; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind } +; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind null_pointer_is_valid } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind null_pointer_is_valid } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll index 83ab5940c733..98e6a29fda28 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll @@ -21,12 +21,18 @@ bb: } define void @baz(<8 x i32> %arg) local_unnamed_addr { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@baz -; CHECK-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr #[[ATTR0]] { -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP1:%.*]] = extractvalue [[STRUCT_ZOT:%.*]] undef, 0, 0 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@baz +; IS__TUNIT____-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr #[[ATTR0]] { +; IS__TUNIT____-NEXT: bb: +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = extractvalue [[STRUCT_ZOT:%.*]] undef, 0, 0 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@baz +; IS__CGSCC____-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: bb: +; IS__CGSCC____-NEXT: ret void ; bb: %tmp = call %struct.zot @widget(<8 x i32> %arg) @@ -34,5 +40,8 @@ bb: ret void } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll index 092334e6ccac..97659802e8b1 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll @@ -126,15 +126,17 @@ define dso_local i16 @vararg_tests(i16 %a) { ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vararg_tests ; IS__CGSCC_OPM-SAME: (i16 [[A:%.*]]) { +; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i16 (i16, ...) @vararg_prop(i16 noundef 7, i16 noundef 8, i16 [[A]]) #[[ATTR1:[0-9]+]] ; 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 7, [[CALL2]] +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i16 [[CALL1]], [[CALL2]] ; IS__CGSCC_OPM-NEXT: ret i16 [[ADD]] ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@vararg_tests ; IS__CGSCC_NPM-SAME: (i16 [[A:%.*]]) #[[ATTR0]] { +; IS__CGSCC_NPM-NEXT: [[CALL1:%.*]] = call i16 (i16, ...) @vararg_prop(i16 noundef 7, i16 noundef 8, i16 [[A]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)* @vararg_no_prop to i16 (i16)*)(i16 7) -; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]] +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add i16 [[CALL1]], [[CALL2]] ; IS__CGSCC_NPM-NEXT: ret i16 [[ADD]] ; %call1 = call i16 (i16, ...) @vararg_prop(i16 7, i16 8, i16 %a) @@ -176,7 +178,9 @@ define internal i16 @vararg_no_prop(i16 %p1, i16 %p2, ...) { ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR1]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind readnone } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR2]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll b/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll index d14ceec9872c..9f9b8135a272 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll @@ -19,8 +19,12 @@ define i32 @baz() { ; constprop @foo's return value into bar. define linkonce_odr i32 @foo() { -; CHECK-LABEL: define {{[^@]+}}@foo() { -; CHECK-NEXT: ret i32 10 +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo() { +; IS__TUNIT____-NEXT: ret i32 10 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo() { +; IS__CGSCC____-NEXT: [[VAL:%.*]] = call i32 @baz() +; IS__CGSCC____-NEXT: ret i32 [[VAL]] ; %val = call i32 @baz() @@ -28,17 +32,23 @@ define linkonce_odr i32 @foo() { } define i32 @bar() { -; CHECK: Function Attrs: norecurse -; CHECK-LABEL: define {{[^@]+}}@bar -; CHECK-SAME: () #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: [[VAL:%.*]] = call i32 @foo() -; CHECK-NEXT: ret i32 [[VAL]] +; IS__TUNIT____: Function Attrs: norecurse +; IS__TUNIT____-LABEL: define {{[^@]+}}@bar +; IS__TUNIT____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__TUNIT____-NEXT: [[VAL:%.*]] = call i32 @foo() +; IS__TUNIT____-NEXT: ret i32 [[VAL]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@bar() { +; IS__CGSCC____-NEXT: [[VAL:%.*]] = call i32 @foo() +; IS__CGSCC____-NEXT: ret i32 [[VAL]] ; %val = call i32 @foo() ret i32 %val } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR1]] = { norecurse } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR1]] = { norecurse } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll index 7209f5edbada..4b33e60594af 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll @@ -62,11 +62,17 @@ entry: } define internal i32 @cb2(i32 %unknown) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@cb2 -; CHECK-SAME: (i32 noundef returned [[UNKNOWN:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i32 [[UNKNOWN]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@cb2 +; IS__TUNIT____-SAME: (i32 noundef returned [[UNKNOWN:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i32 [[UNKNOWN]] +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@cb2 +; IS__CGSCC____-SAME: (i32 noundef returned [[UNKNOWN:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i32 [[UNKNOWN]] ; entry: %call = call i32 @cb0(i32 0) @@ -121,7 +127,10 @@ declare !callback !3 void @broker(i32 (i32)*, i32 (i32)*, i32 (i32)*, i32, i32) !2 = !{i64 2, i64 3, i1 false} !3 = !{!0, !2, !1} ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ;. ; CHECK: [[META0:![0-9]+]] = !{!1, !2, !3} ; CHECK: [[META1:![0-9]+]] = !{i64 0, i64 3, i1 false} diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll index d9c4e2f31fb3..4f899a386015 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll @@ -47,15 +47,16 @@ define i8* @start(i8 %v) { ; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0 ; IS__CGSCC_OPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]] ; IS__CGSCC_OPM: true: -; IS__CGSCC_OPM-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]]) +; IS__CGSCC_OPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @side_effects(i8 [[V]]) ; IS__CGSCC_OPM-NEXT: ret i8* [[CA]] ; IS__CGSCC_OPM: false: ; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1 ; IS__CGSCC_OPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]] ; IS__CGSCC_OPM: c2_true: -; IS__CGSCC_OPM-NEXT: ret i8* null +; IS__CGSCC_OPM-NEXT: [[CA1:%.*]] = musttail call noalias noundef align 4294967296 i8* @no_side_effects(i8 [[V]]) +; IS__CGSCC_OPM-NEXT: ret i8* [[CA1]] ; IS__CGSCC_OPM: c2_false: -; IS__CGSCC_OPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 [[V]]) +; IS__CGSCC_OPM-NEXT: [[CA2:%.*]] = musttail call noalias noundef align 4294967296 i8* @dont_zap_me(i8 [[V]]) ; IS__CGSCC_OPM-NEXT: ret i8* [[CA2]] ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@start @@ -63,15 +64,16 @@ define i8* @start(i8 %v) { ; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0 ; IS__CGSCC_NPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]] ; IS__CGSCC_NPM: true: -; IS__CGSCC_NPM-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 undef) +; IS__CGSCC_NPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @side_effects(i8 undef) ; IS__CGSCC_NPM-NEXT: ret i8* [[CA]] ; IS__CGSCC_NPM: false: ; IS__CGSCC_NPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1 ; IS__CGSCC_NPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]] ; IS__CGSCC_NPM: c2_true: -; IS__CGSCC_NPM-NEXT: ret i8* null +; IS__CGSCC_NPM-NEXT: [[CA1:%.*]] = musttail call noalias noundef align 4294967296 i8* @no_side_effects(i8 [[V]]) +; IS__CGSCC_NPM-NEXT: ret i8* [[CA1]] ; IS__CGSCC_NPM: c2_false: -; IS__CGSCC_NPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 [[V]]) +; IS__CGSCC_NPM-NEXT: [[CA2:%.*]] = musttail call noalias noundef align 4294967296 i8* @dont_zap_me(i8 [[V]]) ; IS__CGSCC_NPM-NEXT: ret i8* [[CA2]] ; %c1 = icmp eq i8 %v, 0 @@ -92,17 +94,29 @@ c2_false: } define internal i8* @side_effects(i8 %v) { -; IS________OPM-LABEL: define {{[^@]+}}@side_effects -; IS________OPM-SAME: (i8 [[V:%.*]]) { -; IS________OPM-NEXT: [[I1:%.*]] = call i32 @external() -; IS________OPM-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]]) -; IS________OPM-NEXT: ret i8* [[CA]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@side_effects +; IS__TUNIT_OPM-SAME: (i8 [[V:%.*]]) { +; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = call i32 @external() +; IS__TUNIT_OPM-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]]) +; IS__TUNIT_OPM-NEXT: ret i8* [[CA]] ; -; IS________NPM-LABEL: define {{[^@]+}}@side_effects -; IS________NPM-SAME: (i8 [[V:%.*]]) { -; IS________NPM-NEXT: [[I1:%.*]] = call i32 @external() -; IS________NPM-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 0) -; IS________NPM-NEXT: ret i8* [[CA]] +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@side_effects +; IS__TUNIT_NPM-SAME: (i8 [[V:%.*]]) { +; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = call i32 @external() +; IS__TUNIT_NPM-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 0) +; IS__TUNIT_NPM-NEXT: ret i8* [[CA]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@side_effects +; IS__CGSCC_OPM-SAME: (i8 [[V:%.*]]) { +; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = call i32 @external() +; IS__CGSCC_OPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @start(i8 [[V]]) +; IS__CGSCC_OPM-NEXT: ret i8* [[CA]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@side_effects +; IS__CGSCC_NPM-SAME: (i8 [[V:%.*]]) { +; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = call i32 @external() +; IS__CGSCC_NPM-NEXT: [[CA:%.*]] = musttail call noalias noundef align 4294967296 i8* @start(i8 0) +; IS__CGSCC_NPM-NEXT: ret i8* [[CA]] ; %i1 = call i32 @external() diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll index 36d91e4d426f..56d945171cd8 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll @@ -53,27 +53,16 @@ define dso_local void @foo(i32 %N) { ; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef, i64 undef) ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo -; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 -; IS__CGSCC_OPM-NEXT: [[P:%.*]] = alloca float, align 4 -; IS__CGSCC_OPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 -; IS__CGSCC_OPM-NEXT: store float 3.000000e+00, float* [[P]], align 4 -; IS__CGSCC_OPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4 -; IS__CGSCC_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[P]], i64 noundef 4617315517961601024) -; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo -; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: [[P:%.*]] = alloca float, align 4 -; IS__CGSCC_NPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 -; IS__CGSCC_NPM-NEXT: store float 3.000000e+00, float* [[P]], align 4 -; IS__CGSCC_NPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4 -; IS__CGSCC_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[P]], i64 noundef 4617315517961601024) -; IS__CGSCC_NPM-NEXT: ret void +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo +; IS__CGSCC____-SAME: (i32 [[N:%.*]]) { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 +; IS__CGSCC____-NEXT: [[P:%.*]] = alloca float, align 4 +; IS__CGSCC____-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4 +; IS__CGSCC____-NEXT: store float 3.000000e+00, float* [[P]], align 4 +; IS__CGSCC____-NEXT: store i32 7, i32* [[N_ADDR]], align 4 +; IS__CGSCC____-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]], i64 noundef 4617315517961601024) +; IS__CGSCC____-NEXT: ret void ; entry: %N.addr = alloca i32, align 4 @@ -207,7 +196,7 @@ define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %. ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@.omp_outlined. -; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 ; IS__CGSCC_OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 @@ -249,8 +238,9 @@ define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %. ; IS__CGSCC_OPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] ; IS__CGSCC_OPM: omp.inner.for.body: ; IS__CGSCC_OPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 +; IS__CGSCC_OPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 ; IS__CGSCC_OPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 -; IS__CGSCC_OPM-NEXT: call void @bar(i32 [[ADD10]], float noundef 3.000000e+00, double [[TMP11]]) +; IS__CGSCC_OPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) ; IS__CGSCC_OPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] ; IS__CGSCC_OPM: omp.body.continue: ; IS__CGSCC_OPM-NEXT: br label [[OMP_INNER_FOR_INC]] @@ -267,7 +257,7 @@ define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %. ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@.omp_outlined. -; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8 ; IS__CGSCC_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 @@ -309,8 +299,9 @@ define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %. ; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]] ; IS__CGSCC_NPM: omp.inner.for.body: ; IS__CGSCC_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2 +; IS__CGSCC_NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]], align 8 -; IS__CGSCC_NPM-NEXT: call void @bar(i32 [[ADD10]], float noundef 3.000000e+00, double [[TMP11]]) +; IS__CGSCC_NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]]) ; IS__CGSCC_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] ; IS__CGSCC_NPM: omp.body.continue: ; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_INC]] diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll index 32fb11b4e5c3..3b9112c177a3 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll @@ -51,7 +51,7 @@ define dso_local i32 @main() { ; IS__CGSCC____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 ; IS__CGSCC____-NEXT: [[THREAD:%.*]] = alloca i64, align 8 ; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 4294967296 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree noundef readnone align 4294967296 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 4294967296 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*)) +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 4294967296 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 4294967296 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 4294967296 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC2]]) ; IS__CGSCC____-NEXT: ret i32 0 diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll b/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll index 5116721b48cc..dcf5c1ef5afd 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll @@ -23,9 +23,9 @@ define void @bar() { ; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] { ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@bar -; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-SAME: () #[[ATTR0]] { ; IS__CGSCC____-NEXT: ret void ; call i32 @foo( i32 17 ) ; :1 [#uses=0] @@ -36,5 +36,4 @@ define void @bar() { ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll index dce5e534b397..1fc336e8a251 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll @@ -11,11 +11,18 @@ ; FIXME: Remove obsolete calls/instructions define i32 @main() noreturn nounwind { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@main -; CHECK-SAME: () #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i32 123 +; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@main +; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i32 123 +; +; IS__CGSCC____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@main +; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = tail call noundef i32 @wwrite() #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[CALL2]] ; entry: %call2 = tail call i32 @wwrite(i64 0) nounwind @@ -51,6 +58,7 @@ return: ;. ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } ;. -; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll index 2ebc4a33b4f0..c6fcb08786d8 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll @@ -6,19 +6,33 @@ ;; This function returns its second argument on all return statements define internal i32* @incdec(i1 %C, i32* %V) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@incdec -; CHECK-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4 -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: T: -; CHECK-NEXT: [[X1:%.*]] = add i32 [[X]], 1 -; CHECK-NEXT: store i32 [[X1]], i32* [[V]], align 4 -; CHECK-NEXT: ret i32* [[V]] -; CHECK: F: -; CHECK-NEXT: [[X2:%.*]] = sub i32 [[X]], 1 -; CHECK-NEXT: store i32 [[X2]], i32* [[V]], align 4 -; CHECK-NEXT: ret i32* [[V]] +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@incdec +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4 +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: T: +; IS__TUNIT____-NEXT: [[X1:%.*]] = add i32 [[X]], 1 +; IS__TUNIT____-NEXT: store i32 [[X1]], i32* [[V]], align 4 +; IS__TUNIT____-NEXT: ret i32* [[V]] +; IS__TUNIT____: F: +; IS__TUNIT____-NEXT: [[X2:%.*]] = sub i32 [[X]], 1 +; IS__TUNIT____-NEXT: store i32 [[X2]], i32* [[V]], align 4 +; IS__TUNIT____-NEXT: ret i32* [[V]] +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@incdec +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: T: +; IS__CGSCC____-NEXT: [[X1:%.*]] = add i32 [[X]], 1 +; IS__CGSCC____-NEXT: store i32 [[X1]], i32* [[V]], align 4 +; IS__CGSCC____-NEXT: ret i32* [[V]] +; IS__CGSCC____: F: +; IS__CGSCC____-NEXT: [[X2:%.*]] = sub i32 [[X]], 1 +; IS__CGSCC____-NEXT: store i32 [[X2]], i32* [[V]], align 4 +; IS__CGSCC____-NEXT: ret i32* [[V]] ; %X = load i32, i32* %V br i1 %C, label %T, label %F @@ -90,14 +104,14 @@ define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 { ; IS__TUNIT_NPM: RET: ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] personality i32 (...)* @__gxx_personality_v0 { +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { ; IS__CGSCC_OPM-NEXT: [[Q:%.*]] = alloca i32, align 4 -; IS__CGSCC_OPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]] -; IS__CGSCC_OPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR3:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[Q]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR4:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 -; IS__CGSCC_OPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR4:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR5:[0-9]+]] ; IS__CGSCC_OPM-NEXT: br label [[OK:%.*]] ; IS__CGSCC_OPM: OK: ; IS__CGSCC_OPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0 @@ -109,14 +123,14 @@ define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 { ; IS__CGSCC_OPM: RET: ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller -; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] personality i32 (...)* @__gxx_personality_v0 { +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { ; IS__CGSCC_NPM-NEXT: [[Q:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]] -; IS__CGSCC_NPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR3:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) [[Q]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR4:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 -; IS__CGSCC_NPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR4:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR5:[0-9]+]] ; IS__CGSCC_NPM-NEXT: br label [[OK:%.*]] ; IS__CGSCC_NPM: OK: ; IS__CGSCC_NPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0 @@ -163,7 +177,8 @@ declare i32 @__gxx_personality_v0(...) ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR3:[0-9]+]] = { readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR4:[0-9]+]] = { nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3:[0-9]+]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR4:[0-9]+]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR5:[0-9]+]] = { nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll index be8a6b61f9c6..5a51fa46aaa6 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll @@ -7,15 +7,26 @@ ; FIXME: icmp folding is missing define i1 @invokecaller(i1 %C) personality i32 (...)* @__gxx_personality_v0 { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@invokecaller -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { -; CHECK-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]]) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: br label [[OK:%.*]] -; CHECK: OK: -; CHECK-NEXT: ret i1 true -; CHECK: FAIL: -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@invokecaller +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { +; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]]) #[[ATTR1:[0-9]+]] +; IS__TUNIT____-NEXT: br label [[OK:%.*]] +; IS__TUNIT____: OK: +; IS__TUNIT____-NEXT: ret i1 true +; IS__TUNIT____: FAIL: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@invokecaller +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: br label [[OK:%.*]] +; IS__CGSCC____: OK: +; IS__CGSCC____-NEXT: [[Y:%.*]] = icmp ne i32 [[X]], 0 +; IS__CGSCC____-NEXT: ret i1 [[Y]] +; IS__CGSCC____: FAIL: +; IS__CGSCC____-NEXT: unreachable ; %X = invoke i32 @foo( i1 %C ) to label %OK unwind label %FAIL ; [#uses=1] OK: @@ -39,7 +50,7 @@ define internal i32 @foo(i1 %C) { ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: T: ; IS__CGSCC____-NEXT: ret i32 52 @@ -56,10 +67,17 @@ F: ; preds = %0 } define i1 @caller(i1 %C) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC____-NEXT: [[Y:%.*]] = icmp ne i32 [[X]], 0 +; IS__CGSCC____-NEXT: ret i1 [[Y]] ; %X = call i32 @foo( i1 %C ) ; [#uses=1] %Y = icmp ne i32 %X, 0 ; [#uses=1] @@ -68,6 +86,11 @@ define i1 @caller(i1 %C) { declare i32 @__gxx_personality_v0(...) ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR1]] = { nounwind readnone } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR1]] = { nounwind readnone } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll index 954840c1207e..84608789c0f5 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll @@ -61,11 +61,17 @@ F: ; preds = %0 } define %0 @caller(i1 %Q) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller -; CHECK-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: ret [[TMP0]] [[X]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller +; IS__TUNIT____-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1:[0-9]+]] +; IS__TUNIT____-NEXT: ret [[TMP0]] [[X]] +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller +; IS__CGSCC____-SAME: (i1 [[Q:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: ret [[TMP0]] [[X]] ; %X = call %0 @foo(i1 %Q) %A = extractvalue %0 %X, 0 @@ -80,19 +86,33 @@ define %0 @caller(i1 %Q) { ; Similar to @caller but the result of both calls are actually used. define i32 @caller2(i1 %Q) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller2 -; CHECK-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1]] -; CHECK-NEXT: [[A:%.*]] = extractvalue [[TMP0]] [[X]], 0 -; CHECK-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1 -; CHECK-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]]) #[[ATTR1]] -; CHECK-NEXT: [[C:%.*]] = extractvalue [[TMP0]] [[Y]], 0 -; CHECK-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1 -; CHECK-NEXT: [[M:%.*]] = add i32 [[A]], [[C]] -; CHECK-NEXT: [[N:%.*]] = add i32 [[B]], [[D]] -; CHECK-NEXT: [[R:%.*]] = add i32 [[N]], [[M]] -; CHECK-NEXT: ret i32 [[R]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2 +; IS__TUNIT____-SAME: (i1 [[Q:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR1]] +; IS__TUNIT____-NEXT: [[A:%.*]] = extractvalue [[TMP0]] [[X]], 0 +; IS__TUNIT____-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1 +; IS__TUNIT____-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]]) #[[ATTR1]] +; IS__TUNIT____-NEXT: [[C:%.*]] = extractvalue [[TMP0]] [[Y]], 0 +; IS__TUNIT____-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1 +; IS__TUNIT____-NEXT: [[M:%.*]] = add i32 [[A]], [[C]] +; IS__TUNIT____-NEXT: [[N:%.*]] = add i32 [[B]], [[D]] +; IS__TUNIT____-NEXT: [[R:%.*]] = add i32 [[N]], [[M]] +; IS__TUNIT____-NEXT: ret i32 [[R]] +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2 +; IS__CGSCC____-SAME: (i1 [[Q:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[A:%.*]] = extractvalue [[TMP0]] [[X]], 0 +; IS__CGSCC____-NEXT: [[B:%.*]] = extractvalue [[TMP0]] [[X]], 1 +; IS__CGSCC____-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[C:%.*]] = extractvalue [[TMP0]] [[Y]], 0 +; IS__CGSCC____-NEXT: [[D:%.*]] = extractvalue [[TMP0]] [[Y]], 1 +; IS__CGSCC____-NEXT: [[M:%.*]] = add i32 [[A]], [[C]] +; IS__CGSCC____-NEXT: [[N:%.*]] = add i32 [[B]], [[D]] +; IS__CGSCC____-NEXT: [[R:%.*]] = add i32 [[N]], [[M]] +; IS__CGSCC____-NEXT: ret i32 [[R]] ; %X = call %0 @foo(i1 %Q) %A = extractvalue %0 %X, 0 @@ -111,5 +131,6 @@ define i32 @caller2(i1 %Q) { ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { readnone willreturn } ;. 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 index 193bd86efb09..0aacec94229c 100644 --- 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 @@ -31,17 +31,19 @@ if.end: ; preds = %if.then1, %entry } define internal i32 @test1(i1 %c) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test1 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: br label [[IF_THEN:%.*]] ; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: br label [[RET1:%.*]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @testf(i1 [[C]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: [[RES:%.*]] = icmp eq i32 [[CALL]], 10 +; IS__CGSCC____-NEXT: br i1 [[RES]], label [[RET1:%.*]], label [[RET2:%.*]] ; IS__CGSCC____: ret1: ; IS__CGSCC____-NEXT: ret i32 99 ; IS__CGSCC____: ret2: -; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____-NEXT: ret i32 0 ; entry: br label %if.then @@ -59,14 +61,24 @@ ret2: ; preds = %if.then, %entry } define i32 @main(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@main -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: ret i32 99 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@main +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: ret i32 99 +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@main +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[RES:%.*]] = call noundef i32 @test1(i1 [[C]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: ret i32 [[RES]] ; %res = call i32 @test1(i1 %c) ret i32 %res } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll index 48fdaf8256c6..94ffa04d45bf 100644 --- a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll @@ -52,7 +52,7 @@ define dso_local void @caller() { ; ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller() { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: call void @broker(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* noundef nonnull @callee, i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) @gsh) +; IS__CGSCC____-NEXT: call void @broker(i32* nofree noundef nonnull readonly align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* noundef nonnull @callee, i32* nofree noundef nonnull readonly align 4 dereferenceable(4) @gsh) ; IS__CGSCC____-NEXT: ret void ; entry: diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll index e3fb1a709620..3524f1da4719 100644 --- a/llvm/test/Transforms/Attributor/align.ll +++ b/llvm/test/Transforms/Attributor/align.ll @@ -245,10 +245,20 @@ define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 { ; TEST 7 ; Better than IR information define align 4 i8* @test7() #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@test7 -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: ret i8* @a1 +; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@test7 +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i8* @a1 +; +; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test7 +; IS__CGSCC_OPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: ret i8* @a1 +; +; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test7 +; IS__CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: ret i8* @a1 ; %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1) ret i8* %c @@ -373,10 +383,20 @@ define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 { } define align 4 i32* @test7b(i32* align 32 %p) #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@test7b -; CHECK-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: ret i32* [[P]] +; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@test7b +; IS__TUNIT____-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32* [[P]] +; +; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test7b +; IS__CGSCC_OPM-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: ret i32* [[P]] +; +; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test7b +; IS__CGSCC_NPM-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: ret i32* [[P]] ; tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1) ret i32* %p @@ -384,23 +404,23 @@ define align 4 i32* @test7b(i32* align 32 %p) #0 { ; TEST 8 define void @test8_helper() { -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test8_helper() { -; NOT_CGSCC_OPM-NEXT: [[PTR0:%.*]] = tail call i32* @unknown() -; NOT_CGSCC_OPM-NEXT: [[PTR1:%.*]] = tail call align 4 i32* @unknown() -; NOT_CGSCC_OPM-NEXT: [[PTR2:%.*]] = tail call align 8 i32* @unknown() -; NOT_CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone [[PTR0]]) #[[ATTR2:[0-9]+]] -; NOT_CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR2]] -; NOT_CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR2]] -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_helper() { +; IS__TUNIT____-NEXT: [[PTR0:%.*]] = tail call i32* @unknown() +; IS__TUNIT____-NEXT: [[PTR1:%.*]] = tail call align 4 i32* @unknown() +; IS__TUNIT____-NEXT: [[PTR2:%.*]] = tail call align 8 i32* @unknown() +; IS__TUNIT____-NEXT: tail call void @test8(i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone [[PTR0]]) #[[ATTR2:[0-9]+]] +; IS__TUNIT____-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR2]] +; IS__TUNIT____-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR2]] +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8_helper() { -; IS__CGSCC_OPM-NEXT: [[PTR0:%.*]] = tail call i32* @unknown() -; IS__CGSCC_OPM-NEXT: [[PTR1:%.*]] = tail call align 4 i32* @unknown() -; IS__CGSCC_OPM-NEXT: [[PTR2:%.*]] = tail call align 8 i32* @unknown() -; IS__CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone [[PTR0]]) #[[ATTR3:[0-9]+]] -; IS__CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_helper() { +; IS__CGSCC____-NEXT: [[PTR0:%.*]] = tail call i32* @unknown() +; IS__CGSCC____-NEXT: [[PTR1:%.*]] = tail call align 4 i32* @unknown() +; IS__CGSCC____-NEXT: [[PTR2:%.*]] = tail call align 8 i32* @unknown() +; IS__CGSCC____-NEXT: tail call void @test8(i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone [[PTR0]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC____-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: ret void ; %ptr0 = tail call i32* @unknown() %ptr1 = tail call align 4 i32* @unknown() @@ -414,21 +434,21 @@ define void @test8_helper() { declare void @user_i32_ptr(i32* nocapture readnone) nounwind define internal void @test8(i32* %a, i32* %b, i32* %c) { -; NOT_CGSCC_OPM: Function Attrs: nounwind -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test8 -; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR2]] { -; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR2]] -; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR2]] -; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR2]] -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@test8 +; IS__TUNIT____-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR2]] +; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR2]] +; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR2]] +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nounwind -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8 -; IS__CGSCC_OPM-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR3]] { -; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@test8 +; IS__CGSCC____-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: ret void ; call void @user_i32_ptr(i32* %a) call void @user_i32_ptr(i32* %b) @@ -456,43 +476,43 @@ define void @test9_traversal(i1 %cnd, i32* align 4 %B, i32* align 8 %C) { ; FIXME: This will work with an upcoming patch (D66618 or similar) ; store i32 -1, i32* %g1, align 32 define i32* @test10a(i32* align 32 %p) { -; NOT_CGSCC_OPM: Function Attrs: nofree nosync nounwind -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test10a -; NOT_CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3:[0-9]+]] { -; NOT_CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 -; NOT_CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 -; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; NOT_CGSCC_OPM: t: -; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]] -; NOT_CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32 -; NOT_CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 -; NOT_CGSCC_OPM-NEXT: br label [[E:%.*]] -; NOT_CGSCC_OPM: f: -; NOT_CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8 -; NOT_CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32 -; NOT_CGSCC_OPM-NEXT: br label [[E]] -; NOT_CGSCC_OPM: e: -; NOT_CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] -; NOT_CGSCC_OPM-NEXT: ret i32* [[PHI]] +; IS__TUNIT____: Function Attrs: nofree nosync nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@test10a +; IS__TUNIT____-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 +; IS__TUNIT____-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]] +; IS__TUNIT____-NEXT: store i32 1, i32* [[R]], align 32 +; IS__TUNIT____-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 +; IS__TUNIT____-NEXT: br label [[E:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8 +; IS__TUNIT____-NEXT: store i32 -1, i32* [[G1]], align 32 +; IS__TUNIT____-NEXT: br label [[E]] +; IS__TUNIT____: e: +; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] +; IS__TUNIT____-NEXT: ret i32* [[PHI]] ; -; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test10a -; IS__CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 -; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__CGSCC_OPM: t: -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]] -; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32 -; IS__CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 -; IS__CGSCC_OPM-NEXT: br label [[E:%.*]] -; IS__CGSCC_OPM: f: -; IS__CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8 -; IS__CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32 -; IS__CGSCC_OPM-NEXT: br label [[E]] -; IS__CGSCC_OPM: e: -; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] -; IS__CGSCC_OPM-NEXT: ret i32* [[PHI]] +; IS__CGSCC____: Function Attrs: nofree nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@test10a +; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 +; IS__CGSCC____-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: store i32 1, i32* [[R]], align 32 +; IS__CGSCC____-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 +; IS__CGSCC____-NEXT: br label [[E:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8 +; IS__CGSCC____-NEXT: store i32 -1, i32* [[G1]], align 32 +; IS__CGSCC____-NEXT: br label [[E]] +; IS__CGSCC____: e: +; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] +; IS__CGSCC____-NEXT: ret i32* [[PHI]] ; %l = load i32, i32* %p %c = icmp eq i32 %l, 0 @@ -518,43 +538,43 @@ e: ; FIXME: This will work with an upcoming patch (D66618 or similar) ; store i32 -1, i32* %g1, align 32 define i32* @test10b(i32* align 32 %p) { -; NOT_CGSCC_OPM: Function Attrs: nofree nosync nounwind -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test10b -; NOT_CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] { -; NOT_CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 -; NOT_CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 -; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; NOT_CGSCC_OPM: t: -; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]] -; NOT_CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32 -; NOT_CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 -; NOT_CGSCC_OPM-NEXT: br label [[E:%.*]] -; NOT_CGSCC_OPM: f: -; NOT_CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8 -; NOT_CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32 -; NOT_CGSCC_OPM-NEXT: br label [[E]] -; NOT_CGSCC_OPM: e: -; NOT_CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] -; NOT_CGSCC_OPM-NEXT: ret i32* [[PHI]] +; IS__TUNIT____: Function Attrs: nofree nosync nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@test10b +; IS__TUNIT____-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 +; IS__TUNIT____-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]] +; IS__TUNIT____-NEXT: store i32 1, i32* [[R]], align 32 +; IS__TUNIT____-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 +; IS__TUNIT____-NEXT: br label [[E:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8 +; IS__TUNIT____-NEXT: store i32 -1, i32* [[G1]], align 32 +; IS__TUNIT____-NEXT: br label [[E]] +; IS__TUNIT____: e: +; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] +; IS__TUNIT____-NEXT: ret i32* [[PHI]] ; -; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test10b -; IS__CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] { -; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 -; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS__CGSCC_OPM: t: -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]] -; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32 -; IS__CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 -; IS__CGSCC_OPM-NEXT: br label [[E:%.*]] -; IS__CGSCC_OPM: f: -; IS__CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8 -; IS__CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32 -; IS__CGSCC_OPM-NEXT: br label [[E]] -; IS__CGSCC_OPM: e: -; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] -; IS__CGSCC_OPM-NEXT: ret i32* [[PHI]] +; IS__CGSCC____: Function Attrs: nofree nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@test10b +; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 +; IS__CGSCC____-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: store i32 1, i32* [[R]], align 32 +; IS__CGSCC____-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 +; IS__CGSCC____-NEXT: br label [[E:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8 +; IS__CGSCC____-NEXT: store i32 -1, i32* [[G1]], align 32 +; IS__CGSCC____-NEXT: br label [[E]] +; IS__CGSCC____: e: +; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] +; IS__CGSCC____-NEXT: ret i32* [[PHI]] ; %l = load i32, i32* %p %c = icmp eq i32 %l, 0 @@ -575,19 +595,19 @@ e: define i64 @test11(i32* %p) { -; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test11 -; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR4:[0-9]+]] { -; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8 -; NOT_CGSCC_OPM-NEXT: ret i64 [[RET]] +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test11 +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__TUNIT____-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8 +; IS__TUNIT____-NEXT: ret i64 [[RET]] ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test11 -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR5:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8 -; IS__CGSCC_OPM-NEXT: ret i64 [[RET]] +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test11 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR5:[0-9]+]] { +; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__CGSCC____-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8 +; IS__CGSCC____-NEXT: ret i64 [[RET]] ; %p-cast = bitcast i32* %p to i64* %ret = load i64, i64* %p-cast, align 8 @@ -599,23 +619,23 @@ define i64 @test11(i32* %p) { ; FXIME: %p should have nonnull define i64 @test12-1(i32* align 4 %p) { -; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-1 -; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR4]] { -; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 -; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 -; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16 -; NOT_CGSCC_OPM-NEXT: ret i64 [[RET]] +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-1 +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR4]] { +; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 +; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 +; IS__TUNIT____-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16 +; IS__TUNIT____-NEXT: ret i64 [[RET]] ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-1 -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR5]] { -; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 -; IS__CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16 -; IS__CGSCC_OPM-NEXT: ret i64 [[RET]] +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-1 +; IS__CGSCC____-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR5]] { +; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 +; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 +; IS__CGSCC____-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16 +; IS__CGSCC____-NEXT: ret i64 [[RET]] ; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 @@ -625,21 +645,21 @@ define i64 @test12-1(i32* align 4 %p) { } define i64 @test12-2(i32* align 4 %p) { -; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-2 -; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR4]] { -; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 -; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16 -; NOT_CGSCC_OPM-NEXT: ret i64 [[RET]] +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-2 +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR4]] { +; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 +; IS__TUNIT____-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16 +; IS__TUNIT____-NEXT: ret i64 [[RET]] ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-2 -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] { -; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 -; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16 -; IS__CGSCC_OPM-NEXT: ret i64 [[RET]] +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-2 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] { +; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 +; IS__CGSCC____-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16 +; IS__CGSCC____-NEXT: ret i64 [[RET]] ; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 @@ -649,23 +669,23 @@ define i64 @test12-2(i32* align 4 %p) { ; FXIME: %p should have nonnull define void @test12-3(i32* align 4 %p) { -; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-3 -; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR5:[0-9]+]] { -; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 -; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 -; NOT_CGSCC_OPM-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16 -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-3 +; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR5:[0-9]+]] { +; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 +; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 +; IS__TUNIT____-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16 +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-3 -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 -; IS__CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 -; IS__CGSCC_OPM-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16 -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-3 +; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 +; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 +; IS__CGSCC____-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16 +; IS__CGSCC____-NEXT: ret void ; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 @@ -675,21 +695,21 @@ define void @test12-3(i32* align 4 %p) { } define void @test12-4(i32* align 4 %p) { -; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-4 -; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] { -; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 -; NOT_CGSCC_OPM-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16 -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-4 +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] { +; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 +; IS__TUNIT____-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16 +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-4 -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR6]] { -; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 -; IS__CGSCC_OPM-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16 -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-4 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR6]] { +; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 +; IS__CGSCC____-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16 +; IS__CGSCC____-NEXT: ret void ; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 @@ -700,23 +720,23 @@ define void @test12-4(i32* align 4 %p) { declare void @use(i64*) willreturn nounwind define void @test12-5(i32* align 4 %p) { -; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-5 -; NOT_CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] { -; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 -; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 -; NOT_CGSCC_OPM-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR6]] -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-5 +; IS__TUNIT____-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 +; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 +; IS__TUNIT____-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR6]] +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nounwind willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-5 -; IS__CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 -; IS__CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 -; IS__CGSCC_OPM-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR7]] -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-5 +; IS__CGSCC____-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 +; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 +; IS__CGSCC____-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: ret void ; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 @@ -726,21 +746,21 @@ define void @test12-5(i32* align 4 %p) { } define void @test12-6(i32* align 4 %p) { -; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-6 -; NOT_CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6]] { -; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 -; NOT_CGSCC_OPM-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR6]] -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-6 +; IS__TUNIT____-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6]] { +; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 +; IS__TUNIT____-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR6]] +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nounwind willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-6 -; IS__CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7]] { -; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* -; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 -; IS__CGSCC_OPM-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR7]] -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-6 +; IS__CGSCC____-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* +; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 +; IS__CGSCC____-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: ret void ; %p-cast = bitcast i32* %p to i64* %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 @@ -749,31 +769,31 @@ define void @test12-6(i32* align 4 %p) { } define void @test13(i1 %c, i32* align 32 %dst) #0 { -; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13 -; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR7:[0-9]+]] { -; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; NOT_CGSCC_OPM: truebb: -; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] -; NOT_CGSCC_OPM: falsebb: -; NOT_CGSCC_OPM-NEXT: br label [[END]] -; NOT_CGSCC_OPM: end: -; NOT_CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] -; NOT_CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@test13 +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__TUNIT____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; IS__TUNIT____: truebb: +; IS__TUNIT____-NEXT: br label [[END:%.*]] +; IS__TUNIT____: falsebb: +; IS__TUNIT____-NEXT: br label [[END]] +; IS__TUNIT____: end: +; IS__TUNIT____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] +; IS__TUNIT____-NEXT: store i32 0, i32* [[PTR]], align 32 +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13 -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; IS__CGSCC_OPM: truebb: -; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] -; IS__CGSCC_OPM: falsebb: -; IS__CGSCC_OPM-NEXT: br label [[END]] -; IS__CGSCC_OPM: end: -; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] -; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13 +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; IS__CGSCC____: truebb: +; IS__CGSCC____-NEXT: br label [[END:%.*]] +; IS__CGSCC____: falsebb: +; IS__CGSCC____-NEXT: br label [[END]] +; IS__CGSCC____: end: +; IS__CGSCC____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] +; IS__CGSCC____-NEXT: store i32 0, i32* [[PTR]], align 32 +; IS__CGSCC____-NEXT: ret void ; br i1 %c, label %truebb, label %falsebb truebb: @@ -787,31 +807,31 @@ end: } define void @test13-1(i1 %c, i32* align 32 %dst) { -; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13-1 -; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] { -; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; NOT_CGSCC_OPM: truebb: -; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] -; NOT_CGSCC_OPM: falsebb: -; NOT_CGSCC_OPM-NEXT: br label [[END]] -; NOT_CGSCC_OPM: end: -; NOT_CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] -; NOT_CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 16 -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-1 +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__TUNIT____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; IS__TUNIT____: truebb: +; IS__TUNIT____-NEXT: br label [[END:%.*]] +; IS__TUNIT____: falsebb: +; IS__TUNIT____-NEXT: br label [[END]] +; IS__TUNIT____: end: +; IS__TUNIT____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] +; IS__TUNIT____-NEXT: store i32 0, i32* [[PTR]], align 16 +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13-1 -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; IS__CGSCC_OPM: truebb: -; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] -; IS__CGSCC_OPM: falsebb: -; IS__CGSCC_OPM-NEXT: br label [[END]] -; IS__CGSCC_OPM: end: -; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] -; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 16 -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-1 +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; IS__CGSCC____: truebb: +; IS__CGSCC____-NEXT: br label [[END:%.*]] +; IS__CGSCC____: falsebb: +; IS__CGSCC____-NEXT: br label [[END]] +; IS__CGSCC____: end: +; IS__CGSCC____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] +; IS__CGSCC____-NEXT: store i32 0, i32* [[PTR]], align 16 +; IS__CGSCC____-NEXT: ret void ; br i1 %c, label %truebb, label %falsebb truebb: @@ -825,31 +845,31 @@ end: } define void @test13-2(i1 %c, i32* align 32 %dst) { -; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13-2 -; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] { -; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; NOT_CGSCC_OPM: truebb: -; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] -; NOT_CGSCC_OPM: falsebb: -; NOT_CGSCC_OPM-NEXT: br label [[END]] -; NOT_CGSCC_OPM: end: -; NOT_CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] -; NOT_CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-2 +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] { +; IS__TUNIT____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; IS__TUNIT____: truebb: +; IS__TUNIT____-NEXT: br label [[END:%.*]] +; IS__TUNIT____: falsebb: +; IS__TUNIT____-NEXT: br label [[END]] +; IS__TUNIT____: end: +; IS__TUNIT____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] +; IS__TUNIT____-NEXT: store i32 0, i32* [[PTR]], align 32 +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13-2 -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] { -; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; IS__CGSCC_OPM: truebb: -; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] -; IS__CGSCC_OPM: falsebb: -; IS__CGSCC_OPM-NEXT: br label [[END]] -; IS__CGSCC_OPM: end: -; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] -; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-2 +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; IS__CGSCC____: truebb: +; IS__CGSCC____-NEXT: br label [[END:%.*]] +; IS__CGSCC____: falsebb: +; IS__CGSCC____-NEXT: br label [[END]] +; IS__CGSCC____: end: +; IS__CGSCC____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] +; IS__CGSCC____-NEXT: store i32 0, i32* [[PTR]], align 32 +; IS__CGSCC____-NEXT: ret void ; br i1 %c, label %truebb, label %falsebb truebb: @@ -863,31 +883,31 @@ end: } define void @test13-3(i1 %c, i32* align 32 %dst) { -; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13-3 -; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] { -; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; NOT_CGSCC_OPM: truebb: -; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] -; NOT_CGSCC_OPM: falsebb: -; NOT_CGSCC_OPM-NEXT: br label [[END]] -; NOT_CGSCC_OPM: end: -; NOT_CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] -; NOT_CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-3 +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] { +; IS__TUNIT____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; IS__TUNIT____: truebb: +; IS__TUNIT____-NEXT: br label [[END:%.*]] +; IS__TUNIT____: falsebb: +; IS__TUNIT____-NEXT: br label [[END]] +; IS__TUNIT____: end: +; IS__TUNIT____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] +; IS__TUNIT____-NEXT: store i32 0, i32* [[PTR]], align 32 +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13-3 -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] { -; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; IS__CGSCC_OPM: truebb: -; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] -; IS__CGSCC_OPM: falsebb: -; IS__CGSCC_OPM-NEXT: br label [[END]] -; IS__CGSCC_OPM: end: -; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] -; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-3 +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] +; IS__CGSCC____: truebb: +; IS__CGSCC____-NEXT: br label [[END:%.*]] +; IS__CGSCC____: falsebb: +; IS__CGSCC____-NEXT: br label [[END]] +; IS__CGSCC____: end: +; IS__CGSCC____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] +; IS__CGSCC____-NEXT: store i32 0, i32* [[PTR]], align 32 +; IS__CGSCC____-NEXT: ret void ; br i1 %c, label %truebb, label %falsebb truebb: @@ -902,33 +922,33 @@ end: ; Don't crash on ptr2int/int2ptr uses. define i64 @ptr2int(i32* %p) { -; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@ptr2int -; NOT_CGSCC_OPM-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9:[0-9]+]] { -; NOT_CGSCC_OPM-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 -; NOT_CGSCC_OPM-NEXT: ret i64 [[P2I]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr2int +; IS__TUNIT____-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__TUNIT____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 +; IS__TUNIT____-NEXT: ret i64 [[P2I]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ptr2int -; IS__CGSCC_OPM-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR10:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 -; IS__CGSCC_OPM-NEXT: ret i64 [[P2I]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr2int +; IS__CGSCC____-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__CGSCC____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 +; IS__CGSCC____-NEXT: ret i64 [[P2I]] ; %p2i = ptrtoint i32* %p to i64 ret i64 %p2i } define i64* @int2ptr(i64 %i) { -; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@int2ptr -; NOT_CGSCC_OPM-SAME: (i64 [[I:%.*]]) #[[ATTR9]] { -; NOT_CGSCC_OPM-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* -; NOT_CGSCC_OPM-NEXT: ret i64* [[I2P]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@int2ptr +; IS__TUNIT____-SAME: (i64 [[I:%.*]]) #[[ATTR9]] { +; IS__TUNIT____-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* +; IS__TUNIT____-NEXT: ret i64* [[I2P]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@int2ptr -; IS__CGSCC_OPM-SAME: (i64 [[I:%.*]]) #[[ATTR10]] { -; IS__CGSCC_OPM-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* -; IS__CGSCC_OPM-NEXT: ret i64* [[I2P]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@int2ptr +; IS__CGSCC____-SAME: (i64 [[I:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* +; IS__CGSCC____-NEXT: ret i64* [[I2P]] ; %i2p = inttoptr i64 %i to i64* ret i64* %i2p @@ -936,17 +956,17 @@ define i64* @int2ptr(i64 %i) { ; Use the store alignment only for the pointer operand. define void @aligned_store(i8* %Value, i8** %Ptr) { -; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_store -; NOT_CGSCC_OPM-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR5]] { -; NOT_CGSCC_OPM-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@aligned_store +; IS__TUNIT____-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR5]] { +; IS__TUNIT____-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_store -; IS__CGSCC_OPM-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR6]] { -; IS__CGSCC_OPM-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@aligned_store +; IS__CGSCC____-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR6]] { +; IS__CGSCC____-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 +; IS__CGSCC____-NEXT: ret void ; store i8* %Value, i8** %Ptr, align 32 ret void @@ -966,19 +986,19 @@ define void @align_call_op_not_store(i8* align 2048 %arg) { } define void @align_store_after_bc(i32* align 2048 %arg) { ; -; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@align_store_after_bc -; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR5]] { -; NOT_CGSCC_OPM-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* -; NOT_CGSCC_OPM-NEXT: store i8 0, i8* [[BC]], align 2048 -; NOT_CGSCC_OPM-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@align_store_after_bc +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR5]] { +; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* +; IS__TUNIT____-NEXT: store i8 0, i8* [[BC]], align 2048 +; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@align_store_after_bc -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR6]] { -; IS__CGSCC_OPM-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* -; IS__CGSCC_OPM-NEXT: store i8 0, i8* [[BC]], align 2048 -; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@align_store_after_bc +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR6]] { +; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* +; IS__CGSCC____-NEXT: store i8 0, i8* [[BC]], align 2048 +; IS__CGSCC____-NEXT: ret void ; %bc = bitcast i32* %arg to i8* store i8 0, i8* %bc @@ -989,17 +1009,17 @@ define void @align_store_after_bc(i32* align 2048 %arg) { ; we cannot also put on the caller. @cnd = external global i1 define i32 @musttail_callee_1(i32* %p) { -; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@musttail_callee_1 -; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR4]] { -; NOT_CGSCC_OPM-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 -; NOT_CGSCC_OPM-NEXT: ret i32 [[V]] +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_callee_1 +; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR4]] { +; IS__TUNIT____-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 +; IS__TUNIT____-NEXT: ret i32 [[V]] ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@musttail_callee_1 -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR5]] { -; IS__CGSCC_OPM-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 -; IS__CGSCC_OPM-NEXT: ret i32 [[V]] +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@musttail_callee_1 +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR5]] { +; IS__CGSCC____-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 +; IS__CGSCC____-NEXT: ret i32 [[V]] ; %v = load i32, i32* %p, align 32 ret i32 %v @@ -1016,27 +1036,16 @@ define i32 @musttail_caller_1(i32* %p) { ; IS__TUNIT____: exit: ; IS__TUNIT____-NEXT: ret i32 0 ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@musttail_caller_1 -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR11:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 -; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] -; IS__CGSCC_OPM: mt: -; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR12:[0-9]+]] -; IS__CGSCC_OPM-NEXT: ret i32 [[V]] -; IS__CGSCC_OPM: exit: -; IS__CGSCC_OPM-NEXT: ret i32 0 -; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@musttail_caller_1 -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR10:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 -; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] -; IS__CGSCC_NPM: mt: -; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR11:[0-9]+]] -; IS__CGSCC_NPM-NEXT: ret i32 [[V]] -; IS__CGSCC_NPM: exit: -; IS__CGSCC_NPM-NEXT: ret i32 0 +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@musttail_caller_1 +; IS__CGSCC____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__CGSCC____-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] +; IS__CGSCC____: mt: +; IS__CGSCC____-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR13:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[V]] +; IS__CGSCC____: exit: +; IS__CGSCC____-NEXT: ret i32 0 ; %c = load i1, i1* @cnd br i1 %c, label %mt, label %exit @@ -1048,37 +1057,37 @@ exit: } define i32* @checkAndAdvance(i32* align(16) %p) { -; NOT_CGSCC_OPM: Function Attrs: nounwind -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@checkAndAdvance -; NOT_CGSCC_OPM-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2]] { -; NOT_CGSCC_OPM-NEXT: entry: -; NOT_CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 16 -; NOT_CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 -; NOT_CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] -; NOT_CGSCC_OPM: if.then: -; NOT_CGSCC_OPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 -; NOT_CGSCC_OPM-NEXT: [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR2]] -; NOT_CGSCC_OPM-NEXT: br label [[RETURN]] -; NOT_CGSCC_OPM: return: -; NOT_CGSCC_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ] -; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR2]] -; NOT_CGSCC_OPM-NEXT: ret i32* [[RETVAL_0]] +; IS__TUNIT____: Function Attrs: nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@checkAndAdvance +; IS__TUNIT____-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 16 +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] +; IS__TUNIT____: if.then: +; IS__TUNIT____-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR2]] +; IS__TUNIT____-NEXT: br label [[RETURN]] +; IS__TUNIT____: return: +; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ] +; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR2]] +; IS__TUNIT____-NEXT: ret i32* [[RETVAL_0]] ; -; IS__CGSCC_OPM: Function Attrs: nounwind -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@checkAndAdvance -; IS__CGSCC_OPM-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 16 -; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 -; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] -; IS__CGSCC_OPM: if.then: -; IS__CGSCC_OPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 -; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: br label [[RETURN]] -; IS__CGSCC_OPM: return: -; IS__CGSCC_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ] -; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: ret i32* [[RETVAL_0]] +; IS__CGSCC____: Function Attrs: nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@checkAndAdvance +; IS__CGSCC____-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 16 +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] +; IS__CGSCC____: if.then: +; IS__CGSCC____-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: br label [[RETURN]] +; IS__CGSCC____: return: +; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ] +; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: ret i32* [[RETVAL_0]] ; entry: %0 = load i32, i32* %p, align 4 @@ -1112,39 +1121,39 @@ declare void @align4_callee(i8* align(4) %p) @G = global i8 0, align 32 define internal i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2) norecurse { -; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return -; NOT_CGSCC_OPM-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] { -; NOT_CGSCC_OPM-NEXT: [[STACK:%.*]] = alloca i8*, align 8 -; NOT_CGSCC_OPM-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]] -; NOT_CGSCC_OPM: t: -; NOT_CGSCC_OPM-NEXT: [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8 -; NOT_CGSCC_OPM-NEXT: [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]] -; NOT_CGSCC_OPM-NEXT: store i8* [[SEL]], i8** [[STACK]], align 8 -; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] -; NOT_CGSCC_OPM: f: -; NOT_CGSCC_OPM-NEXT: store i8* @G, i8** [[STACK]], align 8 -; NOT_CGSCC_OPM-NEXT: br label [[END]] -; NOT_CGSCC_OPM: end: -; NOT_CGSCC_OPM-NEXT: [[L:%.*]] = load i8*, i8** [[STACK]], align 8 -; NOT_CGSCC_OPM-NEXT: ret i8* [[L]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@aligned_8_return +; IS__TUNIT____-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i8*, align 8 +; IS__TUNIT____-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8 +; IS__TUNIT____-NEXT: [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]] +; IS__TUNIT____-NEXT: store i8* [[SEL]], i8** [[STACK]], align 8 +; IS__TUNIT____-NEXT: br label [[END:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i8* @G, i8** [[STACK]], align 8 +; IS__TUNIT____-NEXT: br label [[END]] +; IS__TUNIT____: end: +; IS__TUNIT____-NEXT: [[L:%.*]] = load i8*, i8** [[STACK]], align 8 +; IS__TUNIT____-NEXT: ret i8* [[L]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return -; IS__CGSCC_OPM-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] { -; IS__CGSCC_OPM-NEXT: [[STACK:%.*]] = alloca i8*, align 8 -; IS__CGSCC_OPM-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]] -; IS__CGSCC_OPM: t: -; IS__CGSCC_OPM-NEXT: [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8 -; IS__CGSCC_OPM-NEXT: [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]] -; IS__CGSCC_OPM-NEXT: store i8* [[SEL]], i8** [[STACK]], align 8 -; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] -; IS__CGSCC_OPM: f: -; IS__CGSCC_OPM-NEXT: store i8* @G, i8** [[STACK]], align 8 -; IS__CGSCC_OPM-NEXT: br label [[END]] -; IS__CGSCC_OPM: end: -; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i8*, i8** [[STACK]], align 8 -; IS__CGSCC_OPM-NEXT: ret i8* [[L]] +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@aligned_8_return +; IS__CGSCC____-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i8*, align 8 +; IS__CGSCC____-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8 +; IS__CGSCC____-NEXT: [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]] +; IS__CGSCC____-NEXT: store i8* [[SEL]], i8** [[STACK]], align 8 +; IS__CGSCC____-NEXT: br label [[END:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i8* @G, i8** [[STACK]], align 8 +; IS__CGSCC____-NEXT: br label [[END]] +; IS__CGSCC____: end: +; IS__CGSCC____-NEXT: [[L:%.*]] = load i8*, i8** [[STACK]], align 8 +; IS__CGSCC____-NEXT: ret i8* [[L]] ; %stack = alloca i8* br i1 %c1, label %t, label %f @@ -1162,17 +1171,17 @@ end: } define i8* @aligned_8_return_caller(i8* align(16) %a, i1 %c1, i1 %c2) { -; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return_caller -; NOT_CGSCC_OPM-SAME: (i8* nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] { -; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR12:[0-9]+]] -; NOT_CGSCC_OPM-NEXT: ret i8* [[R]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@aligned_8_return_caller +; IS__TUNIT____-SAME: (i8* nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] { +; IS__TUNIT____-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR12:[0-9]+]] +; IS__TUNIT____-NEXT: ret i8* [[R]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return_caller -; IS__CGSCC_OPM-SAME: (i8* nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] { -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR13:[0-9]+]] -; IS__CGSCC_OPM-NEXT: ret i8* [[R]] +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@aligned_8_return_caller +; IS__CGSCC____-SAME: (i8* nofree readnone align 16 [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__CGSCC____-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR14:[0-9]+]] +; IS__CGSCC____-NEXT: ret i8* [[R]] ; %r = call i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2) ret i8* %r @@ -1207,21 +1216,24 @@ attributes #2 = { null_pointer_is_valid } ; IS__CGSCC_OPM: attributes #[[ATTR8]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR12]] = { readonly willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree nosync nounwind readonly willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readonly willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR14]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { noinline nounwind uwtable } -; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree nosync nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR7]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } -; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR11]] = { readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR12]] = { readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree noinline nosync nounwind readnone willreturn uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR8]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR11]] = { nofree nosync nounwind readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR13]] = { readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR14]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/alwaysinline.ll b/llvm/test/Transforms/Attributor/alwaysinline.ll index fc3ef89e0754..03e5113d9b53 100644 --- a/llvm/test/Transforms/Attributor/alwaysinline.ll +++ b/llvm/test/Transforms/Attributor/alwaysinline.ll @@ -21,11 +21,17 @@ entry: } define void @outer1() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@outer1 -; CHECK-SAME: () #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@outer1 +; IS__TUNIT____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@outer1 +; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret void ; entry: call void @inner1() @@ -45,12 +51,17 @@ entry: ; CHECK-NOT: Function Attrs define i32 @outer2() { -; CHECK: Function Attrs: norecurse -; CHECK-LABEL: define {{[^@]+}}@outer2 -; CHECK-SAME: () #[[ATTR2:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[R:%.*]] = call i32 @inner2() #[[ATTR3:[0-9]+]] -; CHECK-NEXT: ret i32 [[R]] +; IS__TUNIT____: Function Attrs: norecurse +; IS__TUNIT____-LABEL: define {{[^@]+}}@outer2 +; IS__TUNIT____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[R:%.*]] = call i32 @inner2() #[[ATTR3:[0-9]+]] +; IS__TUNIT____-NEXT: ret i32 [[R]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@outer2() { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @inner2() #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: %r = call i32 @inner2() alwaysinline @@ -61,15 +72,25 @@ entry: ; it is `unexactly defined` and alwaysinline but cannot be inlined. ; so it will not be analyzed define linkonce i32 @inner3(i8* %addr) alwaysinline { -; CHECK: Function Attrs: alwaysinline -; CHECK-LABEL: define {{[^@]+}}@inner3 -; CHECK-SAME: (i8* [[ADDR:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: indirectbr i8* [[ADDR]], [label [[ONE:%.*]], label %two] -; CHECK: one: -; CHECK-NEXT: ret i32 42 -; CHECK: two: -; CHECK-NEXT: ret i32 44 +; IS__TUNIT____: Function Attrs: alwaysinline +; IS__TUNIT____-LABEL: define {{[^@]+}}@inner3 +; IS__TUNIT____-SAME: (i8* [[ADDR:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: indirectbr i8* [[ADDR]], [label [[ONE:%.*]], label %two] +; IS__TUNIT____: one: +; IS__TUNIT____-NEXT: ret i32 42 +; IS__TUNIT____: two: +; IS__TUNIT____-NEXT: ret i32 44 +; +; IS__CGSCC____: Function Attrs: alwaysinline +; IS__CGSCC____-LABEL: define {{[^@]+}}@inner3 +; IS__CGSCC____-SAME: (i8* [[ADDR:%.*]]) #[[ATTR2]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: indirectbr i8* [[ADDR]], [label [[ONE:%.*]], label %two] +; IS__CGSCC____: one: +; IS__CGSCC____-NEXT: ret i32 42 +; IS__CGSCC____: two: +; IS__CGSCC____-NEXT: ret i32 44 ; entry: indirectbr i8* %addr, [ label %one, label %two ] @@ -82,13 +103,20 @@ two: } define i32 @outer3(i32 %x) { -; CHECK: Function Attrs: norecurse -; CHECK-LABEL: define {{[^@]+}}@outer3 -; CHECK-SAME: (i32 [[X:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 42 -; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[CMP]], i8* blockaddress(@inner3, [[ONE:%.*]]), i8* blockaddress(@inner3, [[TWO:%.*]]) -; CHECK-NEXT: [[CALL:%.*]] = call i32 @inner3(i8* [[ADDR]]) -; CHECK-NEXT: ret i32 [[CALL]] +; IS__TUNIT____: Function Attrs: norecurse +; IS__TUNIT____-LABEL: define {{[^@]+}}@outer3 +; IS__TUNIT____-SAME: (i32 [[X:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 42 +; IS__TUNIT____-NEXT: [[ADDR:%.*]] = select i1 [[CMP]], i8* blockaddress(@inner3, [[ONE:%.*]]), i8* blockaddress(@inner3, [[TWO:%.*]]) +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @inner3(i8* [[ADDR]]) +; IS__TUNIT____-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@outer3 +; IS__CGSCC____-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 42 +; IS__CGSCC____-NEXT: [[ADDR:%.*]] = select i1 [[CMP]], i8* blockaddress(@inner3, [[ONE:%.*]]), i8* blockaddress(@inner3, [[TWO:%.*]]) +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @inner3(i8* [[ADDR]]) +; IS__CGSCC____-NEXT: ret i32 [[CALL]] ; %cmp = icmp slt i32 %x, 42 %addr = select i1 %cmp, i8* blockaddress(@inner3, %one), i8* blockaddress(@inner3, %two) @@ -96,8 +124,12 @@ define i32 @outer3(i32 %x) { ret i32 %call } ;. -; CHECK: attributes #[[ATTR0]] = { alwaysinline nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR2]] = { norecurse } -; CHECK: attributes #[[ATTR3]] = { alwaysinline } +; IS__TUNIT____: attributes #[[ATTR0]] = { alwaysinline nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR2]] = { norecurse } +; IS__TUNIT____: attributes #[[ATTR3]] = { alwaysinline } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { alwaysinline nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { alwaysinline } ;. diff --git a/llvm/test/Transforms/Attributor/assumes_info.ll b/llvm/test/Transforms/Attributor/assumes_info.ll index 7575e658fc9d..583369f8e7f7 100644 --- a/llvm/test/Transforms/Attributor/assumes_info.ll +++ b/llvm/test/Transforms/Attributor/assumes_info.ll @@ -21,11 +21,17 @@ entry: } define internal void @foo(i1 %cond) #1 { -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @baz(i1 [[COND]]) -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo +; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: call void @baz(i1 [[COND]]) +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo +; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: call void @baz(i1 [[COND]]) #[[ATTR1]] +; IS__CGSCC____-NEXT: ret void ; entry: call void @baz(i1 %cond) @@ -45,17 +51,29 @@ entry: } define internal void @baz(i1 %Cond) { -; CHECK-LABEL: define {{[^@]+}}@baz -; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i1 [[COND]], false -; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; CHECK: if.then: -; CHECK-NEXT: call void @baz(i1 noundef false) -; CHECK-NEXT: br label [[IF_END]] -; CHECK: if.end: -; CHECK-NEXT: call void @qux() -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@baz +; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i1 [[COND]], false +; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT____: if.then: +; IS__TUNIT____-NEXT: call void @baz(i1 noundef false) +; IS__TUNIT____-NEXT: br label [[IF_END]] +; IS__TUNIT____: if.end: +; IS__TUNIT____-NEXT: call void @qux() +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@baz +; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i1 [[COND]], false +; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__CGSCC____: if.then: +; IS__CGSCC____-NEXT: call void @baz(i1 noundef false) +; IS__CGSCC____-NEXT: br label [[IF_END]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: call void @qux() #[[ATTR3]] +; IS__CGSCC____-NEXT: ret void ; entry: %tobool = icmp ne i1 %Cond, 0 @@ -71,11 +89,16 @@ if.end: } define internal void @qux() { -; CHECK-LABEL: define {{[^@]+}}@qux -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @call() -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@qux +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: call void @call() +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@qux() { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: call void @call() +; IS__CGSCC____-NEXT: ret void ; entry: call void @call() @@ -89,7 +112,12 @@ attributes #1 = { "llvm.assume"="B" } attributes #2 = { "llvm.assume"="B,C" } attributes #3 = { "llvm.assume"="B,C,A" } ;. -; CHECK: attributes #[[ATTR0]] = { "llvm.assume"="A" } -; CHECK: attributes #[[ATTR1]] = { "llvm.assume"="B,A" } -; CHECK: attributes #[[ATTR2]] = { "llvm.assume"="B,C,A" } +; IS__TUNIT____: attributes #[[ATTR0]] = { "llvm.assume"="A" } +; IS__TUNIT____: attributes #[[ATTR1]] = { "llvm.assume"="B,A" } +; IS__TUNIT____: attributes #[[ATTR2]] = { "llvm.assume"="B,C,A" } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { "llvm.assume"="A" } +; IS__CGSCC____: attributes #[[ATTR1]] = { "llvm.assume"="B,A" } +; IS__CGSCC____: attributes #[[ATTR2]] = { "llvm.assume"="B,C,A" } +; IS__CGSCC____: attributes #[[ATTR3]] = { "llvm.assume"="B" } ;. diff --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll index ebbc003ec203..9eb536c02ab2 100644 --- a/llvm/test/Transforms/Attributor/callbacks.ll +++ b/llvm/test/Transforms/Attributor/callbacks.ll @@ -40,29 +40,17 @@ define void @t0_caller(i32* %a) { ; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t0_caller -; IS__CGSCC_OPM-SAME: (i32* align 256 [[A:%.*]]) { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 -; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 -; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32 -; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 -; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) -; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t0_caller -; IS__CGSCC_NPM-SAME: (i32* align 256 [[A:%.*]]) { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 -; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 -; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32 -; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 -; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) -; IS__CGSCC_NPM-NEXT: ret void +; IS__CGSCC____-LABEL: define {{[^@]+}}@t0_caller +; IS__CGSCC____-SAME: (i32* align 256 [[A:%.*]]) { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 32 +; IS__CGSCC____-NEXT: [[C:%.*]] = alloca i32*, align 64 +; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 128 +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* +; IS__CGSCC____-NEXT: store i32 42, i32* [[B]], align 32 +; IS__CGSCC____-NEXT: store i32* [[B]], i32** [[C]], align 64 +; IS__CGSCC____-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC____-NEXT: ret void ; entry: %b = alloca i32, align 32 @@ -79,23 +67,41 @@ entry: ; 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) { ; -; IS________OPM-LABEL: define {{[^@]+}}@t0_callback_callee -; IS________OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS________OPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* noundef nonnull align 32 dereferenceable(4) [[TMP0]]) -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t0_callback_callee +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_OPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* noundef nonnull align 32 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM-LABEL: define {{[^@]+}}@t0_callback_callee -; IS________NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS________NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS________NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS________NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* noundef nonnull align 32 dereferenceable(4) [[TMP0]]) -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_callback_callee +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* noundef nonnull align 32 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t0_callback_callee +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__CGSCC_OPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* [[TMP0]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t0_callback_callee +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__CGSCC_NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 noundef 99, i32* [[TMP0]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 @@ -141,7 +147,7 @@ define void @t1_caller(i32* noalias %a) { ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t1_caller -; IS__CGSCC_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32* noalias align 256 [[A:%.*]]) { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 @@ -149,11 +155,11 @@ define void @t1_caller(i32* noalias %a) { ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* ; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32 ; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 -; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 noundef 99, i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t1_caller -; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) { +; IS__CGSCC_NPM-SAME: (i32* noalias align 256 [[A:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 @@ -161,7 +167,7 @@ define void @t1_caller(i32* noalias %a) { ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* ; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32 ; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 -; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 noundef 99, i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__CGSCC_NPM-NEXT: ret void ; entry: @@ -179,25 +185,45 @@ entry: ; 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) { ; -; IS________OPM: Function Attrs: nosync -; IS________OPM-LABEL: define {{[^@]+}}@t1_callback_callee -; IS________OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS________OPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: nosync +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t1_callback_callee +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_OPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: nosync -; IS________NPM-LABEL: define {{[^@]+}}@t1_callback_callee -; IS________NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS________NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS________NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS________NPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: nosync +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_callback_callee +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: nosync +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t1_callback_callee +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__CGSCC_OPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nosync +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t1_callback_callee +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__CGSCC_NPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 @@ -241,7 +267,7 @@ define void @t2_caller(i32* noalias %a) { ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t2_caller -; IS__CGSCC_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32* noalias align 256 [[A:%.*]]) { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 @@ -249,11 +275,11 @@ define void @t2_caller(i32* noalias %a) { ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* ; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32 ; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 -; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 noundef 99, i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t2_caller -; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) { +; IS__CGSCC_NPM-SAME: (i32* noalias align 256 [[A:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 @@ -261,7 +287,7 @@ define void @t2_caller(i32* noalias %a) { ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* ; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32 ; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 -; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 noundef 99, i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__CGSCC_NPM-NEXT: ret void ; entry: @@ -281,23 +307,41 @@ entry: ; 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) { ; -; IS________OPM-LABEL: define {{[^@]+}}@t2_callback_callee -; IS________OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS________OPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t2_callback_callee +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_OPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM-LABEL: define {{[^@]+}}@t2_callback_callee -; IS________NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS________NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS________NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS________NPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_callback_callee +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t2_callback_callee +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__CGSCC_OPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t2_callback_callee +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__CGSCC_NPM-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 @@ -343,7 +387,7 @@ define void @t3_caller(i32* noalias %a) { ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t3_caller -; IS__CGSCC_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) { +; IS__CGSCC_OPM-SAME: (i32* noalias align 256 [[A:%.*]]) { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32 ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 @@ -351,12 +395,12 @@ define void @t3_caller(i32* noalias %a) { ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* ; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32 ; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 -; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 noundef 99, i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) -; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 noundef 99, i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t3_caller -; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]]) { +; IS__CGSCC_NPM-SAME: (i32* noalias align 256 [[A:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32 ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 @@ -364,8 +408,8 @@ define void @t3_caller(i32* noalias %a) { ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* ; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32 ; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 -; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 noundef 99, i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) -; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 noundef 99, i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias nocapture noundef align 4294967296 null, i32* noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nocapture noundef bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 noundef 99, i32** nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__CGSCC_NPM-NEXT: ret void ; entry: @@ -386,23 +430,41 @@ entry: ; 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) { ; -; IS________OPM-LABEL: define {{[^@]+}}@t3_callback_callee -; IS________OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS________OPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t3_callback_callee +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_OPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM-LABEL: define {{[^@]+}}@t3_callback_callee -; IS________NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 -; IS________NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 -; IS________NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 -; IS________NPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_callback_callee +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__TUNIT_NPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture noundef nonnull align 32 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t3_callback_callee +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__CGSCC_OPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t3_callback_callee +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8 +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64 +; IS__CGSCC_NPM-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]], i64 noundef 99, i32* nocapture [[TMP0]]) +; IS__CGSCC_NPM-NEXT: ret void ; entry: %ptr_val = load i32, i32* %ptr, align 8 diff --git a/llvm/test/Transforms/Attributor/cb_liveness_disabled.ll b/llvm/test/Transforms/Attributor/cb_liveness_disabled.ll index 97ae7ffa3970..d6909dfe5c5e 100644 --- a/llvm/test/Transforms/Attributor/cb_liveness_disabled.ll +++ b/llvm/test/Transforms/Attributor/cb_liveness_disabled.ll @@ -63,19 +63,33 @@ define i32 @test_range2(i32 %0) #0 { ret i32 %.0 } define i32 @test(i32 %0, i32 %1) #0 { -; CHECK-LABEL: define {{[^@]+}}@test -; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0 -; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]] -; CHECK: 4: -; CHECK-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] -; CHECK-NEXT: br label [[TMP8:%.*]] -; CHECK: 6: -; CHECK-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]] -; CHECK-NEXT: br label [[TMP8]] -; CHECK: 8: -; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ] -; CHECK-NEXT: ret i32 [[DOT0]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0 +; IS__TUNIT____-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]] +; IS__TUNIT____: 4: +; IS__TUNIT____-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] +; IS__TUNIT____-NEXT: br label [[TMP8:%.*]] +; IS__TUNIT____: 6: +; IS__TUNIT____-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]] +; IS__TUNIT____-NEXT: br label [[TMP8]] +; IS__TUNIT____: 8: +; IS__TUNIT____-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ] +; IS__TUNIT____-NEXT: ret i32 [[DOT0]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0 +; IS__CGSCC____-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]] +; IS__CGSCC____: 4: +; IS__CGSCC____-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) +; IS__CGSCC____-NEXT: br label [[TMP8:%.*]] +; IS__CGSCC____: 6: +; IS__CGSCC____-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) +; IS__CGSCC____-NEXT: br label [[TMP8]] +; IS__CGSCC____: 8: +; IS__CGSCC____-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ] +; IS__CGSCC____-NEXT: ret i32 [[DOT0]] ; %3 = icmp ne i32 %1, 0 br i1 %3, label %4, label %6 @@ -94,12 +108,19 @@ define i32 @test(i32 %0, i32 %1) #0 { } define i32 @test_pcheck1(i32 %0) #0 { -; CHECK-LABEL: define {{[^@]+}}@test_pcheck1 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2:![0-9]+]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101 -; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 -; CHECK-NEXT: ret i32 [[TMP4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_pcheck1 +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2:![0-9]+]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_pcheck1 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101 +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP4]] ; %2 = call i32 @test(i32 %0, i32 1) %3 = icmp slt i32 %2, 101 @@ -108,12 +129,19 @@ define i32 @test_pcheck1(i32 %0) #0 { } define i32 @test_pcheck2(i32 %0) #0 { -; CHECK-LABEL: define {{[^@]+}}@test_pcheck2 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99 -; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 -; CHECK-NEXT: ret i32 [[TMP4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_pcheck2 +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_pcheck2 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99 +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP4]] ; %2 = call i32 @test(i32 %0, i32 0) %3 = icmp sgt i32 %2, 99 @@ -122,12 +150,19 @@ define i32 @test_pcheck2(i32 %0) #0 { } define i32 @test_ncheck1(i32 %0) #0 { -; CHECK-LABEL: define {{[^@]+}}@test_ncheck1 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50 -; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 -; CHECK-NEXT: ret i32 [[TMP4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_ncheck1 +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_ncheck1 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50 +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP4]] ; %2 = call i32 @test(i32 %0, i32 1) %3 = icmp sgt i32 %2, 50 @@ -136,12 +171,19 @@ define i32 @test_ncheck1(i32 %0) #0 { } define i32 @test_ncheck2(i32 %0) #0 { -; CHECK-LABEL: define {{[^@]+}}@test_ncheck2 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150 -; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 -; CHECK-NEXT: ret i32 [[TMP4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_ncheck2 +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_ncheck2 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150 +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP4]] ; %2 = call i32 @test(i32 %0, i32 0) %3 = icmp sgt i32 %2, 150 @@ -158,9 +200,10 @@ attributes #0 = { noinline nounwind sspstrong uwtable} ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone sspstrong willreturn uwtable } -; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone sspstrong willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { readnone willreturn } ;. -; CHECK: [[RNG0]] = !{i32 0, i32 101} -; CHECK: [[RNG1]] = !{i32 100, i32 201} -; CHECK: [[RNG2]] = !{i32 0, i32 201} +; IS__TUNIT____: [[RNG0]] = !{i32 0, i32 101} +; IS__TUNIT____: [[RNG1]] = !{i32 100, i32 201} +; IS__TUNIT____: [[RNG2]] = !{i32 0, i32 201} ;. diff --git a/llvm/test/Transforms/Attributor/cb_liveness_enabled.ll b/llvm/test/Transforms/Attributor/cb_liveness_enabled.ll index 0b119ed6d332..03537c816d22 100644 --- a/llvm/test/Transforms/Attributor/cb_liveness_enabled.ll +++ b/llvm/test/Transforms/Attributor/cb_liveness_enabled.ll @@ -63,19 +63,33 @@ define i32 @test_range2(i32 %0) #0 { ret i32 %.0 } define i32 @test(i32 %0, i32 %1) #0 { -; CHECK-LABEL: define {{[^@]+}}@test -; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0 -; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]] -; CHECK: 4: -; CHECK-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] -; CHECK-NEXT: br label [[TMP8:%.*]] -; CHECK: 6: -; CHECK-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]] -; CHECK-NEXT: br label [[TMP8]] -; CHECK: 8: -; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ] -; CHECK-NEXT: ret i32 [[DOT0]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0 +; IS__TUNIT____-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]] +; IS__TUNIT____: 4: +; IS__TUNIT____-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] +; IS__TUNIT____-NEXT: br label [[TMP8:%.*]] +; IS__TUNIT____: 6: +; IS__TUNIT____-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]] +; IS__TUNIT____-NEXT: br label [[TMP8]] +; IS__TUNIT____: 8: +; IS__TUNIT____-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ] +; IS__TUNIT____-NEXT: ret i32 [[DOT0]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0 +; IS__CGSCC____-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]] +; IS__CGSCC____: 4: +; IS__CGSCC____-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) +; IS__CGSCC____-NEXT: br label [[TMP8:%.*]] +; IS__CGSCC____: 6: +; IS__CGSCC____-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) +; IS__CGSCC____-NEXT: br label [[TMP8]] +; IS__CGSCC____: 8: +; IS__CGSCC____-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ] +; IS__CGSCC____-NEXT: ret i32 [[DOT0]] ; %3 = icmp ne i32 %1, 0 br i1 %3, label %4, label %6 @@ -94,12 +108,19 @@ define i32 @test(i32 %0, i32 %1) #0 { } define i32 @test_pcheck1(i32 %0) #0 { -; CHECK-LABEL: define {{[^@]+}}@test_pcheck1 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2:![0-9]+]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101 -; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 -; CHECK-NEXT: ret i32 [[TMP4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_pcheck1 +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2:![0-9]+]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_pcheck1 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101 +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP4]] ; ; IS__TUNIT_____ENABLED-LABEL: define {{[^@]+}}@test_pcheck1 ; IS__TUNIT_____ENABLED-SAME: (i32 [[TMP0:%.*]]) @@ -111,12 +132,19 @@ define i32 @test_pcheck1(i32 %0) #0 { } define i32 @test_pcheck2(i32 %0) #0 { -; CHECK-LABEL: define {{[^@]+}}@test_pcheck2 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99 -; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 -; CHECK-NEXT: ret i32 [[TMP4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_pcheck2 +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_pcheck2 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99 +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP4]] ; %2 = call i32 @test(i32 %0, i32 0) %3 = icmp sgt i32 %2, 99 @@ -125,12 +153,19 @@ define i32 @test_pcheck2(i32 %0) #0 { } define i32 @test_ncheck1(i32 %0) #0 { -; CHECK-LABEL: define {{[^@]+}}@test_ncheck1 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50 -; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 -; CHECK-NEXT: ret i32 [[TMP4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_ncheck1 +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_ncheck1 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50 +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP4]] ; %2 = call i32 @test(i32 %0, i32 1) %3 = icmp sgt i32 %2, 50 @@ -139,12 +174,19 @@ define i32 @test_ncheck1(i32 %0) #0 { } define i32 @test_ncheck2(i32 %0) #0 { -; CHECK-LABEL: define {{[^@]+}}@test_ncheck2 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150 -; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 -; CHECK-NEXT: ret i32 [[TMP4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_ncheck2 +; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_ncheck2 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150 +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP4]] ; %2 = call i32 @test(i32 %0, i32 0) %3 = icmp sgt i32 %2, 150 @@ -161,9 +203,10 @@ attributes #0 = { noinline nounwind sspstrong uwtable} ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone sspstrong willreturn uwtable } -; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone sspstrong willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { readnone willreturn } ;. -; CHECK: [[RNG0]] = !{i32 0, i32 101} -; CHECK: [[RNG1]] = !{i32 100, i32 201} -; CHECK: [[RNG2]] = !{i32 0, i32 201} +; IS__TUNIT____: [[RNG0]] = !{i32 0, i32 101} +; IS__TUNIT____: [[RNG1]] = !{i32 100, i32 201} +; IS__TUNIT____: [[RNG2]] = !{i32 0, i32 201} ;. diff --git a/llvm/test/Transforms/Attributor/cb_range_disabled.ll b/llvm/test/Transforms/Attributor/cb_range_disabled.ll index b137946d01a9..4a925549bc24 100644 --- a/llvm/test/Transforms/Attributor/cb_range_disabled.ll +++ b/llvm/test/Transforms/Attributor/cb_range_disabled.ll @@ -22,11 +22,17 @@ define i32 @test_range(i32 %unknown) { } define i32 @test1(i32 %unknown, i32 %b) { -; CHECK-LABEL: define {{[^@]+}}@test1 -; CHECK-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] -; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i32 [[TMP1]], [[B]] -; CHECK-NEXT: ret i32 [[TMP2]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1 +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = sub nsw i32 [[TMP1]], [[B]] +; IS__TUNIT____-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1 +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = sub nsw i32 [[TMP1]], [[B]] +; IS__CGSCC____-NEXT: ret i32 [[TMP2]] ; %1 = call i32 @test_range(i32 %unknown) %2 = sub nsw i32 %1, %b @@ -34,11 +40,17 @@ define i32 @test1(i32 %unknown, i32 %b) { } define i32 @test2(i32 %unknown, i32 %b) { -; CHECK-LABEL: define {{[^@]+}}@test2 -; CHECK-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) #[[ATTR1]], !range [[RNG0]] -; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[B]] -; CHECK-NEXT: ret i32 [[TMP2]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2 +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) #[[ATTR1]], !range [[RNG0]] +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[B]] +; IS__TUNIT____-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2 +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[B]] +; IS__CGSCC____-NEXT: ret i32 [[TMP2]] ; %1 = call i32 @test_range(i32 %unknown) %2 = add nsw i32 %1, %b @@ -48,19 +60,19 @@ define i32 @test2(i32 %unknown, i32 %b) { ; Positive checks define i32 @test1_pcheck(i32 %unknown) { -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test1_pcheck -; NOT_CGSCC_NPM-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; NOT_CGSCC_NPM-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) -; NOT_CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90 -; NOT_CGSCC_NPM-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 -; NOT_CGSCC_NPM-NEXT: ret i32 [[TMP3]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_pcheck +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90 +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP3]] ; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test1_pcheck -; IS__CGSCC_NPM-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1:![0-9]+]] -; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90 -; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 -; IS__CGSCC_NPM-NEXT: ret i32 [[TMP3]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_pcheck +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = call i32 @test1(i32 %unknown, i32 20) %2 = icmp sle i32 %1, 90 @@ -69,12 +81,19 @@ define i32 @test1_pcheck(i32 %unknown) { } define i32 @test2_pcheck(i32 %unknown) { -; CHECK-LABEL: define {{[^@]+}}@test2_pcheck -; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) -; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20 -; CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 -; CHECK-NEXT: ret i32 [[TMP3]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_pcheck +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20 +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_pcheck +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = call i32 @test2(i32 %unknown, i32 20) %2 = icmp sge i32 %1, 20 @@ -85,19 +104,19 @@ define i32 @test2_pcheck(i32 %unknown) { ; Negative checks define i32 @test1_ncheck(i32 %unknown) { -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test1_ncheck -; NOT_CGSCC_NPM-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; NOT_CGSCC_NPM-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) -; NOT_CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10 -; NOT_CGSCC_NPM-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 -; NOT_CGSCC_NPM-NEXT: ret i32 [[TMP3]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_ncheck +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10 +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP3]] ; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test1_ncheck -; IS__CGSCC_NPM-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1]] -; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10 -; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 -; IS__CGSCC_NPM-NEXT: ret i32 [[TMP3]] +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_ncheck +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = call i32 @test1(i32 %unknown, i32 20) %2 = icmp sle i32 %1, 10 @@ -106,12 +125,19 @@ define i32 @test1_ncheck(i32 %unknown) { } define i32 @test2_ncheck(i32 %unknown) { -; CHECK-LABEL: define {{[^@]+}}@test2_ncheck -; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) -; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30 -; CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 -; CHECK-NEXT: ret i32 [[TMP3]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_ncheck +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30 +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_ncheck +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = call i32 @test2(i32 %unknown, i32 20) %2 = icmp sge i32 %1, 30 @@ -123,10 +149,8 @@ define i32 @test2_ncheck(i32 %unknown) { ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { readnone willreturn } ;. -; NOT_CGSCC_NPM: [[RNG0]] = !{i32 0, i32 101} -;. -; IS__CGSCC_NPM: [[RNG0]] = !{i32 0, i32 101} -; IS__CGSCC_NPM: [[RNG1]] = !{i32 -2147483647, i32 -2147483648} +; IS__TUNIT____: [[RNG0]] = !{i32 0, i32 101} ;. diff --git a/llvm/test/Transforms/Attributor/cb_range_enabled.ll b/llvm/test/Transforms/Attributor/cb_range_enabled.ll index 70e2710d3260..d61009a37122 100644 --- a/llvm/test/Transforms/Attributor/cb_range_enabled.ll +++ b/llvm/test/Transforms/Attributor/cb_range_enabled.ll @@ -22,11 +22,17 @@ define i32 @test_range(i32 %unknown) { } define i32 @test1(i32 %unknown, i32 %b) { -; CHECK-LABEL: define {{[^@]+}}@test1 -; CHECK-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] -; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i32 [[TMP1]], [[B]] -; CHECK-NEXT: ret i32 [[TMP2]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1 +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = sub nsw i32 [[TMP1]], [[B]] +; IS__TUNIT____-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1 +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = sub nsw i32 [[TMP1]], [[B]] +; IS__CGSCC____-NEXT: ret i32 [[TMP2]] ; %1 = call i32 @test_range(i32 %unknown) %2 = sub nsw i32 %1, %b @@ -34,11 +40,17 @@ define i32 @test1(i32 %unknown, i32 %b) { } define i32 @test2(i32 %unknown, i32 %b) { -; CHECK-LABEL: define {{[^@]+}}@test2 -; CHECK-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) #[[ATTR1]], !range [[RNG0]] -; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[B]] -; CHECK-NEXT: ret i32 [[TMP2]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2 +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) #[[ATTR1]], !range [[RNG0]] +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[B]] +; IS__TUNIT____-NEXT: ret i32 [[TMP2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2 +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]], i32 [[B:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test_range(i32 [[UNKNOWN]]) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[B]] +; IS__CGSCC____-NEXT: ret i32 [[TMP2]] ; %1 = call i32 @test_range(i32 %unknown) %2 = add nsw i32 %1, %b @@ -52,9 +64,16 @@ define i32 @test2(i32 %unknown, i32 %b) { ; we need to look into this again. For the purpose of making some progress we take this regression ; for now, call site contexts are not on by default anyway (yet). define i32 @test1_pcheck(i32 %unknown) { -; CHECK-LABEL: define {{[^@]+}}@test1_pcheck -; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: ret i32 1 +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_pcheck +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32 1 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_pcheck +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = call i32 @test1(i32 %unknown, i32 20) %2 = icmp sle i32 %1, 90 @@ -63,9 +82,16 @@ define i32 @test1_pcheck(i32 %unknown) { } define i32 @test2_pcheck(i32 %unknown) { -; CHECK-LABEL: define {{[^@]+}}@test2_pcheck -; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: ret i32 1 +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_pcheck +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32 1 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_pcheck +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = call i32 @test2(i32 %unknown, i32 20) %2 = icmp sge i32 %1, 20 @@ -76,12 +102,19 @@ define i32 @test2_pcheck(i32 %unknown) { ; Negative checks define i32 @test1_ncheck(i32 %unknown) { -; CHECK-LABEL: define {{[^@]+}}@test1_ncheck -; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1:![0-9]+]] -; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10 -; CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 -; CHECK-NEXT: ret i32 [[TMP3]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_ncheck +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1:![0-9]+]] +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10 +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_ncheck +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = call i32 @test1(i32 %unknown, i32 20) %2 = icmp sle i32 %1, 10 @@ -90,12 +123,19 @@ define i32 @test1_ncheck(i32 %unknown) { } define i32 @test2_ncheck(i32 %unknown) { -; CHECK-LABEL: define {{[^@]+}}@test2_ncheck -; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG2:![0-9]+]] -; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30 -; CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 -; CHECK-NEXT: ret i32 [[TMP3]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_ncheck +; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG2:![0-9]+]] +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30 +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__TUNIT____-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_ncheck +; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = call i32 @test2(i32 %unknown, i32 20) %2 = icmp sge i32 %1, 30 @@ -107,9 +147,10 @@ define i32 @test2_ncheck(i32 %unknown) { ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { readnone willreturn } ;. -; CHECK: [[RNG0]] = !{i32 0, i32 101} -; CHECK: [[RNG1]] = !{i32 -20, i32 81} -; CHECK: [[RNG2]] = !{i32 20, i32 121} +; IS__TUNIT____: [[RNG0]] = !{i32 0, i32 101} +; IS__TUNIT____: [[RNG1]] = !{i32 -20, i32 81} +; IS__TUNIT____: [[RNG2]] = !{i32 20, i32 121} ;. diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll index 85a7b0de709f..fa552f82c6b4 100644 --- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll @@ -498,23 +498,41 @@ for.body: ; preds = %entry, %for.body } define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range) { -; IS________OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind -; IS________OPM-LABEL: define {{[^@]+}}@call_fill_range -; IS________OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR4:[0-9]+]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]] -; IS________OPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR7:[0-9]+]] -; IS________OPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR7]] -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@call_fill_range +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]] +; IS__TUNIT_OPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR7:[0-9]+]] +; IS__TUNIT_OPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn -; IS________NPM-LABEL: define {{[^@]+}}@call_fill_range -; IS________NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR3:[0-9]+]] { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]] -; IS________NPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6:[0-9]+]] -; IS________NPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6]] -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@call_fill_range +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]] +; IS__TUNIT_NPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6:[0-9]+]] +; IS__TUNIT_NPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@call_fill_range +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]] +; IS__CGSCC_OPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR7:[0-9]+]] +; IS__CGSCC_OPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@call_fill_range +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range [[RNG0:![0-9]+]] +; IS__CGSCC_NPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6:[0-9]+]] +; IS__CGSCC_NPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: ret void ; entry: %0 = load i64, i64* %range, align 8, !range !0 @@ -974,7 +992,7 @@ f: ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR6:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind writeonly } @@ -985,7 +1003,7 @@ f: ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR3]] = { argmemonly nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind writeonly } ; IS__CGSCC_NPM: attributes #[[ATTR5:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind willreturn writeonly } diff --git a/llvm/test/Transforms/Attributor/internal-noalias.ll b/llvm/test/Transforms/Attributor/internal-noalias.ll index 6d7d8cc55ad7..95046349bb6c 100644 --- a/llvm/test/Transforms/Attributor/internal-noalias.ll +++ b/llvm/test/Transforms/Attributor/internal-noalias.ll @@ -14,12 +14,12 @@ define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 { ; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; IS__TUNIT____-NEXT: ret i32 [[ADD]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly willreturn uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@visible ; IS__CGSCC____-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR4:[0-9]+]] -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR5:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR5]] ; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; IS__CGSCC____-NEXT: ret i32 [[ADD]] ; @@ -42,14 +42,14 @@ define private i32 @noalias_args(i32* %A, i32* %B) #0 { ; IS__TUNIT____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] ; IS__TUNIT____-NEXT: ret i32 [[ADD2]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly willreturn uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0]] { ; IS__CGSCC____-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 noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR5]] ; IS__CGSCC____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]] ; IS__CGSCC____-NEXT: ret i32 [[ADD2]] ; @@ -64,14 +64,23 @@ entry: define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 { -; CHECK: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@noalias_args_argmem -; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 -; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] -; CHECK-NEXT: ret i32 [[ADD]] +; IS__TUNIT____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@noalias_args_argmem +; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +; IS__TUNIT____-NEXT: ret i32 [[ADD]] +; +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem +; 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:%.*]]) #[[ATTR1:[0-9]+]] { +; 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: ret i32 [[ADD]] ; entry: %0 = load i32, i32* %A, align 4 @@ -92,13 +101,13 @@ define dso_local i32 @visible_local(i32* %A) #0 { ; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; IS__TUNIT____-NEXT: ret i32 [[ADD]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 ; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4 -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) #[[ATTR5]] ; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @noalias_args_argmem(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]]) ; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]] ; IS__CGSCC____-NEXT: ret i32 [[ADD]] @@ -113,10 +122,25 @@ entry: } define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 { -; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable -; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem_ro -; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { -; IS__CGSCC____-NEXT: ret i32 10 +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; 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:%.*]]) #[[ATTR1]] { +; 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: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@noalias_args_argmem_ro +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR1]] { +; 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 @@ -131,11 +155,19 @@ define i32 @visible_local_2() { ; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32, align 4 ; IS__TUNIT____-NEXT: ret i32 10 ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local_2 -; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 -; IS__CGSCC____-NEXT: ret i32 10 +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@visible_local_2 +; IS__CGSCC_OPM-SAME: () #[[ATTR3:[0-9]+]] { +; 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]]) #[[ATTR6:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@visible_local_2 +; IS__CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32 noundef 5, i32 noundef 5) #[[ATTR6:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; %B = alloca i32, align 4 store i32 5, i32* %B, align 4 @@ -144,11 +176,18 @@ define i32 @visible_local_2() { } define internal i32 @noalias_args_argmem_rn(i32* %A, i32* %B) #1 { -; CHECK: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@noalias_args_argmem_rn -; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[B]], align 4 -; CHECK-NEXT: ret i32 [[T0]] +; IS__TUNIT____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@noalias_args_argmem_rn +; IS__TUNIT____-SAME: (i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: [[T0:%.*]] = load i32, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: ret i32 [[T0]] +; +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem_rn +; IS__CGSCC____-SAME: (i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR4:[0-9]+]] { +; 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]] ; %t0 = load i32, i32* %B, align 4 store i32 0, i32* %B @@ -164,12 +203,13 @@ define i32 @visible_local_3() { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B]]) #[[ATTR4:[0-9]+]] ; IS__TUNIT____-NEXT: ret i32 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local_3 -; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { ; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4 ; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4 -; IS__CGSCC____-NEXT: ret i32 5 +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[B]]) #[[ATTR7:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[CALL]] ; %B = alloca i32, align 4 store i32 5, i32* %B, align 4 @@ -186,9 +226,12 @@ attributes #1 = { argmemonly noinline nounwind uwtable willreturn} ; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind readonly } ; IS__TUNIT____: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn } ;. -; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } -; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR4]] = { readonly } +; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree noinline nosync nounwind readonly willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR2]] = { argmemonly nofree noinline nosync nounwind willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR4]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR5]] = { readonly } +; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR7]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll index 5240daf0b9f4..1af967dafd98 100644 --- a/llvm/test/Transforms/Attributor/liveness.ll +++ b/llvm/test/Transforms/Attributor/liveness.ll @@ -2223,8 +2223,8 @@ define i32 @switch_default_caller() { ; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@switch_default_caller ; IS__CGSCC____-SAME: () #[[ATTR12]] { -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = tail call i32 @switch_default() #[[ATTR15]] -; IS__CGSCC____-NEXT: ret i32 123 +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = tail call noundef i32 @switch_default() #[[ATTR15]] +; IS__CGSCC____-NEXT: ret i32 [[CALL2]] ; %call2 = tail call i32 @switch_default(i64 0) ret i32 %call2 @@ -2263,10 +2263,11 @@ define i32 @switch_default_dead_caller() { ; NOT_CGSCC_NPM-SAME: () #[[ATTR11:[0-9]+]] { ; NOT_CGSCC_NPM-NEXT: ret i32 123 ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@switch_default_dead_caller -; IS__CGSCC____-SAME: () #[[ATTR6]] { -; IS__CGSCC____-NEXT: ret i32 123 +; IS__CGSCC____-SAME: () #[[ATTR11]] { +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = tail call noundef i32 @switch_default_dead() #[[ATTR16:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[CALL2]] ; %call2 = tail call i32 @switch_default_dead(i64 0) ret i32 %call2 @@ -2283,19 +2284,29 @@ define void @call_via_pointer_with_dead_args(i32* %a, i32* %b, void (i32*, i32*, } define internal void @call_via_pointer_with_dead_args_internal_a(i32* %a, i32* %b, void (i32*, i32*, i32*, i64, i32**)* %fp) { -; CHECK-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_a -; CHECK-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]]) { -; CHECK-NEXT: call void poison(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null) -; CHECK-NEXT: ret void +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_a +; NOT_CGSCC_NPM-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]]) { +; NOT_CGSCC_NPM-NEXT: call void poison(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null) +; NOT_CGSCC_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_a +; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull [[FP:%.*]]) { +; IS__CGSCC____-NEXT: call void [[FP]](i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null) +; IS__CGSCC____-NEXT: ret void ; call void %fp(i32* %a, i32* %b, i32* %a, i64 -1, i32** null) ret void } define internal void @call_via_pointer_with_dead_args_internal_b(i32* %a, i32* %b, void (i32*, i32*, i32*, i64, i32**)* %fp) { -; CHECK-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_b -; CHECK-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]]) { -; CHECK-NEXT: call void poison(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null) -; CHECK-NEXT: ret void +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_b +; NOT_CGSCC_NPM-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]]) { +; NOT_CGSCC_NPM-NEXT: call void poison(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null) +; NOT_CGSCC_NPM-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_b +; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull [[FP:%.*]]) { +; IS__CGSCC____-NEXT: call void [[FP]](i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null) +; IS__CGSCC____-NEXT: ret void ; call void %fp(i32* %a, i32* %b, i32* %a, i64 -1, i32** null) ret void @@ -2321,8 +2332,8 @@ define void @call_via_pointer_with_dead_args_caller(i32* %a, i32* %b) { ; IS__CGSCC____-NEXT: [[PTR4:%.*]] = alloca i32, align 128 ; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull @called_via_pointer) ; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull @called_via_pointer_internal_1) -; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR3]]) -; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR4]]) +; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR3]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull @called_via_pointer) +; IS__CGSCC____-NEXT: call void @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR4]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull @called_via_pointer_internal_2) ; IS__CGSCC____-NEXT: ret void ; %ptr1 = alloca i32, align 128 @@ -2364,7 +2375,7 @@ entry: ; FIXME: Figure out why the MODULE has the unused arguments still define internal void @called_via_pointer_internal_2(i32* %a, i32* %b, i32* %c, i64 %d, i32** %e) { ; IS__CGSCC____-LABEL: define {{[^@]+}}@called_via_pointer_internal_2 -; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* [[B:%.*]], i32* [[C:%.*]], i64 [[D:%.*]], i32** [[E:%.*]]) { +; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* nocapture nofree readnone [[B:%.*]], i32* nocapture nofree readnone [[C:%.*]], i64 [[D:%.*]], i32** nocapture nofree readnone [[E:%.*]]) { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: tail call void @use_i32p(i32* [[A]]) ; IS__CGSCC____-NEXT: tail call void @use_i32p(i32* [[A]]) @@ -2575,7 +2586,7 @@ define void @bad_gep() { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[N:%.*]] = alloca i8, align 1 ; IS__CGSCC____-NEXT: [[M:%.*]] = alloca i8, align 1 -; IS__CGSCC____-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1, i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[N]]) #[[ATTR16:[0-9]+]] +; IS__CGSCC____-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1, i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[N]]) #[[ATTR17:[0-9]+]] ; IS__CGSCC____-NEXT: br label [[EXIT:%.*]] ; IS__CGSCC____: while.body: ; IS__CGSCC____-NEXT: unreachable @@ -2584,7 +2595,7 @@ define void @bad_gep() { ; IS__CGSCC____: if.end: ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: exit: -; IS__CGSCC____-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 1, i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[N]]) #[[ATTR16]] +; IS__CGSCC____-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 1, i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[N]]) #[[ATTR17]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -2682,5 +2693,6 @@ declare void @llvm.lifetime.end.p0i8(i64 %0, i8* %1) ; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind readonly } ; IS__CGSCC____: attributes #[[ATTR14:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR15]] = { nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR16]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR16]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR17]] = { willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/memory_locations.ll b/llvm/test/Transforms/Attributor/memory_locations.ll index 5a6c344760e4..9937dd649c5c 100644 --- a/llvm/test/Transforms/Attributor/memory_locations.ll +++ b/llvm/test/Transforms/Attributor/memory_locations.ll @@ -122,18 +122,11 @@ return: ; preds = %if.end, %if.then define dso_local i8* @internal_only_rec_static_helper_malloc_noescape(i32 %arg) { ; FIXME: This is actually inaccessiblememonly because the malloced memory does not escape -; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_only_rec_static_helper_malloc_noescape -; IS__TUNIT____-SAME: (i32 [[ARG:%.*]]) { -; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[CALL:%.*]] = call noalias i8* @internal_only_rec_static_malloc_noescape(i32 [[ARG]]) -; IS__TUNIT____-NEXT: ret i8* [[CALL]] -; -; IS__CGSCC____: Function Attrs: inaccessiblememonly -; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_only_rec_static_helper_malloc_noescape -; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] { -; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call noalias i8* @internal_only_rec_static_malloc_noescape(i32 [[ARG]]) -; IS__CGSCC____-NEXT: ret i8* [[CALL]] +; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_helper_malloc_noescape +; CHECK-SAME: (i32 [[ARG:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @internal_only_rec_static_malloc_noescape(i32 [[ARG]]) +; CHECK-NEXT: ret i8* [[CALL]] ; entry: %call = call i8* @internal_only_rec_static_malloc_noescape(i32 %arg) @@ -439,21 +432,33 @@ define internal void @write_global_via_arg_internal(i32* %GPtr) { } define void @writeonly_global() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@writeonly_global -; CHECK-SAME: () #[[ATTR6]] { -; CHECK-NEXT: call void @write_global() #[[ATTR10:[0-9]+]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@writeonly_global +; IS__TUNIT____-SAME: () #[[ATTR6]] { +; IS__TUNIT____-NEXT: call void @write_global() #[[ATTR10:[0-9]+]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@writeonly_global +; IS__CGSCC____-SAME: () #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-NEXT: call void @write_global() #[[ATTR11:[0-9]+]] +; IS__CGSCC____-NEXT: ret void ; call void @write_global() ret void } define void @writeonly_global_via_arg() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@writeonly_global_via_arg -; CHECK-SAME: () #[[ATTR6]] { -; CHECK-NEXT: call void @write_global_via_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) @G) #[[ATTR10]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@writeonly_global_via_arg +; IS__TUNIT____-SAME: () #[[ATTR6]] { +; IS__TUNIT____-NEXT: call void @write_global_via_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) @G) #[[ATTR10]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@writeonly_global_via_arg +; IS__CGSCC____-SAME: () #[[ATTR8]] { +; IS__CGSCC____-NEXT: call void @write_global_via_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) @G) #[[ATTR11]] +; IS__CGSCC____-NEXT: ret void ; call void @write_global_via_arg(i32* @G) ret void @@ -461,28 +466,46 @@ define void @writeonly_global_via_arg() { define void @writeonly_global_via_arg_internal() { ; -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal -; CHECK-SAME: () #[[ATTR6]] { -; CHECK-NEXT: call void @write_global_via_arg_internal() #[[ATTR10]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal +; IS__TUNIT____-SAME: () #[[ATTR6]] { +; IS__TUNIT____-NEXT: call void @write_global_via_arg_internal() #[[ATTR10]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal +; IS__CGSCC____-SAME: () #[[ATTR8]] { +; IS__CGSCC____-NEXT: call void @write_global_via_arg_internal() #[[ATTR11]] +; IS__CGSCC____-NEXT: ret void ; call void @write_global_via_arg_internal(i32* @G) ret void } define i8 @recursive_not_readnone(i8* %ptr, i1 %c) { -; CHECK: Function Attrs: argmemonly nofree nosync nounwind writeonly -; CHECK-LABEL: define {{[^@]+}}@recursive_not_readnone -; CHECK-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8:[0-9]+]] { -; 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(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11:[0-9]+]] -; CHECK-NEXT: ret i8 1 -; CHECK: f: -; CHECK-NEXT: store i8 1, i8* [[PTR]], align 1 -; CHECK-NEXT: ret i8 0 +; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone +; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8:[0-9]+]] { +; 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(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11:[0-9]+]] +; IS__TUNIT____-NEXT: ret i8 1 +; 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 writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone +; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] { +; 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(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR12:[0-9]+]] +; IS__CGSCC____-NEXT: ret i8 1 +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i8 1, i8* [[PTR]], align 1 +; IS__CGSCC____-NEXT: ret i8 0 ; %alloc = alloca i8 br i1 %c, label %t, label %f @@ -496,16 +519,28 @@ f: } define internal i8 @recursive_not_readnone_internal(i8* %ptr, i1 %c) { -; CHECK: Function Attrs: argmemonly nofree nosync nounwind writeonly -; CHECK-LABEL: define {{[^@]+}}@recursive_not_readnone_internal -; CHECK-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { -; 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 noundef false) #[[ATTR11]] -; CHECK-NEXT: ret i8 1 -; CHECK: f: -; CHECK-NEXT: ret i8 0 +; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal +; IS__TUNIT____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { +; 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 noundef false) #[[ATTR11]] +; IS__TUNIT____-NEXT: ret i8 1 +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: ret i8 0 +; +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal +; IS__CGSCC____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR9]] { +; 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 noundef false) #[[ATTR12]] +; IS__CGSCC____-NEXT: ret i8 1 +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i8 1, i8* [[PTR]], align 1 +; IS__CGSCC____-NEXT: ret i8 0 ; %alloc = alloca i8 br i1 %c, label %t, label %f @@ -526,11 +561,11 @@ define i8 @readnone_caller(i1 %c) { ; IS__TUNIT____-NEXT: [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[A]], i1 [[C]]) #[[ATTR11]], !range [[RNG0:![0-9]+]] ; IS__TUNIT____-NEXT: ret i8 [[R]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC____-LABEL: define {{[^@]+}}@readnone_caller -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i8, align 1 -; IS__CGSCC____-NEXT: [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull readnone dereferenceable(1) [[A]], i1 [[C]]) #[[ATTR12:[0-9]+]], !range [[RNG0:![0-9]+]] +; IS__CGSCC____-NEXT: [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[A]], i1 [[C]]) #[[ATTR13:[0-9]+]] ; IS__CGSCC____-NEXT: ret i8 [[R]] ; %a = alloca i8 @@ -539,16 +574,27 @@ define i8 @readnone_caller(i1 %c) { } define internal i8 @recursive_readnone_internal2(i8* %ptr, i1 %c) { -; CHECK: Function Attrs: argmemonly nofree nosync nounwind writeonly -; CHECK-LABEL: define {{[^@]+}}@recursive_readnone_internal2 -; CHECK-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: [[TMP1:%.*]] = call i8 @recursive_readnone_internal2(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]] -; CHECK-NEXT: ret i8 1 -; CHECK: f: -; CHECK-NEXT: ret i8 0 +; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_readnone_internal2 +; IS__TUNIT____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { +; 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_readnone_internal2(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]] +; IS__TUNIT____-NEXT: ret i8 1 +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: ret i8 0 +; +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_readnone_internal2 +; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR9]] { +; 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_readnone_internal2(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR12]] +; IS__CGSCC____-NEXT: ret i8 1 +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: ret i8 0 ; %alloc = alloca i8 br i1 %c, label %t, label %f @@ -568,10 +614,10 @@ define i8 @readnone_caller2(i1 %c) { ; IS__TUNIT____-NEXT: [[R:%.*]] = call noundef i8 @recursive_readnone_internal2(i8* undef, i1 [[C]]) #[[ATTR11]], !range [[RNG0]] ; IS__TUNIT____-NEXT: ret i8 [[R]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC____-LABEL: define {{[^@]+}}@readnone_caller2 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR9]] { -; IS__CGSCC____-NEXT: [[R:%.*]] = call noundef i8 @recursive_readnone_internal2(i8* undef, i1 [[C]]) #[[ATTR12]], !range [[RNG0]] +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-NEXT: [[R:%.*]] = call noundef i8 @recursive_readnone_internal2(i8* undef, i1 [[C]]) #[[ATTR13]] ; IS__CGSCC____-NEXT: ret i8 [[R]] ; %r = call i8 @recursive_readnone_internal2(i8* undef, i1 %c) @@ -579,16 +625,28 @@ define i8 @readnone_caller2(i1 %c) { } define internal i8 @recursive_not_readnone_internal3(i8* %ptr, i1 %c) { -; CHECK: Function Attrs: argmemonly nofree nosync nounwind writeonly -; CHECK-LABEL: define {{[^@]+}}@recursive_not_readnone_internal3 -; CHECK-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { -; 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_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]] -; CHECK-NEXT: ret i8 1 -; CHECK: f: -; CHECK-NEXT: ret i8 0 +; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal3 +; IS__TUNIT____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] { +; 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_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR11]] +; IS__TUNIT____-NEXT: ret i8 1 +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: ret i8 0 +; +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal3 +; IS__CGSCC____-SAME: (i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR9]] { +; 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_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 noundef false) #[[ATTR12]] +; IS__CGSCC____-NEXT: ret i8 1 +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i8 1, i8* [[PTR]], align 1 +; IS__CGSCC____-NEXT: ret i8 0 ; %alloc = alloca i8 br i1 %c, label %t, label %f @@ -609,11 +667,11 @@ define i8 @readnone_caller3(i1 %c) { ; IS__TUNIT____-NEXT: [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 [[C]]) #[[ATTR11]], !range [[RNG0]] ; IS__TUNIT____-NEXT: ret i8 [[R]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC____-LABEL: define {{[^@]+}}@readnone_caller3 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR10]] { ; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 -; IS__CGSCC____-NEXT: [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal3(i8* noalias nocapture nofree noundef nonnull readnone dereferenceable(1) [[ALLOC]], i1 [[C]]) #[[ATTR12]], !range [[RNG0]] +; IS__CGSCC____-NEXT: [[R:%.*]] = call noundef i8 @recursive_not_readnone_internal3(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[ALLOC]], i1 [[C]]) #[[ATTR13]] ; IS__CGSCC____-NEXT: ret i8 [[R]] ; %alloc = alloca i8 @@ -633,11 +691,17 @@ define internal void @argmemonly_before_ipconstprop(i32* %p) argmemonly { } define void @argmemonky_caller() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@argmemonky_caller -; CHECK-SAME: () #[[ATTR6]] { -; CHECK-NEXT: call void @argmemonly_before_ipconstprop() #[[ATTR10]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@argmemonky_caller +; IS__TUNIT____-SAME: () #[[ATTR6]] { +; IS__TUNIT____-NEXT: call void @argmemonly_before_ipconstprop() #[[ATTR10]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@argmemonky_caller +; IS__CGSCC____-SAME: () #[[ATTR8]] { +; IS__CGSCC____-NEXT: call void @argmemonly_before_ipconstprop() #[[ATTR11]] +; IS__CGSCC____-NEXT: ret void ; call void @argmemonly_before_ipconstprop(i32* @G) ret void @@ -664,11 +728,12 @@ define void @argmemonky_caller() { ; IS__CGSCC____: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR7]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree nosync nounwind writeonly } -; IS__CGSCC____: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR11]] = { nofree nosync nounwind writeonly } -; IS__CGSCC____: attributes #[[ATTR12]] = { nounwind readnone } +; IS__CGSCC____: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree nosync nounwind writeonly } +; IS__CGSCC____: attributes #[[ATTR10]] = { nofree nosync nounwind readnone } +; IS__CGSCC____: attributes #[[ATTR11]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR12]] = { nofree nosync nounwind writeonly } +; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind writeonly } ;. -; CHECK: [[META0:![0-9]+]] = !{i8 0, i8 2} +; IS__TUNIT____: [[RNG0]] = !{i8 0, i8 2} ;. diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll index 38cab82b83e4..6b49c3e1f7e1 100644 --- a/llvm/test/Transforms/Attributor/noalias.ll +++ b/llvm/test/Transforms/Attributor/noalias.ll @@ -103,28 +103,46 @@ define i8* @call_alias(){ ; } define i8* @bar() nounwind uwtable { -; CHECK: Function Attrs: nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@bar -; CHECK-SAME: () #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR2:[0-9]+]] -; CHECK-NEXT: ret i8* [[TMP1]] +; NOT_CGSCC_NPM: Function Attrs: nounwind uwtable +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@bar +; NOT_CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR2:[0-9]+]] +; NOT_CGSCC_NPM-NEXT: ret i8* [[TMP1]] +; +; IS__CGSCC____: Function Attrs: nounwind uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@bar +; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz() #[[ATTR3:[0-9]+]] +; IS__CGSCC____-NEXT: ret i8* [[TMP1]] ; %1 = tail call i8* (...) @baz() ret i8* %1 } define i8* @foo1(i32 %0) nounwind uwtable { -; CHECK: Function Attrs: nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@foo1 -; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 -; CHECK-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] -; CHECK: 3: -; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR2]] -; CHECK-NEXT: br label [[TMP5]] -; CHECK: 5: -; CHECK-NEXT: [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) -; CHECK-NEXT: ret i8* [[TMP6]] +; NOT_CGSCC_NPM: Function Attrs: nounwind uwtable +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo1 +; NOT_CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; NOT_CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 +; NOT_CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] +; NOT_CGSCC_NPM: 3: +; NOT_CGSCC_NPM-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR2]] +; NOT_CGSCC_NPM-NEXT: br label [[TMP5]] +; NOT_CGSCC_NPM: 5: +; NOT_CGSCC_NPM-NEXT: [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; NOT_CGSCC_NPM-NEXT: ret i8* [[TMP6]] +; +; IS__CGSCC____: Function Attrs: nounwind uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 +; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] +; IS__CGSCC____: 3: +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz() #[[ATTR3]] +; IS__CGSCC____-NEXT: br label [[TMP5]] +; IS__CGSCC____: 5: +; IS__CGSCC____-NEXT: [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) +; IS__CGSCC____-NEXT: ret i8* [[TMP6]] ; %2 = icmp eq i32 %0, 0 br i1 %2, label %5, label %3 @@ -154,10 +172,16 @@ define i8** @getter() { ; Returning global pointer. Should not be noalias. define i8** @calle1(){ -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@calle1 -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: ret i8** @G +; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@calle1 +; NOT_CGSCC_NPM-SAME: () #[[ATTR0]] { +; NOT_CGSCC_NPM-NEXT: ret i8** @G +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@calle1 +; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call noundef nonnull align 8 dereferenceable(8) i8** @getter() #[[ATTR11:[0-9]+]] +; IS__CGSCC____-NEXT: ret i8** [[TMP1]] ; %1 = call i8** @getter() ret i8** %1 @@ -167,16 +191,27 @@ define i8** @calle1(){ declare noalias i8* @strdup(i8* nocapture) nounwind define i8* @test6() nounwind uwtable ssp { -; CHECK: Function Attrs: nounwind ssp uwtable -; CHECK-LABEL: define {{[^@]+}}@test6 -; CHECK-SAME: () #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: [[X:%.*]] = alloca [2 x i8], align 1 -; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0 -; CHECK-NEXT: store i8 97, i8* [[ARRAYIDX]], align 1 -; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1 -; CHECK-NEXT: store i8 0, i8* [[ARRAYIDX1]], align 1 -; CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture noundef nonnull dereferenceable(2) [[ARRAYIDX]]) #[[ATTR2]] -; CHECK-NEXT: ret i8* [[CALL]] +; NOT_CGSCC_NPM: Function Attrs: nounwind ssp uwtable +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6 +; NOT_CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: [[X:%.*]] = alloca [2 x i8], align 1 +; NOT_CGSCC_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0 +; NOT_CGSCC_NPM-NEXT: store i8 97, i8* [[ARRAYIDX]], align 1 +; NOT_CGSCC_NPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1 +; NOT_CGSCC_NPM-NEXT: store i8 0, i8* [[ARRAYIDX1]], align 1 +; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture noundef nonnull dereferenceable(2) [[ARRAYIDX]]) #[[ATTR2]] +; NOT_CGSCC_NPM-NEXT: ret i8* [[CALL]] +; +; IS__CGSCC____: Function Attrs: nounwind ssp uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@test6 +; IS__CGSCC____-SAME: () #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-NEXT: [[X:%.*]] = alloca [2 x i8], align 1 +; IS__CGSCC____-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0 +; IS__CGSCC____-NEXT: store i8 97, i8* [[ARRAYIDX]], align 1 +; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1 +; IS__CGSCC____-NEXT: store i8 0, i8* [[ARRAYIDX1]], align 1 +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nocapture noundef nonnull dereferenceable(2) [[ARRAYIDX]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: ret i8* [[CALL]] ; %x = alloca [2 x i8], align 1 %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 0 @@ -190,19 +225,33 @@ define i8* @test6() nounwind uwtable ssp { ; TEST 7 define i8* @test7() nounwind { -; CHECK: Function Attrs: nounwind -; CHECK-LABEL: define {{[^@]+}}@test7 -; CHECK-SAME: () #[[ATTR2]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[A:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR2]] -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[A]], null -; CHECK-NEXT: br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]] -; CHECK: if.end: -; CHECK-NEXT: store i8 7, i8* [[A]], align 1 -; CHECK-NEXT: br label [[RETURN]] -; CHECK: return: -; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i8* [ [[A]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ] -; CHECK-NEXT: ret i8* [[RETVAL_0]] +; NOT_CGSCC_NPM: Function Attrs: nounwind +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test7 +; NOT_CGSCC_NPM-SAME: () #[[ATTR2]] { +; NOT_CGSCC_NPM-NEXT: entry: +; NOT_CGSCC_NPM-NEXT: [[A:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR2]] +; NOT_CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[A]], null +; NOT_CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]] +; NOT_CGSCC_NPM: if.end: +; NOT_CGSCC_NPM-NEXT: store i8 7, i8* [[A]], align 1 +; NOT_CGSCC_NPM-NEXT: br label [[RETURN]] +; NOT_CGSCC_NPM: return: +; NOT_CGSCC_NPM-NEXT: [[RETVAL_0:%.*]] = phi i8* [ [[A]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ] +; NOT_CGSCC_NPM-NEXT: ret i8* [[RETVAL_0]] +; +; IS__CGSCC____: Function Attrs: nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@test7 +; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[A:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[A]], null +; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[RETURN:%.*]], label [[IF_END:%.*]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: store i8 7, i8* [[A]], align 1 +; IS__CGSCC____-NEXT: br label [[RETURN]] +; IS__CGSCC____: return: +; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i8* [ [[A]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ] +; IS__CGSCC____-NEXT: ret i8* [[RETVAL_0]] ; entry: %A = call noalias i8* @malloc(i64 4) nounwind @@ -223,7 +272,7 @@ return: define i8* @test8(i32* %0) nounwind uwtable { ; CHECK: Function Attrs: nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@test8 -; CHECK-SAME: (i32* [[TMP0:%.*]]) #[[ATTR1]] { +; CHECK-SAME: (i32* [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32* [[TMP0]], null ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] @@ -522,13 +571,13 @@ define i32 @i2p(i32* %arg) { ; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree readonly align 4 [[BC]]) #[[ATTR10:[0-9]+]] ; NOT_CGSCC_NPM-NEXT: ret i32 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@i2p -; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR4:[0-9]+]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR10:[0-9]+]] +; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { +; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]]) #[[ATTR11]] ; IS__CGSCC____-NEXT: [[I2P:%.*]] = inttoptr i32 [[C]] to i8* ; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* [[I2P]] to i32* -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[BC]]) #[[ATTR11:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[BC]]) #[[ATTR12:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 [[CALL]] ; %c = call i32 @p2i(i32* %arg) @@ -538,11 +587,17 @@ define i32 @i2p(i32* %arg) { ret i32 %call } define internal i32 @ret(i32* %arg) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; CHECK-LABEL: define {{[^@]+}}@ret -; CHECK-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { -; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4 -; CHECK-NEXT: ret i32 [[L]] +; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@ret +; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4 +; NOT_CGSCC_NPM-NEXT: ret i32 [[L]] +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@ret +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__CGSCC____-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4 +; IS__CGSCC____-NEXT: ret i32 [[L]] ; %l = load i32, i32* %arg ret i32 %l @@ -575,7 +630,7 @@ define internal fastcc double @strtox(i8* %s, i8** %p, i32 %prec) unnamed_addr { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* -; IS__CGSCC____-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR12:[0-9]+]] +; IS__CGSCC____-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 144, i8* nocapture nofree noundef nonnull align 8 dereferenceable(240) [[TMP0]]) #[[ATTR13:[0-9]+]] ; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]], i8* [[S]]) ; IS__CGSCC____-NEXT: call void @__shlim(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i64 noundef 0) ; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double @__floatscan(%struct._IO_FILE* noundef nonnull align 8 dereferenceable(240) [[F]], i32 noundef 1, i32 noundef 1) @@ -628,22 +683,34 @@ declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) @alias_of_p = external global i32* define void @make_alias(i32* %p) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@make_alias -; CHECK-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] { -; CHECK-NEXT: store i32* [[P]], i32** @alias_of_p, align 8 -; CHECK-NEXT: ret void +; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@make_alias +; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR7:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: store i32* [[P]], i32** @alias_of_p, align 8 +; NOT_CGSCC_NPM-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@make_alias +; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-NEXT: store i32* [[P]], i32** @alias_of_p, align 8 +; IS__CGSCC____-NEXT: ret void ; store i32* %p, i32** @alias_of_p ret void } define void @only_store(i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@only_store -; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] { -; CHECK-NEXT: store i32 0, i32* [[P]], align 4 -; CHECK-NEXT: ret void +; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@only_store +; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: store i32 0, i32* [[P]], align 4 +; NOT_CGSCC_NPM-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@only_store +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-NEXT: store i32 0, i32* [[P]], align 4 +; IS__CGSCC____-NEXT: ret void ; store i32 0, i32* %p ret void @@ -662,16 +729,16 @@ define void @test15_caller(i32* noalias %p, i32 %c) { ; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR12]] ; NOT_CGSCC_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test15_caller -; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13:[0-9]+]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14:[0-9]+]] ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR14]] ; IS__CGSCC____-NEXT: ret void ; %tobool = icmp eq i32 %c, 0 @@ -725,20 +792,20 @@ define internal void @test16_sub(i32* noalias %p, i32 %c1, i32 %c2) { ; NOT_CGSCC_NPM: if.end3: ; NOT_CGSCC_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_sub -; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]]) #[[ATTR10]] { ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: ; IS__CGSCC____-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]] ; IS__CGSCC____: if.then2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] ; IS__CGSCC____-NEXT: br label [[IF_END3]] ; IS__CGSCC____: if.end3: ; IS__CGSCC____-NEXT: ret void @@ -770,10 +837,10 @@ define void @test16_caller(i32* %p, i32 %c) { ; NOT_CGSCC_NPM-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR12]] ; NOT_CGSCC_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_caller -; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { -; IS__CGSCC____-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR13]] +; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]]) #[[ATTR14]] ; IS__CGSCC____-NEXT: ret void ; tail call void @test16_sub(i32* %p, i32 %c, i32 %c) @@ -815,17 +882,17 @@ define void @test17_caller(i32* noalias %p, i32 %c) { ; NOT_CGSCC_NPM: l3: ; NOT_CGSCC_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test17_caller -; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; IS__CGSCC____: l1: -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]]) #[[ATTR14]] ; IS__CGSCC____-NEXT: br label [[L3:%.*]] ; IS__CGSCC____: l2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] ; IS__CGSCC____-NEXT: br label [[L3]] ; IS__CGSCC____: l3: ; IS__CGSCC____-NEXT: ret void @@ -858,10 +925,15 @@ l3: ; } define void @noreturn() { -; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@noreturn -; CHECK-SAME: () #[[ATTR9:[0-9]+]] { -; CHECK-NEXT: ret void +; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@noreturn +; NOT_CGSCC_NPM-SAME: () #[[ATTR9]] { +; NOT_CGSCC_NPM-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@noreturn +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: ret void ; call void @noreturn() ret void @@ -881,17 +953,17 @@ define void @test18_caller(i32* noalias %p, i32 %c) { ; NOT_CGSCC_NPM-NEXT: tail call void @only_store(i32* nocapture nofree writeonly align 4 [[P]]) #[[ATTR12]] ; NOT_CGSCC_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@test18_caller -; IS__CGSCC____-SAME: (i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[C:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-SAME: (i32* noalias nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[C:%.*]]) #[[ATTR10]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[L1:%.*]], label [[L2:%.*]] ; IS__CGSCC____: l1: -; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] ; IS__CGSCC____-NEXT: br label [[L2]] ; IS__CGSCC____: l2: -; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P]]) #[[ATTR14]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -924,16 +996,17 @@ l2: ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nounwind uwtable } -; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind } -; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind ssp uwtable } -; IS__CGSCC____: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR10]] = { readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR11]] = { readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR12]] = { willreturn } -; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind ssp uwtable } +; IS__CGSCC____: attributes #[[ATTR5]] = { nofree nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR7:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR11]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR12]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR13]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR14]] = { nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/nocapture-1.ll b/llvm/test/Transforms/Attributor/nocapture-1.ll index 66e6af296653..2e7754045e71 100644 --- a/llvm/test/Transforms/Attributor/nocapture-1.ll +++ b/llvm/test/Transforms/Attributor/nocapture-1.ll @@ -34,11 +34,17 @@ define void @c2(i32* %q) { } define void @c3(i32* %q) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@c3 -; CHECK-SAME: (i32* nofree writeonly [[Q:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR16:[0-9]+]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@c3 +; IS__TUNIT____-SAME: (i32* nofree writeonly [[Q:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR16:[0-9]+]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@c3 +; IS__CGSCC____-SAME: (i32* nofree writeonly [[Q:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR19:[0-9]+]] +; IS__CGSCC____-NEXT: ret void ; call void @c2(i32* %q) ret void @@ -94,15 +100,25 @@ l1: @lookup_table = global [2 x i1] [ i1 0, i1 1 ] define i1 @c5(i32* %q, i32 %bitno) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readonly willreturn -; CHECK-LABEL: define {{[^@]+}}@c5 -; CHECK-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2:[0-9]+]] { -; CHECK-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32 -; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]] -; CHECK-NEXT: [[BIT:%.*]] = and i32 [[TMP2]], 1 -; CHECK-NEXT: [[LOOKUP:%.*]] = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 [[BIT]] -; CHECK-NEXT: [[VAL:%.*]] = load i1, i1* [[LOOKUP]], align 1 -; CHECK-NEXT: ret i1 [[VAL]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@c5 +; IS__TUNIT____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__TUNIT____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32 +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]] +; IS__TUNIT____-NEXT: [[BIT:%.*]] = and i32 [[TMP2]], 1 +; IS__TUNIT____-NEXT: [[LOOKUP:%.*]] = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 [[BIT]] +; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i1, i1* [[LOOKUP]], align 1 +; IS__TUNIT____-NEXT: ret i1 [[VAL]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@c5 +; IS__CGSCC____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32 +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]] +; IS__CGSCC____-NEXT: [[BIT:%.*]] = and i32 [[TMP2]], 1 +; IS__CGSCC____-NEXT: [[LOOKUP:%.*]] = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 [[BIT]] +; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i1, i1* [[LOOKUP]], align 1 +; IS__CGSCC____-NEXT: ret i1 [[VAL]] ; %tmp = ptrtoint i32* %q to i32 %tmp2 = lshr i32 %tmp, %bitno @@ -116,17 +132,29 @@ define i1 @c5(i32* %q, i32 %bitno) { declare void @throw_if_bit_set(i8*, i8) readonly define i1 @c6(i8* %q, i8 %bit) personality i32 (...)* @__gxx_personality_v0 { -; CHECK: Function Attrs: nounwind readonly -; CHECK-LABEL: define {{[^@]+}}@c6 -; CHECK-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #[[ATTR4:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { -; CHECK-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]]) #[[ATTR3:[0-9]+]] -; CHECK-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]] -; CHECK: ret0: -; CHECK-NEXT: ret i1 false -; CHECK: ret1: -; CHECK-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 } -; CHECK-NEXT: cleanup -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nounwind readonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@c6 +; IS__TUNIT____-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #[[ATTR4:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { +; IS__TUNIT____-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]]) #[[ATTR3:[0-9]+]] +; IS__TUNIT____-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]] +; IS__TUNIT____: ret0: +; IS__TUNIT____-NEXT: ret i1 false +; IS__TUNIT____: ret1: +; IS__TUNIT____-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 } +; IS__TUNIT____-NEXT: cleanup +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC____: Function Attrs: nounwind readonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@c6 +; IS__CGSCC____-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #[[ATTR5:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 { +; IS__CGSCC____-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]]) #[[ATTR4:[0-9]+]] +; IS__CGSCC____-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]] +; IS__CGSCC____: ret0: +; IS__CGSCC____-NEXT: ret i1 false +; IS__CGSCC____: ret1: +; IS__CGSCC____-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 } +; IS__CGSCC____-NEXT: cleanup +; IS__CGSCC____-NEXT: ret i1 true ; invoke void @throw_if_bit_set(i8* %q, i8 %bit) to label %ret0 unwind label %ret1 @@ -158,12 +186,19 @@ define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind { } define i1 @c7(i32* %q, i32 %bitno) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readonly willreturn -; CHECK-LABEL: define {{[^@]+}}@c7 -; CHECK-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR17:[0-9]+]] -; CHECK-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1 -; CHECK-NEXT: ret i1 [[VAL]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@c7 +; IS__TUNIT____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR17:[0-9]+]] +; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1 +; IS__TUNIT____-NEXT: ret i1 [[VAL]] +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@c7 +; IS__CGSCC____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__CGSCC____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR20:[0-9]+]] +; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1 +; IS__CGSCC____-NEXT: ret i1 [[VAL]] ; %ptr = call i1* @lookup_bit(i32* %q, i32 %bitno) %val = load i1, i1* %ptr @@ -172,18 +207,31 @@ define i1 @c7(i32* %q, i32 %bitno) { define i32 @nc1(i32* %q, i32* %p, i1 %b) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@nc1 -; CHECK-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5:[0-9]+]] { -; CHECK-NEXT: e: -; CHECK-NEXT: br label [[L:%.*]] -; CHECK: l: -; CHECK-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ] -; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Y]] -; CHECK-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4 -; CHECK-NEXT: store i32 0, i32* [[P]], align 4 -; CHECK-NEXT: store i32* [[Y]], i32** @g, align 8 -; CHECK-NEXT: ret i32 [[VAL]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@nc1 +; IS__TUNIT____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5:[0-9]+]] { +; IS__TUNIT____-NEXT: e: +; IS__TUNIT____-NEXT: br label [[L:%.*]] +; IS__TUNIT____: l: +; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ] +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Y]] +; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__TUNIT____-NEXT: store i32 0, i32* [[P]], align 4 +; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g, align 8 +; IS__TUNIT____-NEXT: ret i32 [[VAL]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@nc1 +; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__CGSCC____-NEXT: e: +; IS__CGSCC____-NEXT: br label [[L:%.*]] +; IS__CGSCC____: l: +; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ] +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Y]] +; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: store i32 0, i32* [[P]], align 4 +; IS__CGSCC____-NEXT: store i32* [[Y]], i32** @g, align 8 +; IS__CGSCC____-NEXT: ret i32 [[VAL]] ; e: br label %l @@ -199,20 +247,35 @@ l: } define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* %p, i1 %b) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@nc1_addrspace -; CHECK-SAME: (i32* nofree [[Q:%.*]], i32 addrspace(1)* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5]] { -; CHECK-NEXT: e: -; CHECK-NEXT: br label [[L:%.*]] -; CHECK: l: -; CHECK-NEXT: [[X:%.*]] = phi i32 addrspace(1)* [ [[P]], [[E:%.*]] ] -; CHECK-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ] -; CHECK-NEXT: [[TMP:%.*]] = addrspacecast i32 addrspace(1)* [[X]] to i32* -; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]] -; CHECK-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4 -; CHECK-NEXT: store i32 0, i32* [[TMP]], align 4 -; CHECK-NEXT: store i32* [[Y]], i32** @g, align 8 -; CHECK-NEXT: ret i32 [[VAL]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@nc1_addrspace +; IS__TUNIT____-SAME: (i32* nofree [[Q:%.*]], i32 addrspace(1)* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5]] { +; IS__TUNIT____-NEXT: e: +; IS__TUNIT____-NEXT: br label [[L:%.*]] +; IS__TUNIT____: l: +; IS__TUNIT____-NEXT: [[X:%.*]] = phi i32 addrspace(1)* [ [[P]], [[E:%.*]] ] +; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ] +; IS__TUNIT____-NEXT: [[TMP:%.*]] = addrspacecast i32 addrspace(1)* [[X]] to i32* +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]] +; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__TUNIT____-NEXT: store i32 0, i32* [[TMP]], align 4 +; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g, align 8 +; IS__TUNIT____-NEXT: ret i32 [[VAL]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@nc1_addrspace +; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32 addrspace(1)* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-NEXT: e: +; IS__CGSCC____-NEXT: br label [[L:%.*]] +; IS__CGSCC____: l: +; IS__CGSCC____-NEXT: [[X:%.*]] = phi i32 addrspace(1)* [ [[P]], [[E:%.*]] ] +; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ] +; IS__CGSCC____-NEXT: [[TMP:%.*]] = addrspacecast i32 addrspace(1)* [[X]] to i32* +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]] +; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: store i32 0, i32* [[TMP]], align 4 +; IS__CGSCC____-NEXT: store i32* [[Y]], i32** @g, align 8 +; IS__CGSCC____-NEXT: ret i32 [[VAL]] ; e: br label %l @@ -234,10 +297,10 @@ define void @nc2(i32* %p, i32* %q) { ; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 noundef false) #[[ATTR18:[0-9]+]] ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@nc2 -; IS__CGSCC____-SAME: (i32* nocapture nofree align 4 [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR5]] { -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree align 4 [[P]], i1 noundef false) #[[ATTR13:[0-9]+]] +; IS__CGSCC____-SAME: (i32* nocapture nofree align 4 [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree align 4 [[P]], i1 noundef false) #[[ATTR16:[0-9]+]] ; IS__CGSCC____-NEXT: ret void ; %1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; [#uses=0] @@ -267,8 +330,8 @@ define void @nc4(i8* %p) { ; ; IS__CGSCC____: Function Attrs: argmemonly nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@nc4 -; IS__CGSCC____-SAME: (i8* [[P:%.*]]) #[[ATTR6:[0-9]+]] { -; IS__CGSCC____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR18:[0-9]+]] +; IS__CGSCC____-SAME: (i8* [[P:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR21:[0-9]+]] ; IS__CGSCC____-NEXT: ret void ; call void @external(i8* %p) @@ -288,12 +351,19 @@ define void @nc5(void (i8*)* %f, i8* %p) { ; It would be acceptable to add readnone to %y1_1 and %y1_2. define void @test1_1(i8* %x1_1, i8* %y1_1, i1 %c) { -; CHECK: Function Attrs: nofree nosync nounwind writeonly -; CHECK-LABEL: define {{[^@]+}}@test1_1 -; CHECK-SAME: (i8* nocapture nofree readnone [[X1_1:%.*]], i8* nocapture nofree readnone [[Y1_1:%.*]], i1 [[C:%.*]]) #[[ATTR7:[0-9]+]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) #[[ATTR7]] -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree nosync nounwind writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_1 +; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[X1_1:%.*]], i8* nocapture nofree readnone [[Y1_1:%.*]], i1 [[C:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) #[[ATTR7]] +; IS__TUNIT____-NEXT: store i32* null, i32** @g, align 8 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_1 +; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[X1_1:%.*]], i8* nocapture nofree readnone [[Y1_1:%.*]], i1 [[C:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) #[[ATTR10]] +; IS__CGSCC____-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC____-NEXT: ret void ; call i8* @test1_2(i8* %x1_1, i8* %y1_1, i1 %c) store i32* null, i32** @g @@ -301,27 +371,49 @@ define void @test1_1(i8* %x1_1, i8* %y1_1, i1 %c) { } define i8* @test1_2(i8* %x1_2, i8* %y1_2, i1 %c) { -; IS________OPM: Function Attrs: nofree nosync nounwind writeonly -; IS________OPM-LABEL: define {{[^@]+}}@test1_2 -; IS________OPM-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { -; IS________OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS________OPM: t: -; IS________OPM-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 [[C]]) #[[ATTR7]] -; IS________OPM-NEXT: store i32* null, i32** @g, align 8 -; IS________OPM-NEXT: br label [[F]] -; IS________OPM: f: -; IS________OPM-NEXT: ret i8* [[Y1_2]] +; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind writeonly +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test1_2 +; IS__TUNIT_OPM-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { +; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_OPM: t: +; IS__TUNIT_OPM-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 [[C]]) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: store i32* null, i32** @g, align 8 +; IS__TUNIT_OPM-NEXT: br label [[F]] +; IS__TUNIT_OPM: f: +; IS__TUNIT_OPM-NEXT: ret i8* [[Y1_2]] ; -; IS________NPM: Function Attrs: nofree nosync nounwind writeonly -; IS________NPM-LABEL: define {{[^@]+}}@test1_2 -; IS________NPM-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { -; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS________NPM: t: -; IS________NPM-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 noundef [[C]]) #[[ATTR7]] -; IS________NPM-NEXT: store i32* null, i32** @g, align 8 -; IS________NPM-NEXT: br label [[F]] -; IS________NPM: f: -; IS________NPM-NEXT: ret i8* [[Y1_2]] +; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind writeonly +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test1_2 +; IS__TUNIT_NPM-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { +; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_NPM: t: +; IS__TUNIT_NPM-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 noundef [[C]]) #[[ATTR7]] +; IS__TUNIT_NPM-NEXT: store i32* null, i32** @g, align 8 +; IS__TUNIT_NPM-NEXT: br label [[F]] +; IS__TUNIT_NPM: f: +; IS__TUNIT_NPM-NEXT: ret i8* [[Y1_2]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind writeonly +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test1_2 +; IS__CGSCC_OPM-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR10]] { +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_OPM: t: +; IS__CGSCC_OPM-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 [[C]]) #[[ATTR10]] +; IS__CGSCC_OPM-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC_OPM-NEXT: br label [[F]] +; IS__CGSCC_OPM: f: +; IS__CGSCC_OPM-NEXT: ret i8* [[Y1_2]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test1_2 +; IS__CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR10]] { +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_NPM: t: +; IS__CGSCC_NPM-NEXT: call void @test1_1(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 noundef [[C]]) #[[ATTR10]] +; IS__CGSCC_NPM-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC_NPM-NEXT: br label [[F]] +; IS__CGSCC_NPM: f: +; IS__CGSCC_NPM-NEXT: ret i8* [[Y1_2]] ; br i1 %c, label %t, label %f t: @@ -333,12 +425,19 @@ f: } define void @test2(i8* %x2) { -; CHECK: Function Attrs: nofree nosync nounwind writeonly -; CHECK-LABEL: define {{[^@]+}}@test2 -; CHECK-SAME: (i8* nocapture nofree readnone [[X2:%.*]]) #[[ATTR7]] { -; CHECK-NEXT: call void @test2(i8* noalias nocapture nofree readnone undef) #[[ATTR7]] -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree nosync nounwind writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2 +; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[X2:%.*]]) #[[ATTR7]] { +; IS__TUNIT____-NEXT: call void @test2(i8* noalias nocapture nofree readnone undef) #[[ATTR7]] +; IS__TUNIT____-NEXT: store i32* null, i32** @g, align 8 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2 +; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[X2:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-NEXT: call void @test2(i8* noalias nocapture nofree readnone undef) #[[ATTR10]] +; IS__CGSCC____-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC____-NEXT: ret void ; call void @test2(i8* %x2) store i32* null, i32** @g @@ -346,12 +445,19 @@ define void @test2(i8* %x2) { } define void @test3(i8* %x3, i8* %y3, i8* %z3) { -; CHECK: Function Attrs: nofree nosync nounwind writeonly -; CHECK-LABEL: define {{[^@]+}}@test3 -; CHECK-SAME: (i8* nocapture nofree readnone [[X3:%.*]], i8* nocapture nofree readnone [[Y3:%.*]], i8* nocapture nofree readnone [[Z3:%.*]]) #[[ATTR7]] { -; CHECK-NEXT: call void @test3(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef) #[[ATTR7]] -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree nosync nounwind writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test3 +; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[X3:%.*]], i8* nocapture nofree readnone [[Y3:%.*]], i8* nocapture nofree readnone [[Z3:%.*]]) #[[ATTR7]] { +; IS__TUNIT____-NEXT: call void @test3(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef) #[[ATTR7]] +; IS__TUNIT____-NEXT: store i32* null, i32** @g, align 8 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test3 +; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[X3:%.*]], i8* nocapture nofree readnone [[Y3:%.*]], i8* nocapture nofree readnone [[Z3:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-NEXT: call void @test3(i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef, i8* noalias nocapture nofree readnone undef) #[[ATTR10]] +; IS__CGSCC____-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC____-NEXT: ret void ; call void @test3(i8* %z3, i8* %y3, i8* %x3) store i32* null, i32** @g @@ -359,12 +465,19 @@ define void @test3(i8* %x3, i8* %y3, i8* %z3) { } define void @test4_1(i8* %x4_1, i1 %c) { -; CHECK: Function Attrs: nofree nosync nounwind writeonly -; CHECK-LABEL: define {{[^@]+}}@test4_1 -; CHECK-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nocapture nofree readnone undef, i1 [[C]]) #[[ATTR7]] -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree nosync nounwind writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test4_1 +; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nocapture nofree readnone undef, i1 [[C]]) #[[ATTR7]] +; IS__TUNIT____-NEXT: store i32* null, i32** @g, align 8 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test4_1 +; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nocapture nofree readnone undef, i1 [[C]]) #[[ATTR10]] +; IS__CGSCC____-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC____-NEXT: ret void ; call i8* @test4_2(i8* %x4_1, i8* %x4_1, i8* %x4_1, i1 %c) store i32* null, i32** @g @@ -372,27 +485,49 @@ define void @test4_1(i8* %x4_1, i1 %c) { } define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2, i1 %c) { -; IS________OPM: Function Attrs: nofree nosync nounwind writeonly -; IS________OPM-LABEL: define {{[^@]+}}@test4_2 -; IS________OPM-SAME: (i8* nocapture nofree readnone [[X4_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y4_2:%.*]], i8* nocapture nofree readnone [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { -; IS________OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS________OPM: t: -; IS________OPM-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 [[C]]) #[[ATTR7]] -; IS________OPM-NEXT: store i32* null, i32** @g, align 8 -; IS________OPM-NEXT: br label [[F]] -; IS________OPM: f: -; IS________OPM-NEXT: ret i8* [[Y4_2]] +; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind writeonly +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test4_2 +; IS__TUNIT_OPM-SAME: (i8* nocapture nofree readnone [[X4_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y4_2:%.*]], i8* nocapture nofree readnone [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { +; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_OPM: t: +; IS__TUNIT_OPM-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 [[C]]) #[[ATTR7]] +; IS__TUNIT_OPM-NEXT: store i32* null, i32** @g, align 8 +; IS__TUNIT_OPM-NEXT: br label [[F]] +; IS__TUNIT_OPM: f: +; IS__TUNIT_OPM-NEXT: ret i8* [[Y4_2]] ; -; IS________NPM: Function Attrs: nofree nosync nounwind writeonly -; IS________NPM-LABEL: define {{[^@]+}}@test4_2 -; IS________NPM-SAME: (i8* nocapture nofree readnone [[X4_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y4_2:%.*]], i8* nocapture nofree readnone [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { -; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS________NPM: t: -; IS________NPM-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 noundef [[C]]) #[[ATTR7]] -; IS________NPM-NEXT: store i32* null, i32** @g, align 8 -; IS________NPM-NEXT: br label [[F]] -; IS________NPM: f: -; IS________NPM-NEXT: ret i8* [[Y4_2]] +; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind writeonly +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test4_2 +; IS__TUNIT_NPM-SAME: (i8* nocapture nofree readnone [[X4_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y4_2:%.*]], i8* nocapture nofree readnone [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { +; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_NPM: t: +; IS__TUNIT_NPM-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 noundef [[C]]) #[[ATTR7]] +; IS__TUNIT_NPM-NEXT: store i32* null, i32** @g, align 8 +; IS__TUNIT_NPM-NEXT: br label [[F]] +; IS__TUNIT_NPM: f: +; IS__TUNIT_NPM-NEXT: ret i8* [[Y4_2]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind writeonly +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4_2 +; IS__CGSCC_OPM-SAME: (i8* nocapture nofree readnone [[X4_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y4_2:%.*]], i8* nocapture nofree readnone [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR10]] { +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_OPM: t: +; IS__CGSCC_OPM-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 [[C]]) #[[ATTR10]] +; IS__CGSCC_OPM-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC_OPM-NEXT: br label [[F]] +; IS__CGSCC_OPM: f: +; IS__CGSCC_OPM-NEXT: ret i8* [[Y4_2]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4_2 +; IS__CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[X4_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y4_2:%.*]], i8* nocapture nofree readnone [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR10]] { +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_NPM: t: +; IS__CGSCC_NPM-NEXT: call void @test4_1(i8* noalias nocapture nofree noundef readnone align 4294967296 null, i1 noundef [[C]]) #[[ATTR10]] +; IS__CGSCC_NPM-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC_NPM-NEXT: br label [[F]] +; IS__CGSCC_NPM: f: +; IS__CGSCC_NPM-NEXT: ret i8* [[Y4_2]] ; br i1 %c, label %t, label %f t: @@ -432,46 +567,72 @@ define void @test6_2(i8* %x6_2, i8* %y6_2, i8* %z6_2) { } define void @test_cmpxchg(i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@test_cmpxchg -; CHECK-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] { -; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[P]], i32 0, i32 1 acquire monotonic, align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_cmpxchg +; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[P]], i32 0, i32 1 acquire monotonic, align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_cmpxchg +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[P]], i32 0, i32 1 acquire monotonic, align 4 +; IS__CGSCC____-NEXT: ret void ; cmpxchg i32* %p, i32 0, i32 1 acquire monotonic ret void } define void @test_cmpxchg_ptr(i32** %p, i32* %q) { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@test_cmpxchg_ptr -; CHECK-SAME: (i32** nocapture nofree noundef nonnull dereferenceable(8) [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32** [[P]], i32* null, i32* [[Q]] acquire monotonic, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_cmpxchg_ptr +; IS__TUNIT____-SAME: (i32** nocapture nofree noundef nonnull dereferenceable(8) [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR8]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = cmpxchg i32** [[P]], i32* null, i32* [[Q]] acquire monotonic, align 8 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_cmpxchg_ptr +; IS__CGSCC____-SAME: (i32** nocapture nofree noundef nonnull dereferenceable(8) [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR11]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = cmpxchg i32** [[P]], i32* null, i32* [[Q]] acquire monotonic, align 8 +; IS__CGSCC____-NEXT: ret void ; cmpxchg i32** %p, i32* null, i32* %q acquire monotonic ret void } define void @test_atomicrmw(i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@test_atomicrmw -; CHECK-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst, align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_atomicrmw +; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR8]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst, align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_atomicrmw +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR11]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst, align 4 +; IS__CGSCC____-NEXT: ret void ; atomicrmw add i32* %p, i32 1 seq_cst ret void } define void @test_volatile(i32* %x) { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@test_volatile -; CHECK-SAME: (i32* nofree align 4 [[X:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[X]], i64 1 -; CHECK-NEXT: store volatile i32 0, i32* [[GEP]], align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_volatile +; IS__TUNIT____-SAME: (i32* nofree align 4 [[X:%.*]]) #[[ATTR8]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[X]], i64 1 +; IS__TUNIT____-NEXT: store volatile i32 0, i32* [[GEP]], align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_volatile +; IS__CGSCC____-SAME: (i32* nofree align 4 [[X:%.*]]) #[[ATTR11]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[X]], i64 1 +; IS__CGSCC____-NEXT: store volatile i32 0, i32* [[GEP]], align 4 +; IS__CGSCC____-NEXT: ret void ; entry: %gep = getelementptr i32, i32* %x, i64 1 @@ -490,9 +651,9 @@ define void @nocaptureLaunder(i8* %p) { ; ; IS__CGSCC____: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureLaunder -; IS__CGSCC____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR12:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR19:[0-9]+]] +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR22:[0-9]+]] ; IS__CGSCC____-NEXT: store i8 42, i8* [[B]], align 1 ; IS__CGSCC____-NEXT: ret void ; @@ -513,8 +674,8 @@ define void @captureLaunder(i8* %p) { ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@captureLaunder -; IS__CGSCC____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR5]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR19]] +; IS__CGSCC____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR7]] { +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR22]] ; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g2, align 8 ; IS__CGSCC____-NEXT: ret void ; @@ -534,9 +695,9 @@ define void @nocaptureStrip(i8* %p) { ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureStrip -; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR13:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR17]] +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR20]] ; IS__CGSCC____-NEXT: store i8 42, i8* [[B]], align 1 ; IS__CGSCC____-NEXT: ret void ; @@ -558,7 +719,7 @@ define void @captureStrip(i8* %p) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@captureStrip ; IS__CGSCC____-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR17]] +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR20]] ; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g3, align 8 ; IS__CGSCC____-NEXT: ret void ; @@ -627,12 +788,19 @@ define i1 @nocaptureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x } define i1 @captureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) null_pointer_is_valid { -; CHECK: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp -; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR11:[0-9]+]] { -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8* -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null -; CHECK-NEXT: ret i1 [[TMP2]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp +; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8* +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null +; IS__TUNIT____-NEXT: ret i1 [[TMP2]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp +; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR14:[0-9]+]] { +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8* +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null +; IS__CGSCC____-NEXT: ret i1 [[TMP2]] ; %1 = bitcast i32* %x to i8* %2 = icmp eq i8* %1, null @@ -654,12 +822,19 @@ entry: declare i8* @unknownpi8pi8(i8*,i8* returned) define i8* @test_returned1(i8* %A, i8* returned %B) nounwind readonly { -; CHECK: Function Attrs: nounwind readonly -; CHECK-LABEL: define {{[^@]+}}@test_returned1 -; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* [[A]], i8* [[B]]) -; CHECK-NEXT: ret i8* [[B]] +; IS__TUNIT____: Function Attrs: nounwind readonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_returned1 +; IS__TUNIT____-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* [[A]], i8* [[B]]) +; IS__TUNIT____-NEXT: ret i8* [[B]] +; +; IS__CGSCC____: Function Attrs: nounwind readonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_returned1 +; IS__CGSCC____-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR5]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* [[A]], i8* [[B]]) +; IS__CGSCC____-NEXT: ret i8* [[B]] ; entry: %p = call i8* @unknownpi8pi8(i8* %A, i8* %B) @@ -667,12 +842,19 @@ entry: } define i8* @test_returned2(i8* %A, i8* %B) { -; CHECK: Function Attrs: nounwind readonly -; CHECK-LABEL: define {{[^@]+}}@test_returned2 -; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* readonly [[A]], i8* readonly [[B]]) #[[ATTR4]] -; CHECK-NEXT: ret i8* [[B]] +; IS__TUNIT____: Function Attrs: nounwind readonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_returned2 +; IS__TUNIT____-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* readonly [[A]], i8* readonly [[B]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret i8* [[B]] +; +; IS__CGSCC____: Function Attrs: nounwind readonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_returned2 +; IS__CGSCC____-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR5]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* readonly [[A]], i8* readonly [[B]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: ret i8* [[B]] ; entry: %p = call i8* @unknownpi8pi8(i8* %A, i8* %B) nounwind readonly @@ -685,11 +867,17 @@ declare void @val_use(i8 %ptr) readonly nounwind willreturn ; FIXME: Both pointers should be nocapture define void @ptr_uses(i8* %ptr, i8* %wptr) { -; CHECK: Function Attrs: nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@ptr_uses -; CHECK-SAME: (i8* [[PTR:%.*]], i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR13:[0-9]+]] { -; CHECK-NEXT: store i8 0, i8* [[WPTR]], align 1 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_uses +; IS__TUNIT____-SAME: (i8* [[PTR:%.*]], i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR13:[0-9]+]] { +; IS__TUNIT____-NEXT: store i8 0, i8* [[WPTR]], align 1 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_uses +; IS__CGSCC____-SAME: (i8* [[PTR:%.*]], i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR16]] { +; IS__CGSCC____-NEXT: store i8 0, i8* [[WPTR]], align 1 +; IS__CGSCC____-NEXT: ret void ; %call_ptr = call i8* @maybe_returned_ptr(i8* %ptr) %call_val = call i8 @maybe_returned_val(i8* %call_ptr) @@ -726,22 +914,25 @@ declare i8* @llvm.strip.invariant.group.p0i8(i8*) ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR3]] = { readonly } -; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind readonly } -; IS__CGSCC____: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR6]] = { argmemonly nounwind } -; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly } -; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR9]] = { inaccessiblemem_or_argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR10]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR12:[0-9]+]] = { nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR14:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind speculatable willreturn } -; IS__CGSCC____: attributes #[[ATTR15:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } -; IS__CGSCC____: attributes #[[ATTR16]] = { nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR17]] = { readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR18]] = { nounwind } -; IS__CGSCC____: attributes #[[ATTR19]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR4]] = { readonly } +; IS__CGSCC____: attributes #[[ATTR5]] = { nounwind readonly } +; IS__CGSCC____: attributes #[[ATTR6]] = { nofree nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nounwind } +; IS__CGSCC____: attributes #[[ATTR10]] = { nofree nosync nounwind writeonly } +; IS__CGSCC____: attributes #[[ATTR11]] = { argmemonly nofree norecurse nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR12]] = { inaccessiblemem_or_argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR13]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR14]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR15:[0-9]+]] = { nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR16]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR17:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind speculatable willreturn } +; IS__CGSCC____: attributes #[[ATTR18:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; IS__CGSCC____: attributes #[[ATTR19]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR20]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR21]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR22]] = { willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll b/llvm/test/Transforms/Attributor/nocapture-2.ll index 04b9283c8786..6f368e3ed68e 100644 --- a/llvm/test/Transforms/Attributor/nocapture-2.ll +++ b/llvm/test/Transforms/Attributor/nocapture-2.ll @@ -413,12 +413,12 @@ define void @test_not_captured_but_returned_calls(i64* %a) #0 { ; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_not_captured_but_returned_calls -; IS__CGSCC____-SAME: (i64* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR5:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) #[[ATTR9:[0-9]+]] -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR10:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR10]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -442,11 +442,11 @@ define i64* @negative_test_not_captured_but_returned_call_0a(i64* %a) #0 { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: ret i64* [[A]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a -; IS__CGSCC____-SAME: (i64* nofree noundef nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-SAME: (i64* nofree noundef nonnull returned writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR5]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A]]) #[[ATTR10]] ; IS__CGSCC____-NEXT: ret i64* [[A]] ; entry: @@ -471,11 +471,11 @@ define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 { ; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0b -; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR5]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A]]) #[[ATTR10]] ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[A]] to i64 ; IS__CGSCC____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8 ; IS__CGSCC____-NEXT: ret void @@ -502,11 +502,11 @@ define i64* @negative_test_not_captured_but_returned_call_1a(i64* %a) #0 { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call noundef nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]] ; IS__TUNIT____-NEXT: ret i64* [[CALL]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; IS__CGSCC____: Function Attrs: argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1a -; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR5]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call noundef nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call noundef nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR10]] ; IS__CGSCC____-NEXT: ret i64* [[CALL]] ; entry: @@ -531,11 +531,11 @@ define void @negative_test_not_captured_but_returned_call_1b(i64* %a) #0 { ; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[CALL]], align 8 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind willreturn writeonly uwtable +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind willreturn writeonly uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1b -; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR5:[0-9]+]] { +; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR6:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree noundef nonnull writeonly align 8 dereferenceable(16) [[A]]) #[[ATTR10]] ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64 ; IS__CGSCC____-NEXT: store i64 [[TMP0]], i64* [[CALL]], align 8 ; IS__CGSCC____-NEXT: ret void @@ -621,12 +621,19 @@ r: declare i32* @readonly_unknown(i32*, i32*) readonly define void @not_captured_by_readonly_call(i32* %b) #0 { -; CHECK: Function Attrs: noinline nounwind readonly uwtable -; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call -; CHECK-SAME: (i32* nocapture readonly [[B:%.*]]) #[[ATTR7:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[B]]) #[[ATTR6:[0-9]+]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: noinline nounwind readonly uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call +; IS__TUNIT____-SAME: (i32* nocapture readonly [[B:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[B]]) #[[ATTR6:[0-9]+]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: noinline nounwind readonly uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call +; IS__CGSCC____-SAME: (i32* nocapture readonly [[B:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[B]]) #[[ATTR7:[0-9]+]] +; IS__CGSCC____-NEXT: ret void ; entry: %call = call i32* @readonly_unknown(i32* %b, i32* %b) @@ -639,12 +646,19 @@ entry: ; Make sure the returned flag on %r is strong enough to justify nocapture on %b but **not** on %r. ; define i32* @not_captured_by_readonly_call_not_returned_either1(i32* %b, i32* returned %r) { -; CHECK: Function Attrs: nounwind readonly -; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either1 -; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]] -; CHECK-NEXT: ret i32* [[CALL]] +; IS__TUNIT____: Function Attrs: nounwind readonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either1 +; IS__TUNIT____-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]] +; IS__TUNIT____-NEXT: ret i32* [[CALL]] +; +; IS__CGSCC____: Function Attrs: nounwind readonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either1 +; IS__CGSCC____-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: ret i32* [[CALL]] ; entry: %call = call i32* @readonly_unknown(i32* %b, i32* %r) nounwind @@ -653,12 +667,19 @@ entry: declare i32* @readonly_unknown_r1a(i32*, i32* returned) readonly define i32* @not_captured_by_readonly_call_not_returned_either2(i32* %b, i32* %r) { -; CHECK: Function Attrs: nounwind readonly -; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either2 -; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]] -; CHECK-NEXT: ret i32* [[R]] +; IS__TUNIT____: Function Attrs: nounwind readonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either2 +; IS__TUNIT____-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]] +; IS__TUNIT____-NEXT: ret i32* [[R]] +; +; IS__CGSCC____: Function Attrs: nounwind readonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either2 +; IS__CGSCC____-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: ret i32* [[R]] ; entry: %call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r) nounwind @@ -667,12 +688,19 @@ entry: declare i32* @readonly_unknown_r1b(i32*, i32* returned) readonly nounwind define i32* @not_captured_by_readonly_call_not_returned_either3(i32* %b, i32* %r) { -; CHECK: Function Attrs: nounwind readonly -; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3 -; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR8]] -; CHECK-NEXT: ret i32* [[R]] +; IS__TUNIT____: Function Attrs: nounwind readonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3 +; IS__TUNIT____-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR8]] +; IS__TUNIT____-NEXT: ret i32* [[R]] +; +; IS__CGSCC____: Function Attrs: nounwind readonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3 +; IS__CGSCC____-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: ret i32* [[R]] ; entry: %call = call i32* @readonly_unknown_r1b(i32* %b, i32* %r) @@ -680,12 +708,19 @@ entry: } define i32* @not_captured_by_readonly_call_not_returned_either4(i32* %b, i32* %r) nounwind { -; CHECK: Function Attrs: nounwind readonly -; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either4 -; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR6]] -; CHECK-NEXT: ret i32* [[R]] +; IS__TUNIT____: Function Attrs: nounwind readonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either4 +; IS__TUNIT____-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR6]] +; IS__TUNIT____-NEXT: ret i32* [[R]] +; +; IS__CGSCC____: Function Attrs: nounwind readonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either4 +; IS__CGSCC____-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: ret i32* [[R]] ; entry: %call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r) @@ -710,12 +745,19 @@ entry: declare i32* @readonly_i32p(i32*) readonly define void @nocapture_is_not_subsumed_2(i32* nocapture %b) { -; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2 -; CHECK-SAME: (i32* nocapture [[B:%.*]]) { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly [[B]]) #[[ATTR6]] -; CHECK-NEXT: store i32 0, i32* [[CALL]], align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2 +; IS__TUNIT____-SAME: (i32* nocapture [[B:%.*]]) { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly [[B]]) #[[ATTR6]] +; IS__TUNIT____-NEXT: store i32 0, i32* [[CALL]], align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2 +; IS__CGSCC____-SAME: (i32* nocapture [[B:%.*]]) { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly [[B]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: store i32 0, i32* [[CALL]], align 4 +; IS__CGSCC____-NEXT: ret void ; entry: %call = call i32* @readonly_i32p(i32* %b) @@ -741,9 +783,10 @@ attributes #0 = { noinline nounwind uwtable } ; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone } ; IS__CGSCC____: attributes #[[ATTR3]] = { noinline nounwind uwtable } ; IS__CGSCC____: attributes #[[ATTR4]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } -; IS__CGSCC____: attributes #[[ATTR5]] = { nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } -; IS__CGSCC____: attributes #[[ATTR6]] = { readonly } -; IS__CGSCC____: attributes #[[ATTR7]] = { noinline nounwind readonly uwtable } -; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind readonly } -; IS__CGSCC____: attributes #[[ATTR9]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR5]] = { argmemonly nofree noinline nosync nounwind willreturn writeonly uwtable } +; IS__CGSCC____: attributes #[[ATTR6]] = { nofree noinline nosync nounwind willreturn writeonly uwtable } +; IS__CGSCC____: attributes #[[ATTR7]] = { readonly } +; IS__CGSCC____: attributes #[[ATTR8]] = { noinline nounwind readonly uwtable } +; IS__CGSCC____: attributes #[[ATTR9]] = { nounwind readonly } +; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/nodelete.ll b/llvm/test/Transforms/Attributor/nodelete.ll index 2607da162fa6..30ef4f5be54c 100644 --- a/llvm/test/Transforms/Attributor/nodelete.ll +++ b/llvm/test/Transforms/Attributor/nodelete.ll @@ -14,12 +14,13 @@ define hidden i64 @f1() align 2 { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: ret i64 undef ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f1 ; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] align 2 { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[REF_TMP:%.*]] = alloca [[A:%.*]], align 8 -; IS__CGSCC____-NEXT: ret i64 undef +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @f2() #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: ret i64 [[CALL2]] ; entry: %ref.tmp = alloca %"a", align 8 @@ -28,7 +29,7 @@ entry: } define internal i64 @f2(%"a"* %this) align 2 { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f2 ; IS__CGSCC____-SAME: () #[[ATTR0]] align 2 { ; IS__CGSCC____-NEXT: entry: @@ -44,7 +45,7 @@ entry: } define internal void @f3(%"b"* %this) align 2 { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f3 ; IS__CGSCC____-SAME: () #[[ATTR0]] align 2 { ; IS__CGSCC____-NEXT: entry: @@ -59,7 +60,7 @@ entry: } define internal i1 @f4(%"b"* %this) align 2 { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f4 ; IS__CGSCC____-SAME: () #[[ATTR0]] align 2 { ; IS__CGSCC____-NEXT: entry: @@ -76,7 +77,7 @@ entry: define internal %"a"* @f5(%"b"* %this) align 2 { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f5 -; IS__CGSCC____-SAME: () #[[ATTR0]] align 2 { +; IS__CGSCC____-SAME: () #[[ATTR1:[0-9]+]] align 2 { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: ret %a* undef ; @@ -88,5 +89,9 @@ entry: ret %"a"* %0 } ;. -; CHECK: attributes #[[ATTR0:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/nofree.ll b/llvm/test/Transforms/Attributor/nofree.ll index eb6cc6f5cf71..0e15b913f844 100644 --- a/llvm/test/Transforms/Attributor/nofree.ll +++ b/llvm/test/Transforms/Attributor/nofree.ll @@ -286,15 +286,15 @@ define void @f1() #0 { } define void @f2() #0 { -; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable -; IS__TUNIT____-LABEL: define {{[^@]+}}@f2 -; IS__TUNIT____-SAME: () #[[ATTR4]] { -; IS__TUNIT____-NEXT: ret void +; NOT_CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@f2 +; NOT_CGSCC_NPM-SAME: () #[[ATTR4]] { +; NOT_CGSCC_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable -; IS__CGSCC____-LABEL: define {{[^@]+}}@f2 -; IS__CGSCC____-SAME: () #[[ATTR3]] { -; IS__CGSCC____-NEXT: ret void +; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2 +; IS__CGSCC_NPM-SAME: () #[[ATTR5]] { +; IS__CGSCC_NPM-NEXT: ret void ; tail call void @f1() ret void diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll index b4f8eaa598a5..17e9ff9c2647 100644 --- a/llvm/test/Transforms/Attributor/nonnull.ll +++ b/llvm/test/Transforms/Attributor/nonnull.ll @@ -31,27 +31,16 @@ define i8* @test2(i8* nonnull %p) { } define i8* @test2A(i1 %c, i8* %ret) { -; NOT_CGSCC_NPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test2A -; NOT_CGSCC_NPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2:[0-9]+]] { -; NOT_CGSCC_NPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] -; NOT_CGSCC_NPM: A: -; NOT_CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13:[0-9]+]] [ "nonnull"(i8* [[RET]]) ] -; NOT_CGSCC_NPM-NEXT: ret i8* [[RET]] -; NOT_CGSCC_NPM: B: -; NOT_CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[RET]]) ] -; NOT_CGSCC_NPM-NEXT: ret i8* [[RET]] -; -; IS__CGSCC_NPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2A -; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] -; IS__CGSCC_NPM: A: -; IS__CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12:[0-9]+]] [ "nonnull"(i8* [[RET]]) ] -; IS__CGSCC_NPM-NEXT: ret i8* [[RET]] -; IS__CGSCC_NPM: B: -; IS__CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "nonnull"(i8* [[RET]]) ] -; IS__CGSCC_NPM-NEXT: ret i8* [[RET]] +; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@test2A +; CHECK-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2:[0-9]+]] { +; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] +; CHECK: A: +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13:[0-9]+]] [ "nonnull"(i8* [[RET]]) ] +; CHECK-NEXT: ret i8* [[RET]] +; CHECK: B: +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[RET]]) ] +; CHECK-NEXT: ret i8* [[RET]] ; br i1 %c, label %A, label %B A: @@ -63,27 +52,16 @@ B: } define i8* @test2B(i1 %c, i8* %ret) { -; NOT_CGSCC_NPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test2B -; NOT_CGSCC_NPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2]] { -; NOT_CGSCC_NPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] -; NOT_CGSCC_NPM: A: -; NOT_CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ] -; NOT_CGSCC_NPM-NEXT: ret i8* [[RET]] -; NOT_CGSCC_NPM: B: -; NOT_CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ] -; NOT_CGSCC_NPM-NEXT: ret i8* [[RET]] -; -; IS__CGSCC_NPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2B -; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2]] { -; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] -; IS__CGSCC_NPM: A: -; IS__CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "dereferenceable"(i8* [[RET]], i32 4) ] -; IS__CGSCC_NPM-NEXT: ret i8* [[RET]] -; IS__CGSCC_NPM: B: -; IS__CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "dereferenceable"(i8* [[RET]], i32 4) ] -; IS__CGSCC_NPM-NEXT: ret i8* [[RET]] +; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@test2B +; CHECK-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] +; CHECK: A: +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ] +; CHECK-NEXT: ret i8* [[RET]] +; CHECK: B: +; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ] +; CHECK-NEXT: ret i8* [[RET]] ; br i1 %c, label %A, label %B A: @@ -315,21 +293,13 @@ define i8* @test9(i8* %a, i64 %n) { ; ATTRIBUTOR_OPM: define i8* @test10 ; ATTRIBUTOR_NPM: define nonnull i8* @test10 define i8* @test10(i8* %a, i64 %n) { -; NOT_CGSCC_NPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test10 -; NOT_CGSCC_NPM-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR2]] { -; NOT_CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp ne i64 [[N]], 0 -; NOT_CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef [[CMP]]) #[[ATTR13]] -; NOT_CGSCC_NPM-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]] -; NOT_CGSCC_NPM-NEXT: ret i8* [[B]] -; -; IS__CGSCC_NPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test10 -; IS__CGSCC_NPM-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR2]] { -; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp ne i64 [[N]], 0 -; IS__CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef [[CMP]]) #[[ATTR12]] -; IS__CGSCC_NPM-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]] -; IS__CGSCC_NPM-NEXT: ret i8* [[B]] +; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@test10 +; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[N]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 noundef [[CMP]]) #[[ATTR13]] +; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]] +; CHECK-NEXT: ret i8* [[B]] ; %cmp = icmp ne i64 %n, 0 call void @llvm.assume(i1 %cmp) @@ -477,11 +447,11 @@ define internal i32* @f1(i32* %arg) { ; IS__CGSCC_NPM-NEXT: br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]] ; IS__CGSCC_NPM: bb4: ; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 1 -; IS__CGSCC_NPM-NEXT: [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR13:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR14:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[TMP5C:%.*]] = getelementptr inbounds i32, i32* [[TMP5B]], i64 -1 ; IS__CGSCC_NPM-NEXT: br label [[BB9]] ; IS__CGSCC_NPM: bb6: -; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = tail call i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = tail call i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR14]] ; IS__CGSCC_NPM-NEXT: ret i32* [[TMP7]] ; IS__CGSCC_NPM: bb9: ; IS__CGSCC_NPM-NEXT: [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to i32*), [[BB:%.*]] ] @@ -524,7 +494,7 @@ define internal i32* @f2(i32* %arg) { ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2 ; IS__CGSCC_NPM-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5]] { ; IS__CGSCC_NPM-NEXT: bb: -; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = tail call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = tail call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]] ; IS__CGSCC_NPM-NEXT: ret i32* [[TMP]] ; bb: @@ -545,7 +515,7 @@ define dso_local noalias i32* @f3(i32* %arg) { ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f3 ; IS__CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5]] { ; IS__CGSCC_NPM-NEXT: bb: -; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = call i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]] ; IS__CGSCC_NPM-NEXT: ret i32* [[TMP]] ; bb: @@ -907,17 +877,11 @@ define i8 @parent6(i8* %a, i8* %b) { ; The nonnull callsite is guaranteed to execute, so the argument must be nonnull throughout the parent. define i8 @parent7(i8* %a) { -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@parent7 -; NOT_CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]]) { -; NOT_CGSCC_NPM-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR15:[0-9]+]] -; NOT_CGSCC_NPM-NEXT: call void @use1nonnull(i8* nonnull [[A]]) -; NOT_CGSCC_NPM-NEXT: ret i8 [[RET]] -; -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@parent7 -; IS__CGSCC_NPM-SAME: (i8* nonnull [[A:%.*]]) { -; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR14:[0-9]+]] -; IS__CGSCC_NPM-NEXT: call void @use1nonnull(i8* nonnull [[A]]) -; IS__CGSCC_NPM-NEXT: ret i8 [[RET]] +; CHECK-LABEL: define {{[^@]+}}@parent7 +; CHECK-SAME: (i8* nonnull [[A:%.*]]) { +; CHECK-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR15:[0-9]+]] +; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]]) +; CHECK-NEXT: ret i8 [[RET]] ; @@ -1033,10 +997,22 @@ define internal i32* @g2() { } define i32* @g1() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@g1 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i32* inttoptr (i64 4 to i32*) +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@g1 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i32* inttoptr (i64 4 to i32*) +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g1 +; IS__CGSCC_OPM-SAME: () #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef nonnull align 4 i32* @g2() #[[ATTR16:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32* [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g1 +; IS__CGSCC_NPM-SAME: () #[[ATTR9:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef nonnull align 4 i32* @g2() #[[ATTR16:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32* [[C]] ; %c = call i32* @g2() ret i32* %c @@ -1096,17 +1072,11 @@ define internal void @control(i32* dereferenceable(4) %a) { } ; Avoid nonnull as we do not touch naked functions define internal void @naked(i32* dereferenceable(4) %a) naked { -; NOT_CGSCC_NPM: Function Attrs: naked -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@naked -; NOT_CGSCC_NPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] { -; NOT_CGSCC_NPM-NEXT: call void @use_i32_ptr(i32* [[A]]) -; NOT_CGSCC_NPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: naked -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@naked -; IS__CGSCC_NPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR9:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: call void @use_i32_ptr(i32* [[A]]) -; IS__CGSCC_NPM-NEXT: ret void +; CHECK: Function Attrs: naked +; CHECK-LABEL: define {{[^@]+}}@naked +; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] { +; CHECK-NEXT: call void @use_i32_ptr(i32* [[A]]) +; CHECK-NEXT: ret void ; call void @use_i32_ptr(i32* %a) ret void @@ -1114,17 +1084,11 @@ define internal void @naked(i32* dereferenceable(4) %a) naked { ; Avoid nonnull as we do not touch optnone define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline { ; -; NOT_CGSCC_NPM: Function Attrs: noinline optnone -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@optnone -; NOT_CGSCC_NPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR11:[0-9]+]] { -; NOT_CGSCC_NPM-NEXT: call void @use_i32_ptr(i32* [[A]]) -; NOT_CGSCC_NPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: noinline optnone -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@optnone -; IS__CGSCC_NPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: call void @use_i32_ptr(i32* [[A]]) -; IS__CGSCC_NPM-NEXT: ret void +; CHECK: Function Attrs: noinline optnone +; CHECK-LABEL: define {{[^@]+}}@optnone +; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR11:[0-9]+]] { +; CHECK-NEXT: call void @use_i32_ptr(i32* [[A]]) +; CHECK-NEXT: ret void ; call void @use_i32_ptr(i32* %a) ret void @@ -1523,23 +1487,14 @@ declare i8* @strrchr(i8* %0, i32 %1) nofree nounwind readonly willreturn ; We should not mark the return of @strrchr as `nonnull`, it may well be NULL! define i8* @mybasename(i8* nofree readonly %str) { -; NOT_CGSCC_NPM: Function Attrs: nofree nounwind readonly willreturn -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@mybasename -; NOT_CGSCC_NPM-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR12:[0-9]+]] { -; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR15]] -; NOT_CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null -; NOT_CGSCC_NPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1 -; NOT_CGSCC_NPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]] -; NOT_CGSCC_NPM-NEXT: ret i8* [[COND]] -; -; IS__CGSCC_NPM: Function Attrs: nofree nounwind readonly willreturn -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@mybasename -; IS__CGSCC_NPM-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR11:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR14]] -; IS__CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null -; IS__CGSCC_NPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1 -; IS__CGSCC_NPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]] -; IS__CGSCC_NPM-NEXT: ret i8* [[COND]] +; CHECK: Function Attrs: nofree nounwind readonly willreturn +; CHECK-LABEL: define {{[^@]+}}@mybasename +; CHECK-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR12:[0-9]+]] { +; CHECK-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR15]] +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null +; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1 +; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]] +; CHECK-NEXT: ret i8* [[COND]] ; %call = call i8* @strrchr(i8* %str, i32 47) %tobool = icmp ne i8* %call, null @@ -1565,7 +1520,7 @@ define void @nonnull_assume_pos(i8* %arg) { ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@nonnull_assume_pos ; IS__CGSCC_NPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]]) { -; IS__CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "nonnull"(i8* [[ARG]]) ] +; IS__CGSCC_NPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[ARG]]) ] ; IS__CGSCC_NPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]] ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = call i8* @unknown() ; IS__CGSCC_NPM-NEXT: ret void @@ -1663,22 +1618,40 @@ declare void @nonnull_callee(i8* nonnull %p) attributes #0 = { null_pointer_is_valid } attributes #1 = { nounwind willreturn} ;. -; NOT_CGSCC_NPM: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR2]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR4]] = { noreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR5]] = { nounwind } -; NOT_CGSCC_NPM: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind readonly } -; NOT_CGSCC_NPM: attributes #[[ATTR7]] = { nounwind willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR8:[0-9]+]] = { nounwind readonly willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR10]] = { naked } -; NOT_CGSCC_NPM: attributes #[[ATTR11]] = { noinline optnone } -; NOT_CGSCC_NPM: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR13]] = { willreturn } -; NOT_CGSCC_NPM: attributes #[[ATTR14]] = { nofree nosync nounwind readonly } -; NOT_CGSCC_NPM: attributes #[[ATTR15]] = { readonly willreturn } +; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR2]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR4]] = { noreturn } +; IS__TUNIT____: attributes #[[ATTR5]] = { nounwind } +; IS__TUNIT____: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind readonly } +; IS__TUNIT____: attributes #[[ATTR7]] = { nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR8:[0-9]+]] = { nounwind readonly willreturn } +; IS__TUNIT____: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR10]] = { naked } +; IS__TUNIT____: attributes #[[ATTR11]] = { noinline optnone } +; IS__TUNIT____: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn } +; IS__TUNIT____: attributes #[[ATTR13]] = { willreturn } +; IS__TUNIT____: attributes #[[ATTR14]] = { nofree nosync nounwind readonly } +; IS__TUNIT____: attributes #[[ATTR15]] = { readonly willreturn } +;. +; IS__CGSCC_OPM: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR2]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR4]] = { noreturn } +; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind readonly } +; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR8:[0-9]+]] = { nounwind readonly willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR10]] = { naked } +; IS__CGSCC_OPM: attributes #[[ATTR11]] = { noinline optnone } +; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR13]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree nosync nounwind readonly } +; IS__CGSCC_OPM: attributes #[[ATTR15]] = { readonly willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR16]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } @@ -1689,10 +1662,12 @@ attributes #1 = { nounwind willreturn} ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR7:[0-9]+]] = { nounwind readonly willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR9]] = { naked } -; IS__CGSCC_NPM: attributes #[[ATTR10]] = { noinline optnone } -; IS__CGSCC_NPM: attributes #[[ATTR11]] = { nofree nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR12]] = { willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR13]] = { nofree nosync nounwind readonly } -; IS__CGSCC_NPM: attributes #[[ATTR14]] = { readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR10]] = { naked } +; IS__CGSCC_NPM: attributes #[[ATTR11]] = { noinline optnone } +; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR13]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR14]] = { nofree nosync nounwind readonly } +; IS__CGSCC_NPM: attributes #[[ATTR15]] = { readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR16]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/norecurse.ll b/llvm/test/Transforms/Attributor/norecurse.ll index dd096a32c147..945c0f93fe73 100644 --- a/llvm/test/Transforms/Attributor/norecurse.ll +++ b/llvm/test/Transforms/Attributor/norecurse.ll @@ -110,11 +110,17 @@ define void @m() norecurse { } define internal i32 @called_by_norecurse_indirectly() { -; CHECK: Function Attrs: norecurse nosync readnone -; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly -; CHECK-SAME: () #[[ATTR6]] { -; CHECK-NEXT: [[A:%.*]] = call i32 @k() -; CHECK-NEXT: ret i32 [[A]] +; IS__TUNIT____: Function Attrs: norecurse nosync readnone +; IS__TUNIT____-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly +; IS__TUNIT____-SAME: () #[[ATTR6]] { +; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @k() +; IS__TUNIT____-NEXT: ret i32 [[A]] +; +; IS__CGSCC____: Function Attrs: nosync readnone +; IS__CGSCC____-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @k() +; IS__CGSCC____-NEXT: ret i32 [[A]] ; %a = call i32 @k() ret i32 %a diff --git a/llvm/test/Transforms/Attributor/noreturn.ll b/llvm/test/Transforms/Attributor/noreturn.ll index 5dee60a13818..cc357c8d9f01 100644 --- a/llvm/test/Transforms/Attributor/noreturn.ll +++ b/llvm/test/Transforms/Attributor/noreturn.ll @@ -128,18 +128,31 @@ return: ; No predecessors! ; } ; define i32 @multiple_noreturn_calls(i32 %a) #0 { -; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@multiple_noreturn_calls -; CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0 -; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] -; CHECK: cond.true: -; CHECK-NEXT: unreachable -; CHECK: cond.false: -; CHECK-NEXT: unreachable -; CHECK: cond.end: -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone willreturn uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@multiple_noreturn_calls +; IS__TUNIT____-SAME: (i32 [[A:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0 +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS__TUNIT____: cond.true: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: cond.false: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: cond.end: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree noinline noreturn nosync nounwind readnone willreturn uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@multiple_noreturn_calls +; IS__CGSCC____-SAME: (i32 [[A:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0 +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +; IS__CGSCC____: cond.true: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: cond.false: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: cond.end: +; IS__CGSCC____-NEXT: unreachable ; entry: %cmp = icmp eq i32 %a, 0 @@ -163,13 +176,21 @@ cond.end: ; preds = %cond.false, %cond.t ; FIXME: we should derive "UB" as an argument and report it to the user on request. define i32 @endless_loop_but_willreturn() willreturn { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@endless_loop_but_willreturn -; CHECK-SAME: () #[[ATTR4:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: br label [[WHILE_BODY:%.*]] -; CHECK: while.body: -; CHECK-NEXT: br label [[WHILE_BODY]] +; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@endless_loop_but_willreturn +; IS__TUNIT____-SAME: () #[[ATTR4:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: br label [[WHILE_BODY:%.*]] +; IS__TUNIT____: while.body: +; IS__TUNIT____-NEXT: br label [[WHILE_BODY]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@endless_loop_but_willreturn +; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: br label [[WHILE_BODY:%.*]] +; IS__CGSCC____: while.body: +; IS__CGSCC____-NEXT: br label [[WHILE_BODY]] ; entry: br label %while.body @@ -180,11 +201,17 @@ while.body: ; preds = %entry, %while.body ; TEST 6b: willreturn means *not* no-return or UB define i32 @UB_and_willreturn() willreturn { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@UB_and_willreturn -; CHECK-SAME: () #[[ATTR4]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@UB_and_willreturn +; IS__TUNIT____-SAME: () #[[ATTR4]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@UB_and_willreturn +; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: unreachable ; entry: unreachable @@ -192,9 +219,14 @@ entry: attributes #0 = { noinline nounwind uwtable } ;. -; CHECK: attributes #[[ATTR0]] = { nofree noinline nosync nounwind readnone willreturn uwtable } -; CHECK: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone willreturn uwtable } -; CHECK: attributes #[[ATTR2]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } -; CHECK: attributes #[[ATTR3]] = { nofree noinline norecurse noreturn nosync nounwind readnone willreturn uwtable } -; CHECK: attributes #[[ATTR4]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree noinline nosync nounwind readnone willreturn uwtable } +; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone willreturn uwtable } +; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } +; IS__TUNIT____: attributes #[[ATTR3]] = { nofree noinline norecurse noreturn nosync nounwind readnone willreturn uwtable } +; IS__TUNIT____: attributes #[[ATTR4]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline nosync nounwind readnone willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/nounwind.ll b/llvm/test/Transforms/Attributor/nounwind.ll index 51fd4df48840..f1349d4c5e04 100644 --- a/llvm/test/Transforms/Attributor/nounwind.ll +++ b/llvm/test/Transforms/Attributor/nounwind.ll @@ -128,9 +128,13 @@ define i32 @catch_thing() personality i8* bitcast (i32 (...)* @__gxx_personality } define i32 @catch_thing_user() { -; CHECK-LABEL: define {{[^@]+}}@catch_thing_user() { -; CHECK-NEXT: [[CATCH_THING_CALL:%.*]] = call i32 @catch_thing() -; CHECK-NEXT: ret i32 -1 +; IS__TUNIT____-LABEL: define {{[^@]+}}@catch_thing_user() { +; IS__TUNIT____-NEXT: [[CATCH_THING_CALL:%.*]] = call i32 @catch_thing() +; IS__TUNIT____-NEXT: ret i32 -1 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@catch_thing_user() { +; IS__CGSCC____-NEXT: [[CATCH_THING_CALL:%.*]] = call noundef i32 @catch_thing() +; IS__CGSCC____-NEXT: ret i32 [[CATCH_THING_CALL]] ; %catch_thing_call = call i32 @catch_thing() ret i32 %catch_thing_call diff --git a/llvm/test/Transforms/Attributor/openmp_parallel.ll b/llvm/test/Transforms/Attributor/openmp_parallel.ll index 5243d10da3fe..a4b8197d7353 100644 --- a/llvm/test/Transforms/Attributor/openmp_parallel.ll +++ b/llvm/test/Transforms/Attributor/openmp_parallel.ll @@ -45,31 +45,18 @@ define dso_local void @func(float* nocapture %a, float* %b, i32 %N) local_unname ; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB2]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float**, float**)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef, float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A_ADDR]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B_ADDR]]) ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nounwind uwtable -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@func -; IS__CGSCC_OPM-SAME: (float* nocapture nofree [[A:%.*]], float* nofree [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[A_ADDR:%.*]] = alloca float*, align 8 -; IS__CGSCC_OPM-NEXT: [[B_ADDR:%.*]] = alloca float*, align 8 -; IS__CGSCC_OPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 -; IS__CGSCC_OPM-NEXT: store float* [[A]], float** [[A_ADDR]], align 8 -; IS__CGSCC_OPM-NEXT: store float* [[B]], float** [[B_ADDR]], align 8 -; IS__CGSCC_OPM-NEXT: store i32 199, i32* [[N_ADDR]], align 4 -; IS__CGSCC_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB2]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float**, float**)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[N_ADDR]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A_ADDR]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B_ADDR]]) -; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: nounwind uwtable -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@func -; IS__CGSCC_NPM-SAME: (float* nocapture nofree [[A:%.*]], float* nofree [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[A_ADDR:%.*]] = alloca float*, align 8 -; IS__CGSCC_NPM-NEXT: [[B_ADDR:%.*]] = alloca float*, align 8 -; IS__CGSCC_NPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: store float* [[A]], float** [[A_ADDR]], align 8 -; IS__CGSCC_NPM-NEXT: store float* [[B]], float** [[B_ADDR]], align 8 -; IS__CGSCC_NPM-NEXT: store i32 199, i32* [[N_ADDR]], align 4 -; IS__CGSCC_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB2]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float**, float**)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[N_ADDR]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A_ADDR]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B_ADDR]]) -; IS__CGSCC_NPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nounwind uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@func +; IS__CGSCC____-SAME: (float* nocapture nofree [[A:%.*]], float* nofree [[B:%.*]], i32 [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[A_ADDR:%.*]] = alloca float*, align 8 +; IS__CGSCC____-NEXT: [[B_ADDR:%.*]] = alloca float*, align 8 +; IS__CGSCC____-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4 +; IS__CGSCC____-NEXT: store float* [[A]], float** [[A_ADDR]], align 8 +; IS__CGSCC____-NEXT: store float* [[B]], float** [[B_ADDR]], align 8 +; IS__CGSCC____-NEXT: store i32 199, i32* [[N_ADDR]], align 4 +; IS__CGSCC____-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB2]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float**, float**)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float** nofree noundef nonnull readonly align 8 dereferenceable(8) [[A_ADDR]], float** nofree noundef nonnull readonly align 8 dereferenceable(8) [[B_ADDR]]) +; IS__CGSCC____-NEXT: ret void ; entry: %a.addr = alloca float*, align 8 @@ -85,119 +72,239 @@ entry: ; FIXME: %N should not be loaded but 199 should be used. define internal void @.omp_outlined.(i32* noalias nocapture readonly %.global_tid., i32* noalias nocapture readnone %.bound_tid., i32* nocapture nonnull readonly align 4 dereferenceable(4) %N, float** nocapture nonnull readonly align 8 dereferenceable(8) %a, float** nocapture nonnull readonly align 8 dereferenceable(8) %b) #1 { -; IS________OPM: Function Attrs: alwaysinline nofree norecurse nounwind uwtable -; IS________OPM-LABEL: define {{[^@]+}}@.omp_outlined. -; IS________OPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[N:%.*]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A:%.*]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR1:[0-9]+]] { -; IS________OPM-NEXT: entry: -; 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: br label [[OMP_PRECOND_THEN:%.*]] -; IS________OPM: omp.precond.then: -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) -; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________OPM-NEXT: store i32 197, i32* [[DOTOMP_UB]], align 4 -; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) -; IS________OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 -; IS________OPM-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) -; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 -; IS________OPM-NEXT: [[TMP4:%.*]] = 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) @[[GLOB1]], i32 [[TMP4]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) -; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS________OPM-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP5]], 197 -; IS________OPM-NEXT: [[COND:%.*]] = select i1 [[CMP4]], i32 197, i32 [[TMP5]] -; IS________OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 -; IS________OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 -; IS________OPM-NEXT: [[CMP513:%.*]] = icmp sgt i32 [[TMP6]], [[COND]] -; IS________OPM-NEXT: br i1 [[CMP513]], label [[OMP_LOOP_EXIT:%.*]], label [[OMP_INNER_FOR_BODY_LR_PH:%.*]] -; IS________OPM: omp.inner.for.body.lr.ph: -; IS________OPM-NEXT: [[TMP7:%.*]] = load float*, float** [[B]], align 8 -; IS________OPM-NEXT: [[TMP8:%.*]] = load float*, float** [[A]], align 8 -; IS________OPM-NEXT: [[TMP9:%.*]] = sext i32 [[TMP6]] to i64 -; IS________OPM-NEXT: [[TMP10:%.*]] = sext i32 [[COND]] to i64 -; IS________OPM-NEXT: br label [[OMP_INNER_FOR_BODY:%.*]] -; IS________OPM: omp.inner.for.body: -; IS________OPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[OMP_INNER_FOR_BODY]] ], [ [[TMP9]], [[OMP_INNER_FOR_BODY_LR_PH]] ] -; IS________OPM-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 -; IS________OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[TMP7]], i64 [[INDVARS_IV_NEXT]] -; IS________OPM-NEXT: [[TMP11:%.*]] = load float, float* [[ARRAYIDX]], align 4 -; IS________OPM-NEXT: [[CONV7:%.*]] = fadd float [[TMP11]], 1.000000e+00 -; IS________OPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float* [[TMP8]], i64 [[INDVARS_IV_NEXT]] -; IS________OPM-NEXT: store float [[CONV7]], float* [[ARRAYIDX9]], align 4 -; IS________OPM-NEXT: [[CMP5:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP10]] -; IS________OPM-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY]], label [[OMP_LOOP_EXIT]] -; IS________OPM: omp.loop.exit: -; IS________OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP4]]) -; IS________OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) -; IS________OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) -; IS________OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) -; IS________OPM-NEXT: br label [[OMP_PRECOND_END:%.*]] -; IS________OPM: omp.precond.end: -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: alwaysinline nofree norecurse nounwind uwtable +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[N:%.*]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A:%.*]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: br label [[OMP_PRECOND_THEN:%.*]] +; IS__TUNIT_OPM: omp.precond.then: +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT_OPM-NEXT: store i32 197, i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) +; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) +; IS__TUNIT_OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS__TUNIT_OPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP4]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) +; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_OPM-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP5]], 197 +; IS__TUNIT_OPM-NEXT: [[COND:%.*]] = select i1 [[CMP4]], i32 197, i32 [[TMP5]] +; IS__TUNIT_OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS__TUNIT_OPM-NEXT: [[CMP513:%.*]] = icmp sgt i32 [[TMP6]], [[COND]] +; IS__TUNIT_OPM-NEXT: br i1 [[CMP513]], label [[OMP_LOOP_EXIT:%.*]], label [[OMP_INNER_FOR_BODY_LR_PH:%.*]] +; IS__TUNIT_OPM: omp.inner.for.body.lr.ph: +; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = load float*, float** [[B]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP8:%.*]] = load float*, float** [[A]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP9:%.*]] = sext i32 [[TMP6]] to i64 +; IS__TUNIT_OPM-NEXT: [[TMP10:%.*]] = sext i32 [[COND]] to i64 +; IS__TUNIT_OPM-NEXT: br label [[OMP_INNER_FOR_BODY:%.*]] +; IS__TUNIT_OPM: omp.inner.for.body: +; IS__TUNIT_OPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[OMP_INNER_FOR_BODY]] ], [ [[TMP9]], [[OMP_INNER_FOR_BODY_LR_PH]] ] +; IS__TUNIT_OPM-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; IS__TUNIT_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[TMP7]], i64 [[INDVARS_IV_NEXT]] +; IS__TUNIT_OPM-NEXT: [[TMP11:%.*]] = load float, float* [[ARRAYIDX]], align 4 +; IS__TUNIT_OPM-NEXT: [[CONV7:%.*]] = fadd float [[TMP11]], 1.000000e+00 +; IS__TUNIT_OPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float* [[TMP8]], i64 [[INDVARS_IV_NEXT]] +; IS__TUNIT_OPM-NEXT: store float [[CONV7]], float* [[ARRAYIDX9]], align 4 +; IS__TUNIT_OPM-NEXT: [[CMP5:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP10]] +; IS__TUNIT_OPM-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY]], label [[OMP_LOOP_EXIT]] +; IS__TUNIT_OPM: omp.loop.exit: +; IS__TUNIT_OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP4]]) +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_OPM-NEXT: br label [[OMP_PRECOND_END:%.*]] +; IS__TUNIT_OPM: omp.precond.end: +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: alwaysinline nofree norecurse nounwind uwtable -; IS________NPM-LABEL: define {{[^@]+}}@.omp_outlined. -; IS________NPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[N:%.*]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A:%.*]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR1:[0-9]+]] { -; IS________NPM-NEXT: entry: -; 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: br label [[OMP_PRECOND_THEN:%.*]] -; IS________NPM: omp.precond.then: -; IS________NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) -; IS________NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 -; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________NPM-NEXT: store i32 197, i32* [[DOTOMP_UB]], align 4 -; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) -; IS________NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 -; IS________NPM-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) -; IS________NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 -; IS________NPM-NEXT: [[TMP4:%.*]] = 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) @[[GLOB1]], i32 [[TMP4]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) -; IS________NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 -; IS________NPM-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP5]], 197 -; IS________NPM-NEXT: [[COND:%.*]] = select i1 [[CMP4]], i32 197, i32 [[TMP5]] -; IS________NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 -; IS________NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 -; IS________NPM-NEXT: [[CMP513:%.*]] = icmp sgt i32 [[TMP6]], [[COND]] -; IS________NPM-NEXT: br i1 [[CMP513]], label [[OMP_LOOP_EXIT:%.*]], label [[OMP_INNER_FOR_BODY_LR_PH:%.*]] -; IS________NPM: omp.inner.for.body.lr.ph: -; IS________NPM-NEXT: [[TMP7:%.*]] = load float*, float** [[B]], align 8 -; IS________NPM-NEXT: [[TMP8:%.*]] = load float*, float** [[A]], align 8 -; IS________NPM-NEXT: [[TMP9:%.*]] = sext i32 [[TMP6]] to i64 -; IS________NPM-NEXT: [[TMP10:%.*]] = sext i32 [[COND]] to i64 -; IS________NPM-NEXT: br label [[OMP_INNER_FOR_BODY:%.*]] -; IS________NPM: omp.inner.for.body: -; IS________NPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[OMP_INNER_FOR_BODY]] ], [ [[TMP9]], [[OMP_INNER_FOR_BODY_LR_PH]] ] -; IS________NPM-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 -; IS________NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[TMP7]], i64 [[INDVARS_IV_NEXT]] -; IS________NPM-NEXT: [[TMP11:%.*]] = load float, float* [[ARRAYIDX]], align 4 -; IS________NPM-NEXT: [[CONV7:%.*]] = fadd float [[TMP11]], 1.000000e+00 -; IS________NPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float* [[TMP8]], i64 [[INDVARS_IV_NEXT]] -; IS________NPM-NEXT: store float [[CONV7]], float* [[ARRAYIDX9]], align 4 -; IS________NPM-NEXT: [[CMP5:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP10]] -; IS________NPM-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY]], label [[OMP_LOOP_EXIT]] -; IS________NPM: omp.loop.exit: -; IS________NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP4]]) -; IS________NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) -; IS________NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) -; IS________NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) -; IS________NPM-NEXT: br label [[OMP_PRECOND_END:%.*]] -; IS________NPM: omp.precond.end: -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: alwaysinline nofree norecurse nounwind uwtable +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS__TUNIT_NPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[N:%.*]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A:%.*]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: entry: +; 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: br label [[OMP_PRECOND_THEN:%.*]] +; IS__TUNIT_NPM: omp.precond.then: +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT_NPM-NEXT: store i32 197, i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) +; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = 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) @[[GLOB1]], i32 [[TMP4]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) +; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_NPM-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP5]], 197 +; IS__TUNIT_NPM-NEXT: [[COND:%.*]] = select i1 [[CMP4]], i32 197, i32 [[TMP5]] +; IS__TUNIT_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS__TUNIT_NPM-NEXT: [[CMP513:%.*]] = icmp sgt i32 [[TMP6]], [[COND]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP513]], label [[OMP_LOOP_EXIT:%.*]], label [[OMP_INNER_FOR_BODY_LR_PH:%.*]] +; IS__TUNIT_NPM: omp.inner.for.body.lr.ph: +; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = load float*, float** [[B]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP8:%.*]] = load float*, float** [[A]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP9:%.*]] = sext i32 [[TMP6]] to i64 +; IS__TUNIT_NPM-NEXT: [[TMP10:%.*]] = sext i32 [[COND]] to i64 +; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_BODY:%.*]] +; IS__TUNIT_NPM: omp.inner.for.body: +; IS__TUNIT_NPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[OMP_INNER_FOR_BODY]] ], [ [[TMP9]], [[OMP_INNER_FOR_BODY_LR_PH]] ] +; IS__TUNIT_NPM-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; IS__TUNIT_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[TMP7]], i64 [[INDVARS_IV_NEXT]] +; IS__TUNIT_NPM-NEXT: [[TMP11:%.*]] = load float, float* [[ARRAYIDX]], align 4 +; IS__TUNIT_NPM-NEXT: [[CONV7:%.*]] = fadd float [[TMP11]], 1.000000e+00 +; IS__TUNIT_NPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float* [[TMP8]], i64 [[INDVARS_IV_NEXT]] +; IS__TUNIT_NPM-NEXT: store float [[CONV7]], float* [[ARRAYIDX9]], align 4 +; IS__TUNIT_NPM-NEXT: [[CMP5:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP10]] +; IS__TUNIT_NPM-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY]], label [[OMP_LOOP_EXIT]] +; IS__TUNIT_NPM: omp.loop.exit: +; IS__TUNIT_NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP4]]) +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP0]]) +; IS__TUNIT_NPM-NEXT: br label [[OMP_PRECOND_END:%.*]] +; IS__TUNIT_NPM: omp.precond.end: +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: alwaysinline nofree norecurse nounwind uwtable +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A:%.*]], float** nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[N]], align 4 +; IS__CGSCC_OPM-NEXT: [[SUB2:%.*]] = add nsw i32 [[TMP0]], -2 +; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP0]], 1 +; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +; IS__CGSCC_OPM: omp.precond.then: +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) +; IS__CGSCC_OPM-NEXT: store i32 [[SUB2]], i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP4]]) +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS__CGSCC_OPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) +; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_OPM-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP6]], [[SUB2]] +; IS__CGSCC_OPM-NEXT: [[COND:%.*]] = select i1 [[CMP4]], i32 [[SUB2]], i32 [[TMP6]] +; IS__CGSCC_OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS__CGSCC_OPM-NEXT: [[CMP513:%.*]] = icmp sgt i32 [[TMP7]], [[COND]] +; IS__CGSCC_OPM-NEXT: br i1 [[CMP513]], label [[OMP_LOOP_EXIT:%.*]], label [[OMP_INNER_FOR_BODY_LR_PH:%.*]] +; IS__CGSCC_OPM: omp.inner.for.body.lr.ph: +; IS__CGSCC_OPM-NEXT: [[TMP8:%.*]] = load float*, float** [[B]], align 8 +; IS__CGSCC_OPM-NEXT: [[TMP9:%.*]] = load float*, float** [[A]], align 8 +; IS__CGSCC_OPM-NEXT: [[TMP10:%.*]] = sext i32 [[TMP7]] to i64 +; IS__CGSCC_OPM-NEXT: [[TMP11:%.*]] = sext i32 [[COND]] to i64 +; IS__CGSCC_OPM-NEXT: br label [[OMP_INNER_FOR_BODY:%.*]] +; IS__CGSCC_OPM: omp.inner.for.body: +; IS__CGSCC_OPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[OMP_INNER_FOR_BODY]] ], [ [[TMP10]], [[OMP_INNER_FOR_BODY_LR_PH]] ] +; IS__CGSCC_OPM-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; IS__CGSCC_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[TMP8]], i64 [[INDVARS_IV_NEXT]] +; IS__CGSCC_OPM-NEXT: [[TMP12:%.*]] = load float, float* [[ARRAYIDX]], align 4 +; IS__CGSCC_OPM-NEXT: [[CONV7:%.*]] = fadd float [[TMP12]], 1.000000e+00 +; IS__CGSCC_OPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float* [[TMP9]], i64 [[INDVARS_IV_NEXT]] +; IS__CGSCC_OPM-NEXT: store float [[CONV7]], float* [[ARRAYIDX9]], align 4 +; IS__CGSCC_OPM-NEXT: [[CMP5:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP11]] +; IS__CGSCC_OPM-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY]], label [[OMP_LOOP_EXIT]] +; IS__CGSCC_OPM: omp.loop.exit: +; IS__CGSCC_OPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP5]]) +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP4]]) +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC_OPM-NEXT: br label [[OMP_PRECOND_END]] +; IS__CGSCC_OPM: omp.precond.end: +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: alwaysinline nofree norecurse nounwind uwtable +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@.omp_outlined. +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[A:%.*]], float** noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[N]], align 4 +; IS__CGSCC_NPM-NEXT: [[SUB2:%.*]] = add nsw i32 [[TMP0]], -2 +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP0]], 1 +; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] +; IS__CGSCC_NPM: omp.precond.then: +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) +; IS__CGSCC_NPM-NEXT: store i32 [[SUB2]], i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP4]]) +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 +; IS__CGSCC_NPM-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1) +; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_NPM-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP6]], [[SUB2]] +; IS__CGSCC_NPM-NEXT: [[COND:%.*]] = select i1 [[CMP4]], i32 [[SUB2]], i32 [[TMP6]] +; IS__CGSCC_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4 +; IS__CGSCC_NPM-NEXT: [[CMP513:%.*]] = icmp sgt i32 [[TMP7]], [[COND]] +; IS__CGSCC_NPM-NEXT: br i1 [[CMP513]], label [[OMP_LOOP_EXIT:%.*]], label [[OMP_INNER_FOR_BODY_LR_PH:%.*]] +; IS__CGSCC_NPM: omp.inner.for.body.lr.ph: +; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = load float*, float** [[B]], align 8 +; IS__CGSCC_NPM-NEXT: [[TMP9:%.*]] = load float*, float** [[A]], align 8 +; IS__CGSCC_NPM-NEXT: [[TMP10:%.*]] = sext i32 [[TMP7]] to i64 +; IS__CGSCC_NPM-NEXT: [[TMP11:%.*]] = sext i32 [[COND]] to i64 +; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_BODY:%.*]] +; IS__CGSCC_NPM: omp.inner.for.body: +; IS__CGSCC_NPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[OMP_INNER_FOR_BODY]] ], [ [[TMP10]], [[OMP_INNER_FOR_BODY_LR_PH]] ] +; IS__CGSCC_NPM-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; IS__CGSCC_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[TMP8]], i64 [[INDVARS_IV_NEXT]] +; IS__CGSCC_NPM-NEXT: [[TMP12:%.*]] = load float, float* [[ARRAYIDX]], align 4 +; IS__CGSCC_NPM-NEXT: [[CONV7:%.*]] = fadd float [[TMP12]], 1.000000e+00 +; IS__CGSCC_NPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds float, float* [[TMP9]], i64 [[INDVARS_IV_NEXT]] +; IS__CGSCC_NPM-NEXT: store float [[CONV7]], float* [[ARRAYIDX9]], align 4 +; IS__CGSCC_NPM-NEXT: [[CMP5:%.*]] = icmp slt i64 [[INDVARS_IV]], [[TMP11]] +; IS__CGSCC_NPM-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY]], label [[OMP_LOOP_EXIT]] +; IS__CGSCC_NPM: omp.loop.exit: +; IS__CGSCC_NPM-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP5]]) +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP4]]) +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP3]]) +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP2]]) +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC_NPM-NEXT: br label [[OMP_PRECOND_END]] +; IS__CGSCC_NPM: omp.precond.end: +; IS__CGSCC_NPM-NEXT: ret void ; entry: %.omp.lb = alloca i32, align 4 diff --git a/llvm/test/Transforms/Attributor/potential.ll b/llvm/test/Transforms/Attributor/potential.ll index 53cd9ec41e18..b90e7d16a4b4 100644 --- a/llvm/test/Transforms/Attributor/potential.ll +++ b/llvm/test/Transforms/Attributor/potential.ll @@ -13,18 +13,33 @@ define internal i1 @iszero1(i32 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero1 -; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] { -; IS__CGSCC____-NEXT: ret i1 false +; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 +; IS__CGSCC____-NEXT: ret i1 [[CMP]] ; %cmp = icmp eq i32 %c, 0 ret i1 %cmp } define i1 @potential_test1(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@potential_test1 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: ret i1 false +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test1 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: ret i1 false +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test1 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[ARG:%.*]] = select i1 [[C]], i32 -1, i32 1 +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i1 @iszero1(i32 noundef [[ARG]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test1 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[ARG:%.*]] = select i1 [[C]], i32 -1, i32 1 +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i1 @iszero1(i32 noundef [[ARG]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] ; %arg = select i1 %c, i32 -1, i32 1 %ret = call i1 @iszero1(i32 %arg) @@ -43,8 +58,10 @@ define i1 @potential_test1(i1 %c) { define internal i32 @iszero2(i32 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero2 -; IS__CGSCC____-SAME: () #[[ATTR0]] { -; IS__CGSCC____-NEXT: ret i32 0 +; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 +; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32 +; IS__CGSCC____-NEXT: ret i32 [[RET]] ; %cmp = icmp eq i32 %c, 0 %ret = zext i1 %cmp to i32 @@ -52,10 +69,23 @@ define internal i32 @iszero2(i32 %c) { } 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: () #[[ATTR0]] { -; IS__CGSCC____-NEXT: ret i32 0 +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@call_with_two_values +; IS__CGSCC_OPM-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 noundef [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[MINUSC:%.*]] = sub i32 0, [[C]] +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @iszero2(i32 [[MINUSC]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@call_with_two_values +; IS__CGSCC_NPM-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @iszero2(i32 noundef [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[MINUSC:%.*]] = sub i32 0, [[C]] +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @iszero2(i32 [[MINUSC]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %csret1 = call i32 @iszero2(i32 %c) %minusc = sub i32 0, %c @@ -65,10 +95,26 @@ define internal i32 @call_with_two_values(i32 %c) { } define i32 @potential_test2(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@potential_test2 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test2 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test2 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 noundef 1) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 noundef -1) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test2 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @call_with_two_values(i32 noundef 1) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @call_with_two_values(i32 noundef -1) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = add i32 [[CSRET1]], [[CSRET2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %csret1 = call i32 @call_with_two_values(i32 1) %csret2 = call i32 @call_with_two_values(i32 -1) @@ -114,10 +160,30 @@ define internal i32 @less_than_two(i32 %c) { } define i32 @potential_test3() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@potential_test3 -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: ret i32 2 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test3 +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32 2 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test3 +; IS__CGSCC_OPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = add i32 [[TRUE1]], [[TRUE2]] +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test3 +; IS__CGSCC_NPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[CMP1:%.*]] = call i32 @iszero3(i32 noundef 0) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i32 @less_than_two(i32 [[CMP1]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = call i32 @iszero3(i32 noundef 1) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i32 @less_than_two(i32 [[CMP2]]) #[[ATTR2]] +; 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) @@ -139,10 +205,26 @@ define i32 @potential_test3() { ; int potential_test7(int c) { return return1or3(c) == return3or4(c); } define i32 @potential_test4(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@potential_test4 -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test4 +; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test4 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET]], 2 +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test4 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[CSRET:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET]], 2 +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %csret = call i32 @return1or3(i32 %c) %false = icmp eq i32 %csret, 2 @@ -151,10 +233,28 @@ define i32 @potential_test4(i32 %c) { } define i32 @potential_test5(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@potential_test5 -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test5 +; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test5 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test5 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return2or4(i32 [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[FALSE:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = zext i1 [[FALSE]] to i32 +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %csret1 = call i32 @return1or3(i32 %c) %csret2 = call i32 @return2or4(i32 %c) @@ -164,19 +264,33 @@ define i32 @potential_test5(i32 %c) { } define i1 @potential_test6(i32 %c) { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@potential_test6 -; IS________OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; IS________OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2:[0-9]+]], !range [[RNG0:![0-9]+]] -; IS________OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 -; IS________OPM-NEXT: ret i1 [[RET]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test6 +; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2:[0-9]+]], !range [[RNG0:![0-9]+]] +; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 +; IS__TUNIT_OPM-NEXT: ret i1 [[RET]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@potential_test6 -; IS________NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; IS________NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] -; IS________NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 -; IS________NPM-NEXT: ret i1 [[RET]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test6 +; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]] +; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 +; IS__TUNIT_NPM-NEXT: ret i1 [[RET]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test6 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], 3 +; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test6 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]] +; 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 @@ -184,21 +298,37 @@ define i1 @potential_test6(i32 %c) { } define i1 @potential_test7(i32 %c) { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@potential_test7 -; IS________OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; IS________OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]], !range [[RNG0]] -; IS________OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR2]], !range [[RNG1:![0-9]+]] -; IS________OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] -; IS________OPM-NEXT: ret i1 [[RET]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test7 +; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]], !range [[RNG0]] +; IS__TUNIT_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR2]], !range [[RNG1:![0-9]+]] +; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] +; IS__TUNIT_OPM-NEXT: ret i1 [[RET]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@potential_test7 -; IS________NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; IS________NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]], !range [[RNG0]] -; IS________NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR1]], !range [[RNG1:![0-9]+]] -; IS________NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] -; IS________NPM-NEXT: ret i1 [[RET]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test7 +; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR1]], !range [[RNG0]] +; IS__TUNIT_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR1]], !range [[RNG1:![0-9]+]] +; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] +; IS__TUNIT_NPM-NEXT: ret i1 [[RET]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test7 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = icmp eq i32 [[CSRET1]], [[CSRET2]] +; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test7 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @return1or3(i32 [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @return3or4(i32 [[C]]) #[[ATTR2]] +; 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) @@ -209,7 +339,7 @@ define i1 @potential_test7(i32 %c) { define internal i32 @return1or3(i32 %c) { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@return1or3 -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0 ; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 1, i32 3 ; CHECK-NEXT: ret i32 [[RET]] @@ -252,28 +382,56 @@ define internal i32 @return3or4(i32 %c) { 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: () #[[ATTR0]] { -; IS__CGSCC____-NEXT: ret i1 false +; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 4 +; IS__CGSCC____-NEXT: ret i1 [[CMP]] ; %cmp = icmp eq i32 %c, 4 ret i1 %cmp } define internal i1 @wrapper(i32 %c) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@wrapper -; IS__CGSCC____-SAME: () #[[ATTR0]] { -; IS__CGSCC____-NEXT: ret i1 false +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@wrapper +; IS__CGSCC_OPM-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i1 @cmp_with_four(i32 noundef [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@wrapper +; IS__CGSCC_NPM-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i1 @cmp_with_four(i32 noundef [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] ; %ret = call i1 @cmp_with_four(i32 %c) ret i1 %ret } define i1 @potential_test8() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@potential_test8 -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: ret i1 false +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test8 +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i1 false +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test8 +; IS__CGSCC_OPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[RES1:%.*]] = call i1 @wrapper(i32 noundef 1) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[RES3:%.*]] = call i1 @wrapper(i32 noundef 3) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[RES5:%.*]] = call i1 @wrapper(i32 noundef 5) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[RES13:%.*]] = or i1 [[RES1]], [[RES3]] +; IS__CGSCC_OPM-NEXT: [[RES135:%.*]] = or i1 [[RES13]], [[RES5]] +; IS__CGSCC_OPM-NEXT: ret i1 [[RES135]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test8 +; IS__CGSCC_NPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[RES1:%.*]] = call i1 @wrapper(i32 noundef 1) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[RES3:%.*]] = call i1 @wrapper(i32 noundef 3) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[RES5:%.*]] = call i1 @wrapper(i32 noundef 5) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[RES13:%.*]] = or i1 [[RES1]], [[RES3]] +; IS__CGSCC_NPM-NEXT: [[RES135:%.*]] = or i1 [[RES13]], [[RES5]] +; IS__CGSCC_NPM-NEXT: ret i1 [[RES135]] ; %res1 = call i1 @wrapper(i32 1) %res3 = call i1 @wrapper(i32 3) @@ -284,24 +442,24 @@ define i1 @potential_test8() { } define i1 @potential_test9() { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone -; IS________OPM-LABEL: define {{[^@]+}}@potential_test9 -; IS________OPM-SAME: () #[[ATTR1:[0-9]+]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: br label [[COND:%.*]] -; IS________OPM: cond: -; IS________OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ] -; IS________OPM-NEXT: [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ] -; IS________OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 10 -; IS________OPM-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] -; IS________OPM: body: -; IS________OPM-NEXT: [[C_1]] = mul i32 [[C_0]], -1 -; IS________OPM-NEXT: br label [[INC]] -; IS________OPM: inc: -; IS________OPM-NEXT: [[I_1]] = add i32 [[I_0]], 1 -; IS________OPM-NEXT: br label [[COND]] -; IS________OPM: end: -; IS________OPM-NEXT: ret i1 false +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test9 +; IS__TUNIT_OPM-SAME: () #[[ATTR1:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: br label [[COND:%.*]] +; IS__TUNIT_OPM: cond: +; IS__TUNIT_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ] +; IS__TUNIT_OPM-NEXT: [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ] +; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 10 +; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] +; IS__TUNIT_OPM: body: +; IS__TUNIT_OPM-NEXT: [[C_1]] = mul i32 [[C_0]], -1 +; IS__TUNIT_OPM-NEXT: br label [[INC]] +; IS__TUNIT_OPM: inc: +; IS__TUNIT_OPM-NEXT: [[I_1]] = add i32 [[I_0]], 1 +; IS__TUNIT_OPM-NEXT: br label [[COND]] +; IS__TUNIT_OPM: end: +; IS__TUNIT_OPM-NEXT: ret i1 false ; ; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS________NPM-LABEL: define {{[^@]+}}@potential_test9 @@ -322,6 +480,25 @@ define i1 @potential_test9() { ; IS________NPM: end: ; IS________NPM-NEXT: ret i1 false ; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test9 +; IS__CGSCC_OPM-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: br label [[COND:%.*]] +; IS__CGSCC_OPM: cond: +; IS__CGSCC_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_1:%.*]], [[INC:%.*]] ] +; IS__CGSCC_OPM-NEXT: [[C_0:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[C_1:%.*]], [[INC]] ] +; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 10 +; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[BODY:%.*]], label [[END:%.*]] +; IS__CGSCC_OPM: body: +; IS__CGSCC_OPM-NEXT: [[C_1]] = mul i32 [[C_0]], -1 +; IS__CGSCC_OPM-NEXT: br label [[INC]] +; IS__CGSCC_OPM: inc: +; IS__CGSCC_OPM-NEXT: [[I_1]] = add i32 [[I_0]], 1 +; IS__CGSCC_OPM-NEXT: br label [[COND]] +; IS__CGSCC_OPM: end: +; IS__CGSCC_OPM-NEXT: ret i1 false +; entry: br label %cond cond: @@ -370,10 +547,24 @@ otherwise: } define i1 @potential_test10(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@potential_test10 -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: ret i1 false +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test10 +; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i1 false +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test10 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RET]], 0 +; IS__CGSCC_OPM-NEXT: ret i1 [[CMP]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test10 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @may_return_undef(i32 [[C]]) #[[ATTR2]] +; 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 @@ -438,25 +629,45 @@ f: ; FIXME: returned value can be simplified to 0 define i32 @potential_test11(i1 %c) { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@potential_test11 -; IS________OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; IS________OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR2]], !range [[RNG2:![0-9]+]] -; IS________OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR2]], !range [[RNG3:![0-9]+]] -; IS________OPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR2]], !range [[RNG2]] -; IS________OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] -; IS________OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] -; IS________OPM-NEXT: ret i32 [[ACC2]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test11 +; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR2]], !range [[RNG2:![0-9]+]] +; IS__TUNIT_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR2]], !range [[RNG3:![0-9]+]] +; IS__TUNIT_OPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR2]], !range [[RNG2]] +; IS__TUNIT_OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] +; IS__TUNIT_OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] +; IS__TUNIT_OPM-NEXT: ret i32 [[ACC2]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@potential_test11 -; IS________NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; IS________NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR1]], !range [[RNG2:![0-9]+]] -; IS________NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR1]], !range [[RNG3:![0-9]+]] -; IS________NPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR1]], !range [[RNG2]] -; IS________NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] -; IS________NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] -; IS________NPM-NEXT: ret i32 [[ACC2]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test11 +; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR1]], !range [[RNG2:![0-9]+]] +; IS__TUNIT_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR1]], !range [[RNG3:![0-9]+]] +; IS__TUNIT_NPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT_NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] +; IS__TUNIT_NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] +; IS__TUNIT_NPM-NEXT: ret i32 [[ACC2]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test11 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] +; IS__CGSCC_OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] +; IS__CGSCC_OPM-NEXT: ret i32 [[ACC2]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test11 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]] +; IS__CGSCC_NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]] +; IS__CGSCC_NPM-NEXT: ret i32 [[ACC2]] ; %zero1 = call i32 @optimize_undef_1(i1 %c) %zero2 = call i32 @optimize_undef_2(i1 %c) @@ -495,16 +706,28 @@ f: ; FIXME: returned value can be simplified to 0 define i32 @potential_test12(i1 %c) { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@potential_test12 -; IS________OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; IS________OPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]], !range [[RNG3]] -; IS________OPM-NEXT: ret i32 [[ZERO]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test12 +; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT_OPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]], !range [[RNG3]] +; IS__TUNIT_OPM-NEXT: ret i32 [[ZERO]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@potential_test12 -; IS________NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; IS________NPM-NEXT: ret i32 0 +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test12 +; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT_NPM-NEXT: ret i32 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test12 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: ret i32 [[ZERO]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test12 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[ZERO]] ; %zero = call i32 @optimize_poison_1(i1 %c) ret i32 %zero @@ -527,51 +750,87 @@ define internal i32 @potential_test13_callee(i32 %c) { } define i32 @potential_test13_caller1() { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 -; IS________OPM-SAME: () #[[ATTR0]] { -; IS________OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]], !range [[RNG2]] -; IS________OPM-NEXT: ret i32 [[RET]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 +; IS__TUNIT_OPM-SAME: () #[[ATTR0]] { +; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]], !range [[RNG2]] +; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 -; IS________NPM-SAME: () #[[ATTR0]] { -; IS________NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR1]], !range [[RNG2]] -; IS________NPM-NEXT: ret i32 [[RET]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 +; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { +; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller1 +; IS__CGSCC_OPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller1 +; IS__CGSCC_NPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = call i32 @potential_test13_callee(i32 0) ret i32 %ret } define i32 @potential_test13_caller2() { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 -; IS________OPM-SAME: () #[[ATTR0]] { -; IS________OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]], !range [[RNG2]] -; IS________OPM-NEXT: ret i32 [[RET]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 +; IS__TUNIT_OPM-SAME: () #[[ATTR0]] { +; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]], !range [[RNG2]] +; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 -; IS________NPM-SAME: () #[[ATTR0]] { -; IS________NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR1]], !range [[RNG2]] -; IS________NPM-NEXT: ret i32 [[RET]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 +; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { +; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller2 +; IS__CGSCC_OPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller2 +; IS__CGSCC_NPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 1) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = call i32 @potential_test13_callee(i32 1) ret i32 %ret } define i32 @potential_test13_caller3() { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@potential_test13_caller3 -; IS________OPM-SAME: () #[[ATTR0]] { -; IS________OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR2]], !range [[RNG2]] -; IS________OPM-NEXT: ret i32 [[RET]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3 +; IS__TUNIT_OPM-SAME: () #[[ATTR0]] { +; IS__TUNIT_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR2]], !range [[RNG2]] +; IS__TUNIT_OPM-NEXT: ret i32 [[RET]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@potential_test13_caller3 -; IS________NPM-SAME: () #[[ATTR0]] { -; IS________NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR1]], !range [[RNG2]] -; IS________NPM-NEXT: ret i32 [[RET]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3 +; IS__TUNIT_NPM-SAME: () #[[ATTR0]] { +; IS__TUNIT_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR1]], !range [[RNG2]] +; IS__TUNIT_NPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test13_caller3 +; IS__CGSCC_OPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR3]] +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@potential_test13_caller3 +; IS__CGSCC_NPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 undef) #[[ATTR2]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = call i32 @potential_test13_callee(i32 undef) ret i32 %ret @@ -629,14 +888,16 @@ define i1 @potential_test16(i1 %c0, i1 %c1) { ; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR2]] = { readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } +; IS__CGSCC_OPM: attributes #[[ATTR3]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR1]] = { readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR2]] = { readnone willreturn } ;. -; CHECK: [[META0:![0-9]+]] = !{i32 1, i32 4} -; CHECK: [[META1:![0-9]+]] = !{i32 3, i32 5} -; CHECK: [[META2:![0-9]+]] = !{i32 0, i32 2} -; CHECK: [[META3:![0-9]+]] = !{i32 -1, i32 1} +; IS__TUNIT____: [[META0:![0-9]+]] = !{i32 1, i32 4} +; IS__TUNIT____: [[META1:![0-9]+]] = !{i32 3, i32 5} +; IS__TUNIT____: [[META2:![0-9]+]] = !{i32 0, i32 2} +; IS__TUNIT____: [[META3:![0-9]+]] = !{i32 -1, i32 1} ;. diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll index 49d9da1ed9c7..dc62d80c1f6e 100644 --- a/llvm/test/Transforms/Attributor/range.ll +++ b/llvm/test/Transforms/Attributor/range.ll @@ -24,10 +24,10 @@ define i32 @test0-range-check(i32* %p) { ; IS__TUNIT____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #[[ATTR3:[0-9]+]], !range [[RNG0]] ; IS__TUNIT____-NEXT: ret i32 [[A]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-range-check -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] { -; IS__CGSCC____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR3:[0-9]+]], !range [[RNG0]] +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 [[A]] ; %a = tail call i32 @test0(i32* %p) @@ -97,49 +97,69 @@ define void @test0-icmp-check(i32* %p){ ; ; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-icmp-check ; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) { -; IS__CGSCC____-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR3]], !range [[RNG0]] +; IS__CGSCC____-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5]] +; 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: tail call void @use3(i1 noundef false, i1 [[CMP_EQ_2]], i1 [[CMP_EQ_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]], i1 noundef false) +; 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: tail call void @use3(i1 noundef true, i1 [[CMP_NE_2]], i1 [[CMP_NE_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]], i1 noundef true) +; 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 noundef false, i1 noundef false, i1 [[CMP_UGT_3]]) +; 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 noundef 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: tail call void @use3(i1 noundef false, i1 [[CMP_UGE_2]], i1 [[CMP_UGE_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 noundef true, i1 noundef false) +; 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 noundef 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: tail call void @use3(i1 noundef false, i1 noundef false, i1 [[CMP_SGT_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1 [[CMP_SGT_5]], i1 noundef true) +; 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: tail call void @use3(i1 noundef false, i1 [[CMP_GTE_2]], i1 [[CMP_GTE_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 noundef true, i1 noundef true) +; 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: tail call void @use3(i1 noundef true, i1 [[CMP_SLT_2]], i1 [[CMP_SLT_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 noundef false, i1 noundef false) +; 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: tail call void @use3(i1 noundef true, i1 noundef true, i1 [[CMP_LTE_3]]) -; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1 [[CMP_LTE_5]], i1 noundef false) +; 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 ; %ret = tail call i32 @test0(i32 *%p) @@ -250,10 +270,10 @@ define i1 @test1-check(i32* %p) { ; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 ; IS__TUNIT____-NEXT: ret i1 [[CMP]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test1-check -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0]] { -; IS__CGSCC____-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR3]], !range [[RNG2:![0-9]+]] +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5]] ; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 ; IS__CGSCC____-NEXT: ret i1 [[CMP]] ; @@ -304,17 +324,20 @@ define i32 @test2_check(i32* %p) { ; IS__TUNIT____: return: ; IS__TUNIT____-NEXT: ret i32 2 ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_check -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR1]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: br label [[IF_THEN:%.*]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = tail call i32 @test2(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5 +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; IS__CGSCC____: if.then: ; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] ; IS__CGSCC____: if.end: -; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: return: -; IS__CGSCC____-NEXT: ret i32 2 +; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [ 3, [[IF_END]] ] +; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]] ; entry: %call = tail call i32 @test2(i32* %p) @@ -381,7 +404,7 @@ define internal i32 @r1(i32) local_unnamed_addr { ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@r1 -; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR1]] { +; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR2:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: br label [[TMP3:%.*]] ; IS__CGSCC_NPM: 1: ; IS__CGSCC_NPM-NEXT: br label [[F:%.*]] @@ -427,25 +450,25 @@ define void @f1(i32){ ; IS__TUNIT_OPM: 5: ; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@f1 -; IS________NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { -; IS________NPM-NEXT: br label [[TMP3:%.*]] -; IS________NPM: 2: -; IS________NPM-NEXT: unreachable -; IS________NPM: 3: -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f1 +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { +; IS__TUNIT_NPM-NEXT: br label [[TMP3:%.*]] +; IS__TUNIT_NPM: 2: +; IS__TUNIT_NPM-NEXT: unreachable +; 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() #[[ATTR4:[0-9]+]], !range [[RNG3:![0-9]+]] -; 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____-LABEL: define {{[^@]+}}@f1 +; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) { +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR6:[0-9]+]] +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15 +; IS__CGSCC____-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] +; IS__CGSCC____: 4: +; IS__CGSCC____-NEXT: tail call void @unkown() +; IS__CGSCC____-NEXT: br label [[TMP5]] +; IS__CGSCC____: 5: +; IS__CGSCC____-NEXT: ret void ; %2 = tail call i32 @r1(i32 %0) %3 = icmp sgt i32 %2, 15 @@ -470,17 +493,41 @@ define void @f1(i32){ ; } ; } define dso_local i32 @test4-f1(i32 %u) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@test4-f1 -; CHECK-SAME: (i32 [[U:%.*]]) #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 -; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] -; CHECK: if.then: -; CHECK-NEXT: br label [[RETURN]] -; CHECK: return: -; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ] -; CHECK-NEXT: ret i32 [[RETVAL_0]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test4-f1 +; IS__TUNIT____-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] +; IS__TUNIT____: if.then: +; IS__TUNIT____-NEXT: br label [[RETURN]] +; IS__TUNIT____: return: +; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ] +; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]] +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-f1 +; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 +; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] +; IS__CGSCC_OPM: if.then: +; IS__CGSCC_OPM-NEXT: br label [[RETURN]] +; IS__CGSCC_OPM: return: +; IS__CGSCC_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ] +; IS__CGSCC_OPM-NEXT: ret i32 [[RETVAL_0]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4-f1 +; IS__CGSCC_NPM-SAME: (i32 [[U:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 +; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] +; IS__CGSCC_NPM: if.then: +; IS__CGSCC_NPM-NEXT: br label [[RETURN]] +; IS__CGSCC_NPM: return: +; IS__CGSCC_NPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ] +; IS__CGSCC_NPM-NEXT: ret i32 [[RETVAL_0]] ; ; FIXME: RETVAL_0 >= 0 entry: @@ -497,19 +544,33 @@ return: ; preds = %entry, %if.then define dso_local i32 @test4-g1(i32 %u) { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@test4-g1 -; IS________OPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR5:[0-9]+]] -; IS________OPM-NEXT: ret i32 [[CALL]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test4-g1 +; IS__TUNIT_OPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR5:[0-9]+]] +; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@test4-g1 -; IS________NPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR4:[0-9]+]] -; IS________NPM-NEXT: ret i32 [[CALL]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test4-g1 +; IS__TUNIT_NPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR4:[0-9]+]] +; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g1 +; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR7:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4-g1 +; IS__CGSCC_NPM-SAME: (i32 [[U:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; ; FIXME: %call should have range [0, inf] @@ -527,20 +588,50 @@ entry: ; } ; } define dso_local i32 @test4-f2(i32 %u) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@test4-f2 -; CHECK-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 -; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] -; CHECK: if.then: -; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1 -; CHECK-NEXT: br label [[RETURN:%.*]] -; CHECK: if.else: -; CHECK-NEXT: br label [[RETURN]] -; CHECK: return: -; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ] -; CHECK-NEXT: ret i32 [[RETVAL_0]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test4-f2 +; IS__TUNIT____-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; IS__TUNIT____: if.then: +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1 +; IS__TUNIT____-NEXT: br label [[RETURN:%.*]] +; IS__TUNIT____: if.else: +; IS__TUNIT____-NEXT: br label [[RETURN]] +; IS__TUNIT____: return: +; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ] +; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]] +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-f2 +; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 +; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; IS__CGSCC_OPM: if.then: +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1 +; IS__CGSCC_OPM-NEXT: br label [[RETURN:%.*]] +; IS__CGSCC_OPM: if.else: +; IS__CGSCC_OPM-NEXT: br label [[RETURN]] +; IS__CGSCC_OPM: return: +; IS__CGSCC_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ] +; IS__CGSCC_OPM-NEXT: ret i32 [[RETVAL_0]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4-f2 +; IS__CGSCC_NPM-SAME: (i32 [[U:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1 +; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; IS__CGSCC_NPM: if.then: +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1 +; IS__CGSCC_NPM-NEXT: br label [[RETURN:%.*]] +; IS__CGSCC_NPM: if.else: +; IS__CGSCC_NPM-NEXT: br label [[RETURN]] +; IS__CGSCC_NPM: return: +; IS__CGSCC_NPM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ] +; IS__CGSCC_NPM-NEXT: ret i32 [[RETVAL_0]] ; entry: %cmp = icmp sgt i32 %u, -1 @@ -560,19 +651,33 @@ return: ; preds = %if.else, %if.then define dso_local i32 @test4-g2(i32 %u) { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@test4-g2 -; IS________OPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR5]] -; IS________OPM-NEXT: ret i32 [[CALL]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test4-g2 +; IS__TUNIT_OPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR5]] +; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@test4-g2 -; IS________NPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR4]], !range [[RNG3:![0-9]+]] -; IS________NPM-NEXT: ret i32 [[CALL]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test4-g2 +; IS__TUNIT_NPM-SAME: (i32 [[U:%.*]]) #[[ATTR1]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR4]], !range [[RNG3:![0-9]+]] +; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g2 +; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4-g2 +; IS__CGSCC_NPM-SAME: (i32 [[U:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; entry: %call = tail call i32 @test4-f2(i32 %u) @@ -585,10 +690,15 @@ define dso_local i32 @test-5() { ; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0), !range [[RNG3:![0-9]+]] ; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]] ; -; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test-5() { -; NOT_TUNIT_OPM-NEXT: entry: -; NOT_TUNIT_OPM-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0), !range [[RNG4:![0-9]+]] -; NOT_TUNIT_OPM-NEXT: ret i32 [[CALL]] +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test-5() { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0), !range [[RNG4:![0-9]+]] +; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test-5() { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call noundef i32 @rec(i32 noundef 0) +; IS__CGSCC____-NEXT: ret i32 [[CALL]] ; entry: %call = call i32 @rec(i32 0) @@ -651,31 +761,83 @@ declare dso_local i32 @foo(i32) ; FIXME: All but the return is not needed anymore define dso_local zeroext i1 @phi(i32 %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@phi -; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: bb: -; CHECK-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5 -; CHECK-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]] -; CHECK: bb1: -; CHECK-NEXT: br label [[BB3:%.*]] -; CHECK: bb2: -; CHECK-NEXT: br label [[BB3]] -; CHECK: bb3: -; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10 -; CHECK-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]] -; CHECK: bb5: -; CHECK-NEXT: br label [[BB9:%.*]] -; CHECK: bb7: -; CHECK-NEXT: br label [[BB9]] -; CHECK: bb9: -; CHECK-NEXT: br label [[BB12:%.*]] -; CHECK: bb11: -; CHECK-NEXT: unreachable -; CHECK: bb12: -; CHECK-NEXT: br label [[BB13:%.*]] -; CHECK: bb13: -; CHECK-NEXT: ret i1 false +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@phi +; IS__TUNIT____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: bb: +; IS__TUNIT____-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5 +; IS__TUNIT____-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]] +; IS__TUNIT____: bb1: +; IS__TUNIT____-NEXT: br label [[BB3:%.*]] +; IS__TUNIT____: bb2: +; IS__TUNIT____-NEXT: br label [[BB3]] +; IS__TUNIT____: bb3: +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10 +; IS__TUNIT____-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]] +; IS__TUNIT____: bb5: +; IS__TUNIT____-NEXT: br label [[BB9:%.*]] +; IS__TUNIT____: bb7: +; IS__TUNIT____-NEXT: br label [[BB9]] +; IS__TUNIT____: bb9: +; IS__TUNIT____-NEXT: br label [[BB12:%.*]] +; IS__TUNIT____: bb11: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: bb12: +; IS__TUNIT____-NEXT: br label [[BB13:%.*]] +; IS__TUNIT____: bb13: +; IS__TUNIT____-NEXT: ret i1 false +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@phi +; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: bb: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5 +; IS__CGSCC_OPM-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]] +; IS__CGSCC_OPM: bb1: +; IS__CGSCC_OPM-NEXT: br label [[BB3:%.*]] +; IS__CGSCC_OPM: bb2: +; IS__CGSCC_OPM-NEXT: br label [[BB3]] +; IS__CGSCC_OPM: bb3: +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10 +; IS__CGSCC_OPM-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]] +; IS__CGSCC_OPM: bb5: +; IS__CGSCC_OPM-NEXT: br label [[BB9:%.*]] +; IS__CGSCC_OPM: bb7: +; IS__CGSCC_OPM-NEXT: br label [[BB9]] +; IS__CGSCC_OPM: bb9: +; IS__CGSCC_OPM-NEXT: br label [[BB12:%.*]] +; IS__CGSCC_OPM: bb11: +; IS__CGSCC_OPM-NEXT: unreachable +; IS__CGSCC_OPM: bb12: +; IS__CGSCC_OPM-NEXT: br label [[BB13:%.*]] +; IS__CGSCC_OPM: bb13: +; IS__CGSCC_OPM-NEXT: ret i1 false +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@phi +; IS__CGSCC_NPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: bb: +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5 +; IS__CGSCC_NPM-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]] +; IS__CGSCC_NPM: bb1: +; IS__CGSCC_NPM-NEXT: br label [[BB3:%.*]] +; IS__CGSCC_NPM: bb2: +; IS__CGSCC_NPM-NEXT: br label [[BB3]] +; IS__CGSCC_NPM: bb3: +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10 +; IS__CGSCC_NPM-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]] +; IS__CGSCC_NPM: bb5: +; IS__CGSCC_NPM-NEXT: br label [[BB9:%.*]] +; IS__CGSCC_NPM: bb7: +; IS__CGSCC_NPM-NEXT: br label [[BB9]] +; IS__CGSCC_NPM: bb9: +; IS__CGSCC_NPM-NEXT: br label [[BB12:%.*]] +; IS__CGSCC_NPM: bb11: +; IS__CGSCC_NPM-NEXT: unreachable +; IS__CGSCC_NPM: bb12: +; IS__CGSCC_NPM-NEXT: br label [[BB13:%.*]] +; IS__CGSCC_NPM: bb13: +; IS__CGSCC_NPM-NEXT: ret i1 false ; bb: %tmp = icmp sgt i32 %arg, 5 @@ -717,11 +879,23 @@ bb13: ; preds = %bb12, %bb11 } define dso_local i1 @select(i32 %a) local_unnamed_addr #0 { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@select -; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i1 false +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@select +; IS__TUNIT____-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i1 false +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@select +; IS__CGSCC_OPM-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: ret i1 false +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@select +; IS__CGSCC_NPM-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: ret i1 false ; entry: %cmp = icmp sgt i32 %a, 5 @@ -734,11 +908,23 @@ entry: } define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@select_zext -; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@select_zext +; IS__TUNIT____-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@select_zext +; IS__CGSCC_OPM-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: ret i32 0 +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@select_zext +; IS__CGSCC_NPM-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: ret i32 0 ; entry: %cmp = icmp sgt i32 %a, 5 @@ -752,11 +938,23 @@ entry: } define dso_local i64 @select_int2ptr_bitcast_ptr2int(i32 %a) local_unnamed_addr #0 { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int -; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i64 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int +; IS__TUNIT____-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i64 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int +; IS__CGSCC_OPM-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: ret i64 0 +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int +; IS__CGSCC_NPM-SAME: (i32 [[A:%.*]]) local_unnamed_addr #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: ret i64 0 ; entry: %cmp = icmp sgt i32 %a, 5 @@ -774,77 +972,157 @@ entry: ; } define i1 @f_fcmp(float %a, float %b) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@f_fcmp -; CHECK-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]] -; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false -; CHECK-NEXT: ret i1 [[S]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@f_fcmp +; IS__TUNIT____-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]] +; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__TUNIT____-NEXT: ret i1 [[S]] +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f_fcmp +; IS__CGSCC_OPM-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]] +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__CGSCC_OPM-NEXT: ret i1 [[S]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f_fcmp +; IS__CGSCC_NPM-SAME: (float [[A:%.*]], float [[B:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]] +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__CGSCC_NPM-NEXT: ret i1 [[S]] ; %r = fcmp uge float %a, %b %s = select i1 %r, i1 %r, i1 0 ret i1 %s } define i1 @d_fcmp(double %a, double %b) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@d_fcmp -; CHECK-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]] -; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false -; CHECK-NEXT: ret i1 [[S]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@d_fcmp +; IS__TUNIT____-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]] +; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__TUNIT____-NEXT: ret i1 [[S]] +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@d_fcmp +; IS__CGSCC_OPM-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]] +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__CGSCC_OPM-NEXT: ret i1 [[S]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@d_fcmp +; IS__CGSCC_NPM-SAME: (double [[A:%.*]], double [[B:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]] +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__CGSCC_NPM-NEXT: ret i1 [[S]] ; %r = fcmp oeq double %a, %b %s = select i1 %r, i1 %r, i1 0 ret i1 %s } define i1 @dp_icmp(double* %a, double* %b) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@dp_icmp -; CHECK-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]] -; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false -; CHECK-NEXT: ret i1 [[S]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@dp_icmp +; IS__TUNIT____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]] +; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__TUNIT____-NEXT: ret i1 [[S]] +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@dp_icmp +; IS__CGSCC_OPM-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]] +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__CGSCC_OPM-NEXT: ret i1 [[S]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@dp_icmp +; IS__CGSCC_NPM-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]] +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__CGSCC_NPM-NEXT: ret i1 [[S]] ; %r = icmp sge double* %a, %b %s = select i1 %r, i1 %r, i1 0 ret i1 %s } define i1 @ip_icmp(i8* %a, i8* %b) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@ip_icmp -; CHECK-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]] -; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false -; CHECK-NEXT: ret i1 [[S]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ip_icmp +; IS__TUNIT____-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]] +; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__TUNIT____-NEXT: ret i1 [[S]] +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ip_icmp +; IS__CGSCC_OPM-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]] +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__CGSCC_OPM-NEXT: ret i1 [[S]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ip_icmp +; IS__CGSCC_NPM-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]] +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false +; IS__CGSCC_NPM-NEXT: ret i1 [[S]] ; %r = icmp ult i8* %a, %b %s = select i1 %r, i1 %r, i1 0 ret i1 %s } define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dpa, double* %dpb, i8* %ipa, i8* %ipb) { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@fcmp_caller -; IS________OPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR1]] { -; IS________OPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR5]] -; IS________OPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR5]] -; IS________OPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR5]] -; IS________OPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR5]] -; IS________OPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] -; IS________OPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] -; IS________OPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] -; IS________OPM-NEXT: ret i1 [[O3]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fcmp_caller +; IS__TUNIT_OPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR1]] { +; IS__TUNIT_OPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR5]] +; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR5]] +; IS__TUNIT_OPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR5]] +; IS__TUNIT_OPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR5]] +; IS__TUNIT_OPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] +; IS__TUNIT_OPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] +; IS__TUNIT_OPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] +; IS__TUNIT_OPM-NEXT: ret i1 [[O3]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@fcmp_caller -; IS________NPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR1]] { -; IS________NPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR4]] -; IS________NPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR4]] -; IS________NPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR4]] -; IS________NPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR4]] -; IS________NPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] -; IS________NPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] -; IS________NPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] -; IS________NPM-NEXT: ret i1 [[O3]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fcmp_caller +; IS__TUNIT_NPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR1]] { +; IS__TUNIT_NPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR4]] +; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR4]] +; IS__TUNIT_NPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR4]] +; IS__TUNIT_NPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR4]] +; IS__TUNIT_NPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] +; IS__TUNIT_NPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] +; IS__TUNIT_NPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] +; IS__TUNIT_NPM-NEXT: ret i1 [[O3]] +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fcmp_caller +; IS__CGSCC_OPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] +; IS__CGSCC_OPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] +; IS__CGSCC_OPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] +; IS__CGSCC_OPM-NEXT: ret i1 [[O3]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fcmp_caller +; IS__CGSCC_NPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] +; IS__CGSCC_NPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] +; IS__CGSCC_NPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] +; IS__CGSCC_NPM-NEXT: ret i1 [[O3]] ; %r1 = call i1 @f_fcmp(float %fa, float %fb) %r2 = call i1 @d_fcmp(double %da, double %db) @@ -857,28 +1135,62 @@ define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dp } define i8 @ret_two() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@ret_two -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 2 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_two +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 2 +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ret_two +; IS__CGSCC_OPM-SAME: () #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: ret i8 2 +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ret_two +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: ret i8 2 ; ret i8 2 } define i8 @ret_undef() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@ret_undef -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 undef +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_undef +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 undef +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ret_undef +; IS__CGSCC_OPM-SAME: () #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: ret i8 undef +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ret_undef +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: ret i8 undef ; ret i8 undef } ; Verify we collapse undef to a value and return something non-undef here. define i8 @undef_collapse_1() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@undef_collapse_1 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_1 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@undef_collapse_1 +; IS__CGSCC_OPM-SAME: () #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i8 @ret_undef() #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = shl i8 [[C]], 2 +; IS__CGSCC_OPM-NEXT: ret i8 [[S]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@undef_collapse_1 +; IS__CGSCC_NPM-SAME: () #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8 @ret_undef() #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = shl i8 [[C]], 2 +; IS__CGSCC_NPM-NEXT: ret i8 [[S]] ; %c = call i8 @ret_undef() %s = shl i8 %c, 2 @@ -887,10 +1199,24 @@ define i8 @undef_collapse_1() { ; Verify we collapse undef to a value and return something non-undef here. define i8 @undef_collapse_2() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@undef_collapse_2 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_2 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@undef_collapse_2 +; IS__CGSCC_OPM-SAME: () #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i8 @ret_two() #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = shl i8 undef, [[C]] +; IS__CGSCC_OPM-NEXT: ret i8 [[S]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@undef_collapse_2 +; IS__CGSCC_NPM-SAME: () #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8 @ret_two() #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = shl i8 undef, [[C]] +; IS__CGSCC_NPM-NEXT: ret i8 [[S]] ; %c = call i8 @ret_two() %s = shl i8 undef, %c @@ -899,10 +1225,26 @@ define i8 @undef_collapse_2() { define i8 @undef_collapse_caller() { ; -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@undef_collapse_caller -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_caller +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@undef_collapse_caller +; IS__CGSCC_OPM-SAME: () #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]] +; IS__CGSCC_OPM-NEXT: ret i8 [[A]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@undef_collapse_caller +; IS__CGSCC_NPM-SAME: () #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]] +; IS__CGSCC_NPM-NEXT: ret i8 [[A]] ; %c1 = call i8 @undef_collapse_1() %c2 = call i8 @undef_collapse_2() @@ -911,21 +1253,57 @@ define i8 @undef_collapse_caller() { } define i32 @ret1or2(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@ret1or2 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2 -; CHECK-NEXT: ret i32 [[S]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ret1or2 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2 +; IS__TUNIT____-NEXT: ret i32 [[S]] +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ret1or2 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2 +; IS__CGSCC_OPM-NEXT: ret i32 [[S]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ret1or2 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2 +; IS__CGSCC_NPM-NEXT: ret i32 [[S]] ; %s = select i1 %c, i32 1, i32 2 ret i32 %s } define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) { ; -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@callee_range_1 -; CHECK-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@callee_range_1 +; IS__TUNIT____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee_range_1 +; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]] +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]] +; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4 +; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 +; IS__CGSCC_OPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] +; IS__CGSCC_OPM-NEXT: ret i1 [[F]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callee_range_1 +; IS__CGSCC_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]] +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]] +; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4 +; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 +; IS__CGSCC_NPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]] +; IS__CGSCC_NPM-NEXT: ret i1 [[F]] ; %r1 = call i32 @ret1or2(i1 %c1) %r2 = call i32 @ret1or2(i1 %c2) @@ -948,23 +1326,36 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) { ; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 ; IS__TUNIT_OPM-NEXT: ret i1 [[I1]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@callee_range_2 -; IS________NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] { -; IS________NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]], !range [[RNG5:![0-9]+]] -; IS________NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]], !range [[RNG5]] -; IS________NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] -; IS________NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 -; IS________NPM-NEXT: ret i1 [[I1]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_range_2 +; IS__TUNIT_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] { +; IS__TUNIT_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]], !range [[RNG5:![0-9]+]] +; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]], !range [[RNG5]] +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] +; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 +; IS__TUNIT_NPM-NEXT: ret i1 [[I1]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee_range_2 -; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] { -; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR5]], !range [[RNG5:![0-9]+]] -; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR5]], !range [[RNG5]] +; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]] ; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 -; IS__CGSCC_OPM-NEXT: ret i1 [[I1]] +; 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 nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callee_range_2 +; IS__CGSCC_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR6]] +; 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) @@ -977,41 +1368,81 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) { define i32 @ret100() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@ret100 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i32 100 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ret100 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i32 100 +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ret100 +; IS__CGSCC_OPM-SAME: () #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: ret i32 100 +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ret100 +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: ret i32 100 ; ret i32 100 } define i1 @ctx_adjustment(i32 %V) { ; -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@ctx_adjustment -; IS________OPM-SAME: (i32 [[V:%.*]]) #[[ATTR1]] { -; IS________OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 -; IS________OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] -; IS________OPM: if.true: -; IS________OPM-NEXT: br label [[END:%.*]] -; IS________OPM: if.false: -; IS________OPM-NEXT: br label [[END]] -; IS________OPM: end: -; IS________OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ] -; IS________OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100 -; IS________OPM-NEXT: ret i1 [[C2]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@ctx_adjustment +; IS__TUNIT_OPM-SAME: (i32 [[V:%.*]]) #[[ATTR1]] { +; IS__TUNIT_OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 +; IS__TUNIT_OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__TUNIT_OPM: if.true: +; IS__TUNIT_OPM-NEXT: br label [[END:%.*]] +; IS__TUNIT_OPM: if.false: +; IS__TUNIT_OPM-NEXT: br label [[END]] +; IS__TUNIT_OPM: end: +; IS__TUNIT_OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ] +; IS__TUNIT_OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100 +; IS__TUNIT_OPM-NEXT: ret i1 [[C2]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@ctx_adjustment -; IS________NPM-SAME: (i32 [[V:%.*]]) #[[ATTR1]] { -; IS________NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 -; IS________NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] -; IS________NPM: if.true: -; IS________NPM-NEXT: br label [[END:%.*]] -; IS________NPM: if.false: -; IS________NPM-NEXT: br label [[END]] -; IS________NPM: end: -; IS________NPM-NEXT: ret i1 true +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@ctx_adjustment +; IS__TUNIT_NPM-SAME: (i32 [[V:%.*]]) #[[ATTR1]] { +; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 +; IS__TUNIT_NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__TUNIT_NPM: if.true: +; IS__TUNIT_NPM-NEXT: br label [[END:%.*]] +; IS__TUNIT_NPM: if.false: +; IS__TUNIT_NPM-NEXT: br label [[END]] +; IS__TUNIT_NPM: end: +; IS__TUNIT_NPM-NEXT: ret i1 true +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ctx_adjustment +; IS__CGSCC_OPM-SAME: (i32 [[V:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 +; IS__CGSCC_OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__CGSCC_OPM: if.true: +; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] +; IS__CGSCC_OPM: if.false: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @ret100() #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: br label [[END]] +; IS__CGSCC_OPM: end: +; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ [[CALL]], [[IF_FALSE]] ] +; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100 +; IS__CGSCC_OPM-NEXT: ret i1 [[C2]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ctx_adjustment +; IS__CGSCC_NPM-SAME: (i32 [[V:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100 +; IS__CGSCC_NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__CGSCC_NPM: if.true: +; IS__CGSCC_NPM-NEXT: br label [[END:%.*]] +; IS__CGSCC_NPM: if.false: +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @ret100() #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: br label [[END]] +; IS__CGSCC_NPM: end: +; IS__CGSCC_NPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ [[CALL]], [[IF_FALSE]] ] +; IS__CGSCC_NPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100 +; IS__CGSCC_NPM-NEXT: ret i1 [[C2]] ; %c1 = icmp sge i32 %V, 100 br i1 %c1, label %if.true, label %if.false @@ -1028,11 +1459,23 @@ end: define i32 @func(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@func -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1 -; CHECK-NEXT: ret i32 [[RET]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@func +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1 +; IS__TUNIT____-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@func +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1 +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@func +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1 +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = select i1 %c, i32 0, i32 1 ret i32 %ret @@ -1051,29 +1494,41 @@ define i32 @simplify_callsite_argument(i1 %d) { ; IS__TUNIT_OPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR5]], !range [[RNG3]] ; IS__TUNIT_OPM-NEXT: ret i32 [[RET2]] ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@simplify_callsite_argument -; IS________NPM-SAME: (i1 [[D:%.*]]) #[[ATTR1]] { -; IS________NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false -; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS________NPM: t: -; IS________NPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef true) #[[ATTR4]], !range [[RNG4]] -; IS________NPM-NEXT: ret i32 [[RET1]] -; IS________NPM: f: -; IS________NPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR4]], !range [[RNG4]] -; IS________NPM-NEXT: ret i32 [[RET2]] +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@simplify_callsite_argument +; IS__TUNIT_NPM-SAME: (i1 [[D:%.*]]) #[[ATTR1]] { +; 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 noundef i32 @func(i1 noundef true) #[[ATTR4]], !range [[RNG4]] +; IS__TUNIT_NPM-NEXT: ret i32 [[RET1]] +; IS__TUNIT_NPM: f: +; IS__TUNIT_NPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR4]], !range [[RNG4]] +; IS__TUNIT_NPM-NEXT: ret i32 [[RET2]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@simplify_callsite_argument -; IS__CGSCC_OPM-SAME: (i1 [[D:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-SAME: (i1 [[D:%.*]]) #[[ATTR4]] { ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_OPM: t: -; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR5]], !range [[RNG4]] +; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR7]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET1]] ; IS__CGSCC_OPM: f: -; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR5]], !range [[RNG4]] +; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR7]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@simplify_callsite_argument +; IS__CGSCC_NPM-SAME: (i1 [[D:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_NPM: t: +; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef true) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RET1]] +; IS__CGSCC_NPM: f: +; IS__CGSCC_NPM-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RET2]] ; %c = select i1 %d, i1 true, i1 false br i1 %c, label %t, label %f @@ -1087,32 +1542,64 @@ f: define internal i32 @less_than_65536(i32 %arg) { ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_65536 -; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: [[SHRINKED:%.*]] = udiv i32 [[ARG]], 65536 -; IS__CGSCC____-NEXT: ret i32 [[SHRINKED]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@less_than_65536 +; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[SHRINKED:%.*]] = udiv i32 [[ARG]], 65536 +; IS__CGSCC_OPM-NEXT: ret i32 [[SHRINKED]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@less_than_65536 +; IS__CGSCC_NPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[SHRINKED:%.*]] = udiv i32 [[ARG]], 65536 +; IS__CGSCC_NPM-NEXT: ret i32 [[SHRINKED]] ; %shrinked = udiv i32 %arg, 65536 ret i32 %shrinked } define internal i1 @is_less_than_65536(i32 %arg) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_65536 -; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp ult i32 [[ARG]], 65536 -; 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_65536 +; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp ult i32 [[ARG]], 65536 +; 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_65536 +; IS__CGSCC_NPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp ult i32 [[ARG]], 65536 +; IS__CGSCC_NPM-NEXT: ret i1 [[CMP]] ; %cmp = icmp ult i32 %arg, 65536 ret i1 %cmp } define i1 @check_divided_range(i32 %arg) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@check_divided_range -; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@check_divided_range +; IS__TUNIT____-SAME: (i32 [[ARG:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@check_divided_range +; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]] +; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@check_divided_range +; IS__CGSCC_NPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR6]] +; 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) @@ -1124,32 +1611,62 @@ define i1 @check_divided_range(i32 %arg) { define internal i32 @cast_and_return(i1 %c) { ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@cast_and_return -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[C]] to i32 -; IS__CGSCC____-NEXT: ret i32 [[RET]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@cast_and_return +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = zext i1 [[C]] to i32 +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@cast_and_return +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = zext i1 [[C]] to i32 +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = zext i1 %c to i32 ret i32 %ret } define internal i1 @is_less_than_3(i32 %c) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_3 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 3 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@is_less_than_3 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 3 +; 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_3 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 3 +; IS__CGSCC_NPM-NEXT: ret i1 [[CMP]] ; %cmp = icmp slt i32 %c, 3 ret i1 %cmp } define i1 @check_casted_range(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@check_casted_range -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@check_casted_range +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@check_casted_range +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]] +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@check_casted_range +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]] +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: ret i1 [[RET]] ; %csret1 = call i32 @cast_and_return(i1 true) %csret2 = call i32 @cast_and_return(i1 %c) @@ -1159,34 +1676,63 @@ define i1 @check_casted_range(i1 %c) { } define internal i32 @less_than_100_1(i32 %c) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_100_1 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ -; IS__CGSCC____-NEXT: i32 0, label [[ONZERO:%.*]] -; IS__CGSCC____-NEXT: i32 1, label [[ONONE:%.*]] -; IS__CGSCC____-NEXT: i32 2, label [[ONTWO:%.*]] -; IS__CGSCC____-NEXT: i32 3, label [[ONTHREE:%.*]] -; IS__CGSCC____-NEXT: i32 4, label [[ONFOUR:%.*]] -; IS__CGSCC____-NEXT: i32 5, label [[ONFIVE:%.*]] -; IS__CGSCC____-NEXT: i32 6, label [[ONSIX:%.*]] -; IS__CGSCC____-NEXT: ] -; IS__CGSCC____: onzero: -; IS__CGSCC____-NEXT: ret i32 0 -; IS__CGSCC____: onone: -; IS__CGSCC____-NEXT: ret i32 1 -; IS__CGSCC____: ontwo: -; IS__CGSCC____-NEXT: ret i32 2 -; IS__CGSCC____: onthree: -; IS__CGSCC____-NEXT: ret i32 3 -; IS__CGSCC____: onfour: -; IS__CGSCC____-NEXT: ret i32 4 -; IS__CGSCC____: onfive: -; IS__CGSCC____-NEXT: ret i32 5 -; IS__CGSCC____: onsix: -; IS__CGSCC____-NEXT: ret i32 6 -; IS__CGSCC____: otherwise: -; IS__CGSCC____-NEXT: ret i32 99 +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@less_than_100_1 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ +; IS__CGSCC_OPM-NEXT: i32 0, label [[ONZERO:%.*]] +; IS__CGSCC_OPM-NEXT: i32 1, label [[ONONE:%.*]] +; IS__CGSCC_OPM-NEXT: i32 2, label [[ONTWO:%.*]] +; IS__CGSCC_OPM-NEXT: i32 3, label [[ONTHREE:%.*]] +; IS__CGSCC_OPM-NEXT: i32 4, label [[ONFOUR:%.*]] +; IS__CGSCC_OPM-NEXT: i32 5, label [[ONFIVE:%.*]] +; IS__CGSCC_OPM-NEXT: i32 6, label [[ONSIX:%.*]] +; IS__CGSCC_OPM-NEXT: ] +; IS__CGSCC_OPM: onzero: +; IS__CGSCC_OPM-NEXT: ret i32 0 +; IS__CGSCC_OPM: onone: +; IS__CGSCC_OPM-NEXT: ret i32 1 +; IS__CGSCC_OPM: ontwo: +; IS__CGSCC_OPM-NEXT: ret i32 2 +; IS__CGSCC_OPM: onthree: +; IS__CGSCC_OPM-NEXT: ret i32 3 +; IS__CGSCC_OPM: onfour: +; IS__CGSCC_OPM-NEXT: ret i32 4 +; IS__CGSCC_OPM: onfive: +; IS__CGSCC_OPM-NEXT: ret i32 5 +; IS__CGSCC_OPM: onsix: +; IS__CGSCC_OPM-NEXT: ret i32 6 +; IS__CGSCC_OPM: otherwise: +; IS__CGSCC_OPM-NEXT: ret i32 99 +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@less_than_100_1 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ +; IS__CGSCC_NPM-NEXT: i32 0, label [[ONZERO:%.*]] +; IS__CGSCC_NPM-NEXT: i32 1, label [[ONONE:%.*]] +; IS__CGSCC_NPM-NEXT: i32 2, label [[ONTWO:%.*]] +; IS__CGSCC_NPM-NEXT: i32 3, label [[ONTHREE:%.*]] +; IS__CGSCC_NPM-NEXT: i32 4, label [[ONFOUR:%.*]] +; IS__CGSCC_NPM-NEXT: i32 5, label [[ONFIVE:%.*]] +; IS__CGSCC_NPM-NEXT: i32 6, label [[ONSIX:%.*]] +; IS__CGSCC_NPM-NEXT: ] +; IS__CGSCC_NPM: onzero: +; IS__CGSCC_NPM-NEXT: ret i32 0 +; IS__CGSCC_NPM: onone: +; IS__CGSCC_NPM-NEXT: ret i32 1 +; IS__CGSCC_NPM: ontwo: +; IS__CGSCC_NPM-NEXT: ret i32 2 +; IS__CGSCC_NPM: onthree: +; IS__CGSCC_NPM-NEXT: ret i32 3 +; IS__CGSCC_NPM: onfour: +; IS__CGSCC_NPM-NEXT: ret i32 4 +; IS__CGSCC_NPM: onfive: +; IS__CGSCC_NPM-NEXT: ret i32 5 +; IS__CGSCC_NPM: onsix: +; IS__CGSCC_NPM-NEXT: ret i32 6 +; IS__CGSCC_NPM: otherwise: +; IS__CGSCC_NPM-NEXT: ret i32 99 ; switch i32 %c, label %otherwise [ i32 0, label %onzero i32 1, label %onone @@ -1214,21 +1760,41 @@ otherwise: } define internal i1 @is_less_than_100_1(i32 %c) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_1 -; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@is_less_than_100_1 +; IS__CGSCC_OPM-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] { +; 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 noundef [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 +; IS__CGSCC_NPM-NEXT: ret i1 [[CMP]] ; %cmp = icmp slt i32 %c, 100 ret i1 %cmp } define i1 @propagate_range1(i32 %c){ -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@propagate_range1 -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@propagate_range1 +; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@propagate_range1 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 [[C]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: ret i1 [[TRUE]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@propagate_range1 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 [[C]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR6]] +; 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) @@ -1237,34 +1803,63 @@ define i1 @propagate_range1(i32 %c){ define internal i32 @less_than_100_2(i32 %c) { ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_100_2 -; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ -; IS__CGSCC____-NEXT: i32 0, label [[ONZERO:%.*]] -; IS__CGSCC____-NEXT: i32 1, label [[ONONE:%.*]] -; IS__CGSCC____-NEXT: i32 2, label [[ONTWO:%.*]] -; IS__CGSCC____-NEXT: i32 3, label [[ONTHREE:%.*]] -; IS__CGSCC____-NEXT: i32 4, label [[ONFOUR:%.*]] -; IS__CGSCC____-NEXT: i32 5, label [[ONFIVE:%.*]] -; IS__CGSCC____-NEXT: i32 6, label [[ONSIX:%.*]] -; IS__CGSCC____-NEXT: ] -; IS__CGSCC____: onzero: -; IS__CGSCC____-NEXT: ret i32 0 -; IS__CGSCC____: onone: -; IS__CGSCC____-NEXT: ret i32 1 -; IS__CGSCC____: ontwo: -; IS__CGSCC____-NEXT: ret i32 2 -; IS__CGSCC____: onthree: -; IS__CGSCC____-NEXT: ret i32 3 -; IS__CGSCC____: onfour: -; IS__CGSCC____-NEXT: ret i32 4 -; IS__CGSCC____: onfive: -; IS__CGSCC____-NEXT: ret i32 5 -; IS__CGSCC____: onsix: -; IS__CGSCC____-NEXT: ret i32 6 -; IS__CGSCC____: otherwise: -; IS__CGSCC____-NEXT: ret i32 99 +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@less_than_100_2 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ +; IS__CGSCC_OPM-NEXT: i32 0, label [[ONZERO:%.*]] +; IS__CGSCC_OPM-NEXT: i32 1, label [[ONONE:%.*]] +; IS__CGSCC_OPM-NEXT: i32 2, label [[ONTWO:%.*]] +; IS__CGSCC_OPM-NEXT: i32 3, label [[ONTHREE:%.*]] +; IS__CGSCC_OPM-NEXT: i32 4, label [[ONFOUR:%.*]] +; IS__CGSCC_OPM-NEXT: i32 5, label [[ONFIVE:%.*]] +; IS__CGSCC_OPM-NEXT: i32 6, label [[ONSIX:%.*]] +; IS__CGSCC_OPM-NEXT: ] +; IS__CGSCC_OPM: onzero: +; IS__CGSCC_OPM-NEXT: ret i32 0 +; IS__CGSCC_OPM: onone: +; IS__CGSCC_OPM-NEXT: ret i32 1 +; IS__CGSCC_OPM: ontwo: +; IS__CGSCC_OPM-NEXT: ret i32 2 +; IS__CGSCC_OPM: onthree: +; IS__CGSCC_OPM-NEXT: ret i32 3 +; IS__CGSCC_OPM: onfour: +; IS__CGSCC_OPM-NEXT: ret i32 4 +; IS__CGSCC_OPM: onfive: +; IS__CGSCC_OPM-NEXT: ret i32 5 +; IS__CGSCC_OPM: onsix: +; IS__CGSCC_OPM-NEXT: ret i32 6 +; IS__CGSCC_OPM: otherwise: +; IS__CGSCC_OPM-NEXT: ret i32 99 +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@less_than_100_2 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: switch i32 [[C]], label [[OTHERWISE:%.*]] [ +; IS__CGSCC_NPM-NEXT: i32 0, label [[ONZERO:%.*]] +; IS__CGSCC_NPM-NEXT: i32 1, label [[ONONE:%.*]] +; IS__CGSCC_NPM-NEXT: i32 2, label [[ONTWO:%.*]] +; IS__CGSCC_NPM-NEXT: i32 3, label [[ONTHREE:%.*]] +; IS__CGSCC_NPM-NEXT: i32 4, label [[ONFOUR:%.*]] +; IS__CGSCC_NPM-NEXT: i32 5, label [[ONFIVE:%.*]] +; IS__CGSCC_NPM-NEXT: i32 6, label [[ONSIX:%.*]] +; IS__CGSCC_NPM-NEXT: ] +; IS__CGSCC_NPM: onzero: +; IS__CGSCC_NPM-NEXT: ret i32 0 +; IS__CGSCC_NPM: onone: +; IS__CGSCC_NPM-NEXT: ret i32 1 +; IS__CGSCC_NPM: ontwo: +; IS__CGSCC_NPM-NEXT: ret i32 2 +; IS__CGSCC_NPM: onthree: +; IS__CGSCC_NPM-NEXT: ret i32 3 +; IS__CGSCC_NPM: onfour: +; IS__CGSCC_NPM-NEXT: ret i32 4 +; IS__CGSCC_NPM: onfive: +; IS__CGSCC_NPM-NEXT: ret i32 5 +; IS__CGSCC_NPM: onsix: +; IS__CGSCC_NPM-NEXT: ret i32 6 +; IS__CGSCC_NPM: otherwise: +; IS__CGSCC_NPM-NEXT: ret i32 99 ; switch i32 %c, label %otherwise [ i32 0, label %onzero i32 1, label %onone @@ -1293,21 +1888,47 @@ otherwise: define internal i1 @is_less_than_100_2(i32 %c) { ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@is_less_than_100_2 -; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 -; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@is_less_than_100_2 +; IS__CGSCC_OPM-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] { +; 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_2 +; IS__CGSCC_NPM-SAME: (i32 noundef [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 100 +; IS__CGSCC_NPM-NEXT: ret i1 [[CMP]] ; %cmp = icmp slt i32 %c, 100 ret i1 %cmp } define i1 @propagate_range2(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@propagate_range2 -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@propagate_range2 +; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@propagate_range2 +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]] +; IS__CGSCC_OPM-NEXT: ret i1 [[TRUE]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@propagate_range2 +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 [[C]]) #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR6]] +; 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) @@ -1318,15 +1939,21 @@ define i1 @propagate_range2(i32 %c) { } define internal i1 @non_zero(i8 %v) { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@non_zero -; IS________OPM-SAME: (i8 [[V:%.*]]) #[[ATTR1]] { -; IS________OPM-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0 -; IS________OPM-NEXT: ret i1 [[R]] +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@non_zero +; IS__TUNIT_OPM-SAME: (i8 [[V:%.*]]) #[[ATTR1]] { +; IS__TUNIT_OPM-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0 +; IS__TUNIT_OPM-NEXT: ret i1 [[R]] +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@non_zero +; IS__CGSCC_OPM-SAME: (i8 [[V:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0 +; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@non_zero -; IS__CGSCC_NPM-SAME: () #[[ATTR1]] { +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: ret i1 true ; %r = icmp ne i8 %v, 0 @@ -1335,28 +1962,52 @@ define internal i1 @non_zero(i8 %v) { ; Avoid range metadata for %l below define i1 @context(i8* %p) { -; IS________OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS________OPM-LABEL: define {{[^@]+}}@context -; IS________OPM-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR0]] { -; IS________OPM-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 -; IS________OPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] -; IS________OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS________OPM: t: -; IS________OPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR5]] -; IS________OPM-NEXT: ret i1 [[R]] -; IS________OPM: f: -; IS________OPM-NEXT: ret i1 false +; IS__TUNIT_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@context +; IS__TUNIT_OPM-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR0]] { +; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] +; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_OPM: t: +; IS__TUNIT_OPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR5]] +; IS__TUNIT_OPM-NEXT: ret i1 [[R]] +; IS__TUNIT_OPM: f: +; IS__TUNIT_OPM-NEXT: ret i1 false ; -; IS________NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn -; IS________NPM-LABEL: define {{[^@]+}}@context -; IS________NPM-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR0]] { -; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 -; IS________NPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] -; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS________NPM: t: -; IS________NPM-NEXT: ret i1 true -; IS________NPM: f: -; IS________NPM-NEXT: ret i1 false +; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@context +; IS__TUNIT_NPM-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR0]] { +; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] +; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_NPM: t: +; IS__TUNIT_NPM-NEXT: ret i1 true +; IS__TUNIT_NPM: f: +; IS__TUNIT_NPM-NEXT: ret i1 false +; +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@context +; IS__CGSCC_OPM-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_OPM: t: +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR7]] +; IS__CGSCC_OPM-NEXT: ret i1 [[R]] +; IS__CGSCC_OPM: f: +; IS__CGSCC_OPM-NEXT: ret i1 false +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@context +; IS__CGSCC_NPM-SAME: (i8* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_NPM: t: +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i1 @non_zero() #[[ATTR6]] +; IS__CGSCC_NPM-NEXT: ret i1 [[R]] +; IS__CGSCC_NPM: f: +; IS__CGSCC_NPM-NEXT: ret i1 false ; %l = load i8, i8* %p %c = icmp slt i8 0, %l @@ -1432,20 +2083,35 @@ bb3: ; preds = %bb2, %bb1 } define i1 @loop_1(i32 %N) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone -; CHECK-LABEL: define {{[^@]+}}@loop_1 -; CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: br label [[HEADER:%.*]] -; CHECK: header: -; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ] -; CHECK-NEXT: [[INC:%.*]] = add i32 [[I]], 1 -; CHECK-NEXT: [[AND]] = and i32 [[INC]], 9999 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]] -; CHECK-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] -; CHECK: exit: -; CHECK-NEXT: [[R:%.*]] = icmp sle i32 [[I]], 5 -; CHECK-NEXT: ret i1 [[R]] +; NOT_CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@loop_1 +; NOT_CGSCC_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR2:[0-9]+]] { +; NOT_CGSCC_NPM-NEXT: entry: +; NOT_CGSCC_NPM-NEXT: br label [[HEADER:%.*]] +; NOT_CGSCC_NPM: header: +; NOT_CGSCC_NPM-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ] +; NOT_CGSCC_NPM-NEXT: [[INC:%.*]] = add i32 [[I]], 1 +; NOT_CGSCC_NPM-NEXT: [[AND]] = and i32 [[INC]], 9999 +; NOT_CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]] +; NOT_CGSCC_NPM-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] +; NOT_CGSCC_NPM: exit: +; NOT_CGSCC_NPM-NEXT: [[R:%.*]] = icmp sle i32 [[I]], 5 +; NOT_CGSCC_NPM-NEXT: ret i1 [[R]] +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@loop_1 +; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: br label [[HEADER:%.*]] +; IS__CGSCC_NPM: header: +; IS__CGSCC_NPM-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[AND:%.*]], [[HEADER]] ] +; IS__CGSCC_NPM-NEXT: [[INC:%.*]] = add i32 [[I]], 1 +; IS__CGSCC_NPM-NEXT: [[AND]] = and i32 [[INC]], 9999 +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp ne i32 [[N]], [[AND]] +; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]] +; IS__CGSCC_NPM: exit: +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = icmp sle i32 [[I]], 5 +; IS__CGSCC_NPM-NEXT: ret i1 [[R]] ; entry: br label %header @@ -1482,17 +2148,21 @@ declare void @barney(i32 signext, i32 signext) ; IS__TUNIT_NPM: attributes #[[ATTR4]] = { nofree nosync nounwind readnone willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind readonly willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR3]] = { readonly willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR5]] = { readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR5]] = { readonly willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nounwind readnone } +; IS__CGSCC_OPM: attributes #[[ATTR7]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC_NPM: attributes #[[ATTR3]] = { readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR4]] = { readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readnone } +; IS__CGSCC_NPM: attributes #[[ATTR5]] = { readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR6]] = { readnone willreturn } ;. ; IS__TUNIT_OPM: [[RNG0]] = !{i32 0, i32 10} ; IS__TUNIT_OPM: [[RNG1]] = !{i32 10, i32 100} @@ -1500,17 +2170,13 @@ declare void @barney(i32 signext, i32 signext) ; IS__TUNIT_OPM: [[RNG3]] = !{i32 0, i32 2} ; IS__TUNIT_OPM: [[RNG4]] = !{i32 1, i32 3} ;. -; IS________NPM: [[RNG0]] = !{i32 0, i32 10} -; IS________NPM: [[RNG1]] = !{i32 10, i32 100} -; IS________NPM: [[RNG2]] = !{i32 200, i32 1091} -; IS________NPM: [[RNG3]] = !{i32 1, i32 -2147483648} -; IS________NPM: [[RNG4]] = !{i32 0, i32 2} -; IS________NPM: [[RNG5]] = !{i32 1, i32 3} +; IS__TUNIT_NPM: [[RNG0]] = !{i32 0, i32 10} +; IS__TUNIT_NPM: [[RNG1]] = !{i32 10, i32 100} +; IS__TUNIT_NPM: [[RNG2]] = !{i32 200, i32 1091} +; IS__TUNIT_NPM: [[RNG3]] = !{i32 1, i32 -2147483648} +; IS__TUNIT_NPM: [[RNG4]] = !{i32 0, i32 2} +; IS__TUNIT_NPM: [[RNG5]] = !{i32 1, i32 3} ;. -; IS__CGSCC_OPM: [[RNG0]] = !{i32 0, i32 10} -; IS__CGSCC_OPM: [[RNG1]] = !{i32 10, i32 100} -; IS__CGSCC_OPM: [[RNG2]] = !{i32 200, i32 1091} -; IS__CGSCC_OPM: [[RNG3]] = !{i32 10, i32 21} -; IS__CGSCC_OPM: [[RNG4]] = !{i32 0, i32 2} -; IS__CGSCC_OPM: [[RNG5]] = !{i32 1, i32 3} +; IS__CGSCC____: [[RNG0]] = !{i32 0, i32 10} +; IS__CGSCC____: [[RNG1]] = !{i32 10, i32 100} ;. diff --git a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll index c13685c007a2..1070923a6ea3 100644 --- a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll +++ b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll @@ -49,10 +49,10 @@ define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) { ; IS__CGSCC____-LABEL: define {{[^@]+}}@external_ret2_nrw ; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree [[W0]]) #[[ATTR3:[0-9]+]] -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree align 4 [[R0]], i32* nofree align 4 [[R0]], i32* nofree [[W0]]) #[[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR4:[0-9]+]] -; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree [[W0]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree align 4 [[R0]], i32* nofree align 4 [[R0]], i32* nofree [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly [[W0]]) #[[ATTR3:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]]) #[[ATTR2]] ; IS__CGSCC____-NEXT: ret i32* [[CALL3]] ; entry: @@ -103,12 +103,12 @@ define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) { ; 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]]) #[[ATTR3]] -; 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]]) #[[ATTR3]] -; 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]]) #[[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[W0]]) #[[ATTR4]] -; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[W0]]) #[[ATTR4]] -; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: return: ; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[N0]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ] @@ -179,19 +179,19 @@ define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) { ; 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 noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) #[[ATTR2]] ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[R0]], align 4 ; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* [[R1]], align 4 ; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[TMP2]] ; IS__CGSCC____-NEXT: store i32 [[ADD]], i32* [[W0]], align 4 -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @internal_ret0_nw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] -; 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]]) #[[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @external_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree noundef 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]]) #[[ATTR4]] -; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[W0]]) #[[ATTR4]] -; 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]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @internal_ret0_nw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[W0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @external_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: return: ; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[R1]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ] @@ -291,13 +291,13 @@ define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) { ; 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 noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) #[[ATTR3]] +; 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) [[R0]], i32* nofree [[W0]]) #[[ATTR2]] ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[R0]], align 4 ; IS__CGSCC____-NEXT: store i32 [[TMP1]], i32* [[W0]], align 4 -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret0_nw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] -; 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]]) #[[ATTR3]] -; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[W0]]) #[[ATTR4]] -; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret0_nw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[W0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4 dereferenceable(4) [[W0]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]] ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: return: ; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL4]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ] @@ -335,12 +335,12 @@ define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) { ; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR3]] ; IS__TUNIT____-NEXT: ret i32* [[CALL1]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@external_source_ret2_nrw -; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR5:[0-9]+]] -; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly [[W0]]) #[[ATTR4:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR3]] ; IS__CGSCC____-NEXT: ret i32* [[CALL1]] ; entry: @@ -360,8 +360,7 @@ entry: ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind } ; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { argmemonly nofree norecurse nosync nounwind } -; IS__CGSCC____: attributes #[[ATTR3]] = { nofree nosync nounwind } -; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind } -; IS__CGSCC____: attributes #[[ATTR5]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind } +; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll index 94ed99c4ce82..d3af93dbb4c3 100644 --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -110,12 +110,19 @@ entry: } define void @test8_2(i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@test8_2 -; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: store i32 10, i32* [[P]], align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_2 +; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: store i32 10, i32* [[P]], align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_2 +; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: store i32 10, i32* [[P]], align 4 +; IS__CGSCC____-NEXT: ret void ; entry: %call = call i32* @test8_1(i32* %p) @@ -129,11 +136,17 @@ declare void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32>%val, <4 x i32*>, i32, ; CHECK-NOT: readnone ; CHECK-NOT: readonly define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@test9 -; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef ) #[[ATTR12:[0-9]+]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test9 +; IS__TUNIT____-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef ) #[[ATTR12:[0-9]+]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test9 +; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef ) #[[ATTR13:[0-9]+]] +; IS__CGSCC____-NEXT: ret void ; call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32>%val, <4 x i32*> %ptrs, i32 4, <4 x i1>) ret void @@ -142,11 +155,17 @@ define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) { ; CHECK: declare <4 x i32> @llvm.masked.gather declare <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*>, i32, <4 x i1>, <4 x i32>) define <4 x i32> @test10(<4 x i32*> %ptrs) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readonly willreturn -; CHECK-LABEL: define {{[^@]+}}@test10 -; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR6:[0-9]+]] { -; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef , <4 x i32> undef) #[[ATTR13:[0-9]+]] -; CHECK-NEXT: ret <4 x i32> [[RES]] +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test10 +; IS__TUNIT____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__TUNIT____-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef , <4 x i32> undef) #[[ATTR13:[0-9]+]] +; IS__TUNIT____-NEXT: ret <4 x i32> [[RES]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@test10 +; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef , <4 x i32> undef) #[[ATTR14:[0-9]+]] +; IS__CGSCC____-NEXT: ret <4 x i32> [[RES]] ; %res = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> %ptrs, i32 4, <4 x i1>, <4 x i32>undef) ret <4 x i32> %res @@ -155,11 +174,17 @@ define <4 x i32> @test10(<4 x i32*> %ptrs) { ; CHECK: declare <4 x i32> @test11_1 declare <4 x i32> @test11_1(<4 x i32*>) argmemonly nounwind readonly define <4 x i32> @test11_2(<4 x i32*> %ptrs) { -; CHECK: Function Attrs: argmemonly nounwind readonly -; CHECK-LABEL: define {{[^@]+}}@test11_2 -; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR7:[0-9]+]] { -; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) #[[ATTR11:[0-9]+]] -; CHECK-NEXT: ret <4 x i32> [[RES]] +; IS__TUNIT____: Function Attrs: argmemonly nounwind readonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test11_2 +; IS__TUNIT____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__TUNIT____-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) #[[ATTR11:[0-9]+]] +; IS__TUNIT____-NEXT: ret <4 x i32> [[RES]] +; +; IS__CGSCC____: Function Attrs: argmemonly nounwind readonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test11_2 +; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) #[[ATTR12:[0-9]+]] +; IS__CGSCC____-NEXT: ret <4 x i32> [[RES]] ; %res = call <4 x i32> @test11_1(<4 x i32*> %ptrs) ret <4 x i32> %res @@ -168,22 +193,34 @@ define <4 x i32> @test11_2(<4 x i32*> %ptrs) { declare <4 x i32> @test12_1(<4 x i32*>) argmemonly nounwind ; CHECK-NOT: readnone define <4 x i32> @test12_2(<4 x i32*> %ptrs) { -; CHECK: Function Attrs: argmemonly nounwind -; CHECK-LABEL: define {{[^@]+}}@test12_2 -; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR8:[0-9]+]] { -; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR14:[0-9]+]] -; CHECK-NEXT: ret <4 x i32> [[RES]] +; IS__TUNIT____: Function Attrs: argmemonly nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@test12_2 +; IS__TUNIT____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__TUNIT____-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR14:[0-9]+]] +; IS__TUNIT____-NEXT: ret <4 x i32> [[RES]] +; +; IS__CGSCC____: Function Attrs: argmemonly nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@test12_2 +; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR15:[0-9]+]] +; IS__CGSCC____-NEXT: ret <4 x i32> [[RES]] ; %res = call <4 x i32> @test12_1(<4 x i32*> %ptrs) ret <4 x i32> %res } define i32 @volatile_load(i32* %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@volatile_load -; CHECK-SAME: (i32* nofree noundef align 4 [[P:%.*]]) #[[ATTR9:[0-9]+]] { -; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4 -; CHECK-NEXT: ret i32 [[LOAD]] +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_load +; IS__TUNIT____-SAME: (i32* nofree noundef align 4 [[P:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__TUNIT____-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4 +; IS__TUNIT____-NEXT: ret i32 [[LOAD]] +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_load +; IS__CGSCC____-SAME: (i32* nofree noundef align 4 [[P:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__CGSCC____-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4 +; IS__CGSCC____-NEXT: ret i32 [[LOAD]] ; %load = load volatile i32, i32* %p ret i32 %load @@ -257,11 +294,17 @@ define void @byval_not_readonly_2(i8* byval(i8) %written) readonly { } define void @byval_not_readnone_1(i8* byval(i8) %written) readnone { -; CHECK: Function Attrs: readnone -; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_1 -; CHECK-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR10:[0-9]+]] { -; CHECK-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]]) -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: readnone +; IS__TUNIT____-LABEL: define {{[^@]+}}@byval_not_readnone_1 +; IS__TUNIT____-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__TUNIT____-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]]) +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: readnone +; IS__CGSCC____-LABEL: define {{[^@]+}}@byval_not_readnone_1 +; IS__CGSCC____-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__CGSCC____-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]]) +; IS__CGSCC____-NEXT: ret void ; call void @escape_i8(i8* %written) ret void @@ -301,7 +344,7 @@ define void @testbyval(i8* %read_only) { ; IS__CGSCC____-SAME: (i8* nocapture noundef nonnull readonly dereferenceable(1) [[READ_ONLY:%.*]]) { ; IS__CGSCC____-NEXT: call void @byval_not_readonly_1(i8* noalias nocapture noundef nonnull readonly byval(i8) dereferenceable(1) [[READ_ONLY]]) #[[ATTR2]] ; IS__CGSCC____-NEXT: call void @byval_not_readnone_1(i8* noalias nocapture noundef nonnull readnone byval(i8) dereferenceable(1) [[READ_ONLY]]) -; IS__CGSCC____-NEXT: call void @byval_no_fnarg(i8* noalias nocapture nofree noundef nonnull readnone byval(i8) dereferenceable(1) [[READ_ONLY]]) #[[ATTR15:[0-9]+]] +; IS__CGSCC____-NEXT: call void @byval_no_fnarg(i8* noalias nocapture nofree noundef nonnull readnone byval(i8) dereferenceable(1) [[READ_ONLY]]) #[[ATTR16:[0-9]+]] ; IS__CGSCC____-NEXT: ret void ; call void @byval_not_readonly_1(i8* byval(i8) %read_only) @@ -318,12 +361,19 @@ declare i8 @maybe_returned_val(i8* %ptr) readonly nounwind declare void @val_use(i8 %ptr) readonly nounwind define void @ptr_uses(i8* %ptr) { -; CHECK: Function Attrs: nounwind readonly -; CHECK-LABEL: define {{[^@]+}}@ptr_uses -; CHECK-SAME: (i8* nocapture readonly [[PTR:%.*]]) #[[ATTR11]] { -; CHECK-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]]) #[[ATTR11]] -; CHECK-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]]) #[[ATTR11]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nounwind readonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_uses +; IS__TUNIT____-SAME: (i8* nocapture readonly [[PTR:%.*]]) #[[ATTR11]] { +; IS__TUNIT____-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]]) #[[ATTR11]] +; IS__TUNIT____-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]]) #[[ATTR11]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nounwind readonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_uses +; IS__CGSCC____-SAME: (i8* nocapture readonly [[PTR:%.*]]) #[[ATTR12]] { +; IS__CGSCC____-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]]) #[[ATTR12]] +; IS__CGSCC____-NEXT: ret void ; %call_ptr = call i8* @maybe_returned_ptr(i8* %ptr) %call_val = call i8 @maybe_returned_val(i8* %call_ptr) @@ -371,20 +421,38 @@ define i32 @read_only_constant_mem() { ret i32 %l } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn writeonly } -; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; CHECK: attributes #[[ATTR2]] = { readonly } -; CHECK: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; CHECK: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind willreturn writeonly } -; CHECK: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind readonly willreturn } -; CHECK: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readonly willreturn } -; CHECK: attributes #[[ATTR7]] = { argmemonly nounwind readonly } -; CHECK: attributes #[[ATTR8]] = { argmemonly nounwind } -; CHECK: attributes #[[ATTR9]] = { argmemonly nofree norecurse nounwind willreturn } -; CHECK: attributes #[[ATTR10]] = { readnone } -; CHECK: attributes #[[ATTR11]] = { nounwind readonly } -; CHECK: attributes #[[ATTR12]] = { willreturn writeonly } -; CHECK: attributes #[[ATTR13]] = { readonly willreturn } -; CHECK: attributes #[[ATTR14]] = { nounwind } -; CHECK: attributes #[[ATTR15:[0-9]+]] = { nounwind writeonly } +; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR2]] = { readonly } +; IS__TUNIT____: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__TUNIT____: attributes #[[ATTR4:[0-9]+]] = { nocallback nofree nosync nounwind willreturn writeonly } +; IS__TUNIT____: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind readonly willreturn } +; IS__TUNIT____: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readonly willreturn } +; IS__TUNIT____: attributes #[[ATTR7]] = { argmemonly nounwind readonly } +; IS__TUNIT____: attributes #[[ATTR8]] = { argmemonly nounwind } +; IS__TUNIT____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR10]] = { readnone } +; IS__TUNIT____: attributes #[[ATTR11]] = { nounwind readonly } +; IS__TUNIT____: attributes #[[ATTR12]] = { willreturn writeonly } +; IS__TUNIT____: attributes #[[ATTR13]] = { readonly willreturn } +; IS__TUNIT____: attributes #[[ATTR14]] = { nounwind } +; IS__TUNIT____: attributes #[[ATTR15]] = { nounwind writeonly } +;. +; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { readonly } +; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nounwind readonly } +; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nounwind } +; IS__CGSCC____: attributes #[[ATTR10]] = { argmemonly nofree norecurse nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR11]] = { readnone } +; IS__CGSCC____: attributes #[[ATTR12]] = { nounwind readonly } +; IS__CGSCC____: attributes #[[ATTR13]] = { willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR14]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR15]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR16]] = { nounwind writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll index b1c0cb43ac6e..e6c08dca67d3 100644 --- a/llvm/test/Transforms/Attributor/returned.ll +++ b/llvm/test/Transforms/Attributor/returned.ll @@ -54,12 +54,19 @@ entry: } define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@scc_r1 -; CHECK-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR10:[0-9]+]] -; CHECK-NEXT: ret i32 [[R]] +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_r1 +; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR10:[0-9]+]] +; IS__TUNIT____-NEXT: ret i32 [[R]] +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r1 +; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR7:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: %call = call i32 @sink_r0(i32 %r) @@ -68,40 +75,75 @@ entry: } define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@scc_r2 -; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] { -; 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: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR10]] -; 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: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR10]] -; CHECK-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR10]] -; CHECK-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR10]] -; CHECK-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR10]] -; CHECK-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR10]] -; CHECK-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR10]] -; 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]]) #[[ATTR10]] -; CHECK-NEXT: br label [[COND_END]] -; CHECK: cond.end: -; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ] -; CHECK-NEXT: br label [[RETURN]] -; CHECK: return: -; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] -; CHECK-NEXT: ret i32 [[R]] +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_r2 +; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] { +; 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: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR10]] +; 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: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR10]] +; 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]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: br label [[COND_END]] +; IS__TUNIT____: cond.end: +; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ] +; IS__TUNIT____-NEXT: br label [[RETURN]] +; IS__TUNIT____: return: +; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; IS__TUNIT____-NEXT: ret i32 [[R]] +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r2 +; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] { +; 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: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR7]] +; 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: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR7]] +; 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]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: br label [[COND_END]] +; IS__CGSCC____: cond.end: +; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ] +; IS__CGSCC____-NEXT: br label [[RETURN]] +; IS__CGSCC____: return: +; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: %cmp = icmp sgt i32 %a, %b @@ -183,26 +225,26 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 { ; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[B]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] ; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]] ; -; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable +; 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:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR1]] { ; 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: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR11:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR8:[0-9]+]] ; 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: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR11]] -; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR11]] -; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 [[R]]) #[[ATTR11]] -; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR11]] -; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[B]]) #[[ATTR11]] -; IS__CGSCC____-NEXT: [[CALL10:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR11]] -; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[B]], i32 [[B]]) #[[ATTR11]] +; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]] +; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR8]] +; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 [[R]]) #[[ATTR8]] +; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]] +; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[B]]) #[[ATTR8]] +; IS__CGSCC____-NEXT: [[CALL10:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]] +; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[B]], i32 [[B]]) #[[ATTR8]] ; IS__CGSCC____-NEXT: br label [[RETURN]] ; IS__CGSCC____: if.end12: ; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]] @@ -210,7 +252,7 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 { ; 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]]) #[[ATTR11]] +; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]] ; IS__CGSCC____-NEXT: br label [[COND_END]] ; IS__CGSCC____: cond.end: ; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ] @@ -296,12 +338,19 @@ entry: } define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@ptr_scc_r1 -; CHECK-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] -; CHECK-NEXT: ret double* [[R]] +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r1 +; IS__TUNIT____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: ret double* [[R]] +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r1 +; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: ret double* [[R]] ; entry: %call = call double* @ptr_sink_r0(double* %r) @@ -310,40 +359,75 @@ entry: } define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@ptr_scc_r2 -; CHECK-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]] -; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; CHECK: if.then: -; CHECK-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] -; CHECK-NEXT: br label [[RETURN:%.*]] -; CHECK: if.end: -; CHECK-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]] -; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] -; CHECK: if.then3: -; CHECK-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR10]] -; CHECK-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] -; CHECK-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR10]] -; CHECK-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] -; CHECK-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] -; CHECK-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR10]] -; CHECK-NEXT: br label [[RETURN]] -; CHECK: if.end12: -; CHECK-NEXT: [[CMP13:%.*]] = icmp eq double* [[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 double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] -; CHECK-NEXT: br label [[COND_END]] -; CHECK: cond.end: -; CHECK-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ] -; CHECK-NEXT: br label [[RETURN]] -; CHECK: return: -; CHECK-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] -; CHECK-NEXT: ret double* [[R]] +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r2 +; IS__TUNIT____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]] +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT____: if.then: +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: br label [[RETURN:%.*]] +; IS__TUNIT____: if.end: +; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]] +; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] +; IS__TUNIT____: if.then3: +; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR10]] +; IS__TUNIT____-NEXT: br label [[RETURN]] +; IS__TUNIT____: if.end12: +; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq double* [[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 double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: br label [[COND_END]] +; IS__TUNIT____: cond.end: +; IS__TUNIT____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ] +; IS__TUNIT____-NEXT: br label [[RETURN]] +; IS__TUNIT____: return: +; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; IS__TUNIT____-NEXT: ret double* [[R]] +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r2 +; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned [[R:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; 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: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: br label [[RETURN:%.*]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]] +; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]] +; IS__CGSCC____: if.then3: +; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR7]] +; IS__CGSCC____-NEXT: br label [[RETURN]] +; IS__CGSCC____: if.end12: +; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq double* [[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 double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: br label [[COND_END]] +; IS__CGSCC____: cond.end: +; IS__CGSCC____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ] +; IS__CGSCC____-NEXT: br label [[RETURN]] +; IS__CGSCC____: return: +; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ] +; IS__CGSCC____-NEXT: ret double* [[R]] ; entry: %cmp = icmp ugt double* %a, %b @@ -406,9 +490,9 @@ define i32* @rt0(i32* %a) #0 { ; ; IS__CGSCC____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@rt0 -; IS__CGSCC____-SAME: (i32* nofree noundef nonnull readonly returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nofree noundef nonnull readonly returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt0(i32* nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR12:[0-9]+]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt0(i32* nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR9:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32* [[A]] ; entry: @@ -426,11 +510,17 @@ entry: ; } ; define i32* @rt1(i32* %a) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@rt1 -; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR4:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i32* undef +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@rt1 +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i32* undef +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@rt1 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i32* undef ; entry: %v = load i32, i32* %a, align 4 @@ -443,12 +533,19 @@ entry: ; TEST another SCC test ; define i32* @rt2_helper(i32* %a) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@rt2_helper -; CHECK-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR10]] -; CHECK-NEXT: ret i32* [[A]] +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@rt2_helper +; IS__TUNIT____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: ret i32* [[A]] +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2_helper +; IS__CGSCC____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: ret i32* [[A]] ; entry: %call = call i32* @rt2(i32* %a, i32* %a) @@ -456,18 +553,31 @@ entry: } define i32* @rt2(i32* %a, i32 *%b) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@rt2 -; CHECK-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null -; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; CHECK: if.then: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR10]] -; CHECK-NEXT: br label [[IF_END]] -; CHECK: if.end: -; CHECK-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ] -; CHECK-NEXT: ret i32* [[SEL]] +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@rt2 +; IS__TUNIT____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT____: if.then: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: br label [[IF_END]] +; IS__TUNIT____: if.end: +; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ] +; IS__TUNIT____-NEXT: ret i32* [[SEL]] +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2 +; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__CGSCC____: if.then: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: br label [[IF_END]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ] +; IS__CGSCC____-NEXT: ret i32* [[SEL]] ; entry: %cmp = icmp eq i32* %a, null @@ -485,12 +595,19 @@ if.end: ; TEST another SCC test ; define i32* @rt3_helper(i32* %a, i32* %b) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@rt3_helper -; CHECK-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR10]] -; CHECK-NEXT: ret i32* [[B]] +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3_helper +; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: ret i32* [[B]] +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3_helper +; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: ret i32* [[B]] ; entry: %call = call i32* @rt3(i32* %a, i32* %b) @@ -498,18 +615,31 @@ entry: } define i32* @rt3(i32* %a, i32 *%b) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@rt3 -; CHECK-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null -; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; CHECK: if.then: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR10]] -; CHECK-NEXT: br label [[IF_END]] -; CHECK: if.end: -; CHECK-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ] -; CHECK-NEXT: ret i32* [[B]] +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3 +; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT____: if.then: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: br label [[IF_END]] +; IS__TUNIT____: if.end: +; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ] +; IS__TUNIT____-NEXT: ret i32* [[B]] +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3 +; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__CGSCC____: if.then: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: br label [[IF_END]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ] +; IS__CGSCC____-NEXT: ret i32* [[B]] ; entry: %cmp = icmp eq i32* %a, null @@ -544,8 +674,8 @@ define i32* @calls_unknown_fn(i32* %r) #0 { ; ; IS__CGSCC____: Function Attrs: noinline nounwind uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_unknown_fn -; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR5:[0-9]+]] { -; IS__CGSCC____-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR13:[0-9]+]] +; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR10:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32* [[R]] ; tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn) @@ -567,11 +697,17 @@ define i32* @calls_unknown_fn(i32* %r) #0 { ; Verify the maybe-redefined function is not annotated: ; define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 { -; CHECK: Function Attrs: noinline nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn -; CHECK-SAME: (i32* [[R:%.*]]) #[[ATTR5:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i32* [[R]] +; IS__TUNIT____: Function Attrs: noinline nounwind uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn +; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR5]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i32* [[R]] +; +; IS__CGSCC____: Function Attrs: noinline nounwind uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@maybe_redefined_fn +; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i32* [[R]] ; entry: ret i32* %r @@ -585,11 +721,11 @@ define i32* @calls_maybe_redefined_fn(i32* %r) #0 { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR12]] ; IS__TUNIT____-NEXT: ret i32* [[R]] ; -; IS__CGSCC____: Function Attrs: noinline norecurse nounwind uwtable +; IS__CGSCC____: Function Attrs: noinline nounwind uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn -; IS__CGSCC____-SAME: (i32* returned [[R:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* returned [[R:%.*]]) #[[ATTR4]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR10]] ; IS__CGSCC____-NEXT: ret i32* [[R]] ; entry: @@ -610,11 +746,17 @@ entry: ; Verify the maybe-redefined function is not annotated: ; define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 { -; CHECK: Function Attrs: noinline nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn2 -; CHECK-SAME: (i32* [[R:%.*]]) #[[ATTR5]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret i32* [[R]] +; IS__TUNIT____: Function Attrs: noinline nounwind uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn2 +; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR5]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret i32* [[R]] +; +; IS__CGSCC____: Function Attrs: noinline nounwind uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@maybe_redefined_fn2 +; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: ret i32* [[R]] ; entry: ret i32* %r @@ -628,11 +770,11 @@ define i32* @calls_maybe_redefined_fn2(i32* %r) #0 { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR12]] ; IS__TUNIT____-NEXT: ret i32* [[CALL]] ; -; IS__CGSCC____: Function Attrs: noinline norecurse nounwind uwtable +; IS__CGSCC____: Function Attrs: noinline nounwind uwtable ; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2 -; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR6]] { +; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR13]] +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR10]] ; IS__CGSCC____-NEXT: ret i32* [[CALL]] ; entry: @@ -687,18 +829,31 @@ if.end: ; preds = %if.then, %entry ; } ; define double @recursion_select_and_phi(i32 %a, double %b) #0 { -; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; CHECK-LABEL: define {{[^@]+}}@recursion_select_and_phi -; CHECK-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[A]], -1 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0 -; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; CHECK: if.then: -; CHECK-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR10]] -; CHECK-NEXT: br label [[IF_END]] -; CHECK: if.end: -; CHECK-NEXT: ret double [[B]] +; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@recursion_select_and_phi +; IS__TUNIT____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[DEC:%.*]] = add nsw i32 [[A]], -1 +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0 +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT____: if.then: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR10]] +; IS__TUNIT____-NEXT: br label [[IF_END]] +; IS__TUNIT____: if.end: +; IS__TUNIT____-NEXT: ret double [[B]] +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@recursion_select_and_phi +; IS__CGSCC____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[DEC:%.*]] = add nsw i32 [[A]], -1 +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0 +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__CGSCC____: if.then: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR7]] +; IS__CGSCC____-NEXT: br label [[IF_END]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: ret double [[B]] ; entry: %dec = add nsw i32 %a, -1 @@ -940,17 +1095,29 @@ ret_undef1: declare i32* @unknown(i32*) define i32* @ret_arg_or_unknown(i32* %b) #0 { -; CHECK: Function Attrs: noinline nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown -; CHECK-SAME: (i32* [[B:%.*]]) #[[ATTR5]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null -; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]] -; CHECK: ret_arg: -; CHECK-NEXT: ret i32* [[B]] -; CHECK: ret_unknown: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]]) -; CHECK-NEXT: ret i32* [[CALL]] +; IS__TUNIT____: Function Attrs: noinline nounwind uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown +; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR5]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]] +; IS__TUNIT____: ret_arg: +; IS__TUNIT____-NEXT: ret i32* [[B]] +; IS__TUNIT____: ret_unknown: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]]) +; IS__TUNIT____-NEXT: ret i32* [[CALL]] +; +; IS__CGSCC____: Function Attrs: noinline nounwind uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_or_unknown +; IS__CGSCC____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]] +; IS__CGSCC____: ret_arg: +; IS__CGSCC____-NEXT: ret i32* [[B]] +; IS__CGSCC____: ret_unknown: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]]) +; IS__CGSCC____-NEXT: ret i32* [[CALL]] ; entry: %cmp = icmp eq i32* %b, null @@ -965,20 +1132,35 @@ ret_unknown: } define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 { -; CHECK: Function Attrs: noinline nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi -; CHECK-SAME: (i32* [[B:%.*]]) #[[ATTR5]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null -; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]] -; CHECK: ret_arg: -; CHECK-NEXT: br label [[R:%.*]] -; CHECK: ret_unknown: -; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]]) -; CHECK-NEXT: br label [[R]] -; CHECK: r: -; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ] -; CHECK-NEXT: ret i32* [[PHI]] +; IS__TUNIT____: Function Attrs: noinline nounwind uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi +; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR5]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]] +; IS__TUNIT____: ret_arg: +; IS__TUNIT____-NEXT: br label [[R:%.*]] +; IS__TUNIT____: ret_unknown: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]]) +; IS__TUNIT____-NEXT: br label [[R]] +; IS__TUNIT____: r: +; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ] +; IS__TUNIT____-NEXT: ret i32* [[PHI]] +; +; IS__CGSCC____: Function Attrs: noinline nounwind uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi +; IS__CGSCC____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]] +; IS__CGSCC____: ret_arg: +; IS__CGSCC____-NEXT: br label [[R:%.*]] +; IS__CGSCC____: ret_unknown: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]]) +; IS__CGSCC____-NEXT: br label [[R]] +; IS__CGSCC____: r: +; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ] +; IS__CGSCC____-NEXT: ret i32* [[PHI]] ; entry: %cmp = icmp eq i32* %b, null @@ -1097,20 +1279,35 @@ r: declare void @noreturn() noreturn; define i32 @deadblockphi3(i32 %A, i1 %c) #0 { -; CHECK: Function Attrs: noinline nounwind uwtable -; CHECK-LABEL: define {{[^@]+}}@deadblockphi3 -; CHECK-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR5]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]] -; CHECK: unreachablecall: -; CHECK-NEXT: call void @noreturn() #[[ATTR7:[0-9]+]] -; CHECK-NEXT: unreachable -; CHECK: unreachableblock2: -; CHECK-NEXT: unreachable -; CHECK: unreachableblock3: -; CHECK-NEXT: unreachable -; CHECK: r: -; CHECK-NEXT: ret i32 [[A]] +; IS__TUNIT____: Function Attrs: noinline nounwind uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@deadblockphi3 +; IS__TUNIT____-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR5]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]] +; IS__TUNIT____: unreachablecall: +; IS__TUNIT____-NEXT: call void @noreturn() #[[ATTR7:[0-9]+]] +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: unreachableblock2: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: unreachableblock3: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: r: +; IS__TUNIT____-NEXT: ret i32 [[A]] +; +; IS__CGSCC____: Function Attrs: noinline nounwind uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@deadblockphi3 +; IS__CGSCC____-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]] +; IS__CGSCC____: unreachablecall: +; IS__CGSCC____-NEXT: call void @noreturn() #[[ATTR5:[0-9]+]] +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: unreachableblock2: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: unreachableblock3: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: r: +; IS__CGSCC____-NEXT: ret i32 [[A]] ; entry: br i1 %c, label %r, label %unreachablecall @@ -1168,21 +1365,36 @@ define weak_odr align 16 i32* @non_exact_4(i32* align 32 %a) { ; 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) { -; CHECK: Function Attrs: norecurse -; CHECK-LABEL: define {{[^@]+}}@exact -; CHECK-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) #[[ATTR8:[0-9]+]] { -; CHECK-NEXT: [[C0:%.*]] = call i32 @non_exact_0() -; CHECK-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1) -; CHECK-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2) -; CHECK-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) -; CHECK-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) -; CHECK-NEXT: [[C3L:%.*]] = load i32, i32* [[A]], align 32 -; CHECK-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 -; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] -; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2 -; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] -; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] -; CHECK-NEXT: ret i32 [[ADD4]] +; IS__TUNIT____: Function Attrs: norecurse +; IS__TUNIT____-LABEL: define {{[^@]+}}@exact +; IS__TUNIT____-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__TUNIT____-NEXT: [[C0:%.*]] = call i32 @non_exact_0() +; IS__TUNIT____-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1) +; IS__TUNIT____-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2) +; IS__TUNIT____-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) +; IS__TUNIT____-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) +; IS__TUNIT____-NEXT: [[C3L:%.*]] = load i32, i32* [[A]], align 32 +; IS__TUNIT____-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 +; IS__TUNIT____-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] +; IS__TUNIT____-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2 +; IS__TUNIT____-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] +; IS__TUNIT____-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] +; IS__TUNIT____-NEXT: ret i32 [[ADD4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@exact +; IS__CGSCC____-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) { +; IS__CGSCC____-NEXT: [[C0:%.*]] = call i32 @non_exact_0() +; IS__CGSCC____-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1) +; IS__CGSCC____-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2) +; IS__CGSCC____-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) +; IS__CGSCC____-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) +; IS__CGSCC____-NEXT: [[C3L:%.*]] = load i32, i32* [[A]], align 32 +; IS__CGSCC____-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 +; IS__CGSCC____-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] +; IS__CGSCC____-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2 +; IS__CGSCC____-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] +; IS__CGSCC____-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] +; IS__CGSCC____-NEXT: ret i32 [[ADD4]] ; %c0 = call i32 @non_exact_0() %c1 = call i32 @non_exact_1(i32 1) @@ -1209,19 +1421,31 @@ define i32* @ret_const() #0 { ret i32* %bc } define i32* @use_const() #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@use_const -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: ret i32* bitcast (i8* @G to i32*) +; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@use_const +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32* bitcast (i8* @G to i32*) +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@use_const +; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[C:%.*]] = call noundef nonnull dereferenceable(1) i32* @ret_const() #[[ATTR11:[0-9]+]] +; IS__CGSCC____-NEXT: ret i32* [[C]] ; %c = call i32* @ret_const() ret i32* %c } define i32* @dont_use_const() #0 { -; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable -; CHECK-LABEL: define {{[^@]+}}@dont_use_const -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: ret i32* bitcast (i8* @G to i32*) +; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; IS__TUNIT____-LABEL: define {{[^@]+}}@dont_use_const +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32* bitcast (i8* @G to i32*) +; +; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable +; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_use_const +; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[C:%.*]] = musttail call noundef nonnull dereferenceable(1) i32* @ret_const() #[[ATTR11]] +; IS__CGSCC____-NEXT: ret i32* [[C]] ; %c = musttail call i32* @ret_const() ret i32* %c @@ -1289,16 +1513,14 @@ attributes #0 = { noinline nounwind uwtable } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } -; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly nofree noinline nosync nounwind readonly uwtable } -; IS__CGSCC____: attributes #[[ATTR4]] = { nofree noinline nosync nounwind readnone willreturn uwtable } -; IS__CGSCC____: attributes #[[ATTR5]] = { noinline nounwind uwtable } -; IS__CGSCC____: attributes #[[ATTR6]] = { noinline norecurse nounwind uwtable } -; IS__CGSCC____: attributes #[[ATTR7]] = { noreturn } -; IS__CGSCC____: attributes #[[ATTR8]] = { norecurse } -; IS__CGSCC____: attributes #[[ATTR9:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR10]] = { nofree nosync nounwind readnone } -; IS__CGSCC____: attributes #[[ATTR11]] = { nounwind readnone } -; IS__CGSCC____: attributes #[[ATTR12]] = { nofree nosync nounwind readonly } -; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR2]] = { argmemonly nofree noinline nosync nounwind readonly uwtable } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree noinline nosync nounwind readnone willreturn uwtable } +; IS__CGSCC____: attributes #[[ATTR4]] = { noinline nounwind uwtable } +; IS__CGSCC____: attributes #[[ATTR5]] = { noreturn } +; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind readnone } +; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind readnone } +; IS__CGSCC____: attributes #[[ATTR9]] = { nofree nosync nounwind readonly } +; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR11]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll index ed802549529a..136d5ec565dc 100644 --- a/llvm/test/Transforms/Attributor/undefined_behavior.ll +++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -74,10 +74,15 @@ define internal i32* @ret_null() { } define void @load_null_propagated() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@load_null_propagated -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@load_null_propagated +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@load_null_propagated +; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-NEXT: ret void ; %ptr = call i32* @ret_null() %a = load i32, i32* %ptr @@ -97,11 +102,17 @@ define void @store_wholly_unreachable() { } define void @store_wholly_unreachable_volatile() { -; CHECK: Function Attrs: nofree norecurse nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile -; CHECK-SAME: () #[[ATTR2:[0-9]+]] { -; CHECK-NEXT: store volatile i32 5, i32* null, align 4294967296 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile +; IS__TUNIT____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__TUNIT____-NEXT: store volatile i32 5, i32* null, align 4294967296 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile +; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-NEXT: store volatile i32 5, i32* null, align 4294967296 +; IS__CGSCC____-NEXT: ret void ; store volatile i32 5, i32* null ret void @@ -126,11 +137,17 @@ e: } define void @store_null_pointer_is_defined() null_pointer_is_valid { -; CHECK: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@store_null_pointer_is_defined -; CHECK-SAME: () #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: store i32 5, i32* null, align 4294967296 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined +; IS__TUNIT____-SAME: () #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-NEXT: store i32 5, i32* null, align 4294967296 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined +; IS__CGSCC____-SAME: () #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-NEXT: store i32 5, i32* null, align 4294967296 +; IS__CGSCC____-NEXT: ret void ; store i32 5, i32* null ret void @@ -140,10 +157,16 @@ define void @store_null_propagated() { ; ATTRIBUTOR-LABEL: @store_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@store_null_propagated -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_propagated +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_propagated +; IS__CGSCC____-SAME: () #[[ATTR5:[0-9]+]] { +; IS__CGSCC____-NEXT: [[PTR:%.*]] = call noalias align 4294967296 i32* @ret_null() #[[ATTR10:[0-9]+]] +; IS__CGSCC____-NEXT: ret void ; %ptr = call i32* @ret_null() store i32 5, i32* %ptr @@ -153,24 +176,38 @@ define void @store_null_propagated() { ; -- AtomicRMW tests -- define void @atomicrmw_wholly_unreachable() { -; CHECK: Function Attrs: nofree norecurse nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable -; CHECK-SAME: () #[[ATTR2]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable +; IS__TUNIT____-SAME: () #[[ATTR2]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable +; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-NEXT: unreachable ; %a = atomicrmw add i32* null, i32 1 acquire ret void } define void @atomicrmw_single_bb_unreachable(i1 %cond) { -; CHECK: Function Attrs: nofree norecurse nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable -; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] -; CHECK: t: -; CHECK-NEXT: unreachable -; CHECK: e: -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable +; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: e: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable +; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: e: +; IS__CGSCC____-NEXT: ret void ; br i1 %cond, label %t, label %e t: @@ -181,11 +218,17 @@ e: } define void @atomicrmw_null_pointer_is_defined() null_pointer_is_valid { -; CHECK: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn -; CHECK-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined -; CHECK-SAME: () #[[ATTR4:[0-9]+]] { -; CHECK-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire, align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined +; IS__TUNIT____-SAME: () #[[ATTR4:[0-9]+]] { +; IS__TUNIT____-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire, align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined +; IS__CGSCC____-SAME: () #[[ATTR6:[0-9]+]] { +; IS__CGSCC____-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire, align 4 +; IS__CGSCC____-NEXT: ret void ; %a = atomicrmw add i32* null, i32 1 acquire ret void @@ -195,10 +238,17 @@ define void @atomicrmw_null_propagated() { ; ATTRIBUTOR-LABEL: @atomicrmw_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; -; CHECK: Function Attrs: nofree norecurse nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@atomicrmw_null_propagated -; CHECK-SAME: () #[[ATTR2]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated +; IS__TUNIT____-SAME: () #[[ATTR2]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated +; IS__CGSCC____-SAME: () #[[ATTR7:[0-9]+]] { +; IS__CGSCC____-NEXT: [[PTR:%.*]] = call noalias i32* @ret_null() #[[ATTR10]] +; IS__CGSCC____-NEXT: [[A:%.*]] = atomicrmw add i32* [[PTR]], i32 1 acquire, align 4 +; IS__CGSCC____-NEXT: ret void ; %ptr = call i32* @ret_null() %a = atomicrmw add i32* %ptr, i32 1 acquire @@ -208,24 +258,38 @@ define void @atomicrmw_null_propagated() { ; -- AtomicCmpXchg tests -- define void @atomiccmpxchg_wholly_unreachable() { -; CHECK: Function Attrs: nofree norecurse nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable -; CHECK-SAME: () #[[ATTR2]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable +; IS__TUNIT____-SAME: () #[[ATTR2]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable +; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-NEXT: unreachable ; %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic ret void } define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) { -; CHECK: Function Attrs: nofree norecurse nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable -; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] -; CHECK: t: -; CHECK-NEXT: unreachable -; CHECK: e: -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable +; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: e: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable +; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: e: +; IS__CGSCC____-NEXT: ret void ; br i1 %cond, label %t, label %e t: @@ -236,11 +300,17 @@ e: } define void @atomiccmpxchg_null_pointer_is_defined() null_pointer_is_valid { -; CHECK: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn -; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined -; CHECK-SAME: () #[[ATTR4]] { -; CHECK-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic, align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined +; IS__TUNIT____-SAME: () #[[ATTR4]] { +; IS__TUNIT____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic, align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined +; IS__CGSCC____-SAME: () #[[ATTR6]] { +; IS__CGSCC____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic, align 4 +; IS__CGSCC____-NEXT: ret void ; %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic ret void @@ -250,10 +320,17 @@ define void @atomiccmpxchg_null_propagated() { ; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; -; CHECK: Function Attrs: nofree norecurse nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated -; CHECK-SAME: () #[[ATTR2]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated +; IS__TUNIT____-SAME: () #[[ATTR2]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated +; IS__CGSCC____-SAME: () #[[ATTR7]] { +; IS__CGSCC____-NEXT: [[PTR:%.*]] = call noalias i32* @ret_null() #[[ATTR10]] +; IS__CGSCC____-NEXT: [[A:%.*]] = cmpxchg i32* [[PTR]], i32 2, i32 3 acq_rel monotonic, align 4 +; IS__CGSCC____-NEXT: ret void ; %ptr = call i32* @ret_null() %a = cmpxchg i32* %ptr, i32 2, i32 3 acq_rel monotonic @@ -265,14 +342,23 @@ define void @atomiccmpxchg_null_propagated() { ; Note: The unreachable on %t and %e is _not_ from AAUndefinedBehavior define i32 @cond_br_on_undef() { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef -; CHECK-SAME: () #[[ATTR5:[0-9]+]] { -; CHECK-NEXT: unreachable -; CHECK: t: -; CHECK-NEXT: unreachable -; CHECK: e: -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef +; IS__TUNIT____-SAME: () #[[ATTR5:[0-9]+]] { +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: e: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef +; IS__CGSCC____-SAME: () #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: e: +; IS__CGSCC____-NEXT: unreachable ; br i1 undef, label %t, label %e t: @@ -319,14 +405,24 @@ define i1 @ret_undef() { } define void @cond_br_on_undef_interproc() { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc -; CHECK-SAME: () #[[ATTR5]] { -; CHECK-NEXT: unreachable -; CHECK: t: -; CHECK-NEXT: unreachable -; CHECK: e: -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc +; IS__TUNIT____-SAME: () #[[ATTR5]] { +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: e: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[COND:%.*]] = call i1 @ret_undef() #[[ATTR10]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: ret void +; IS__CGSCC____: e: +; IS__CGSCC____-NEXT: ret void ; %cond = call i1 @ret_undef() br i1 %cond, label %t, label %e @@ -355,14 +451,24 @@ e: ; More complicated interproc deduction of undef define void @cond_br_on_undef_interproc2() { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 -; CHECK-SAME: () #[[ATTR5]] { -; CHECK-NEXT: unreachable -; CHECK: t: -; CHECK-NEXT: unreachable -; CHECK: e: -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 +; IS__TUNIT____-SAME: () #[[ATTR5]] { +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: e: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[COND:%.*]] = call i1 @ret_undef2() #[[ATTR10]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: ret void +; IS__CGSCC____: e: +; IS__CGSCC____-NEXT: ret void ; %cond = call i1 @ret_undef2() br i1 %cond, label %t, label %e @@ -395,14 +501,23 @@ e: ; Branch on undef because of uninitialized value. ; FIXME: Currently it doesn't propagate the undef. define i32 @cond_br_on_undef_uninit() { -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit -; CHECK-SAME: () #[[ATTR5]] { -; CHECK-NEXT: unreachable -; CHECK: t: -; CHECK-NEXT: unreachable -; CHECK: e: -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit +; IS__TUNIT____-SAME: () #[[ATTR5]] { +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: e: +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit +; IS__CGSCC____-SAME: () #[[ATTR8]] { +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: e: +; IS__CGSCC____-NEXT: unreachable ; %alloc = alloca i1 %cond = load i1, i1* %alloc @@ -441,10 +556,16 @@ F: } define i32 @foo() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: ret i32 1 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32 1 +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[X:%.*]] = call noundef i32 @callee() #[[ATTR10]] +; IS__CGSCC____-NEXT: ret i32 [[X]] ; %X = call i32 @callee(i1 false, i32* null) ret i32 %X @@ -455,41 +576,67 @@ define i32 @foo() { ; Tests for argument position define void @arg_nonnull_1(i32* nonnull %a) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@arg_nonnull_1 -; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { -; CHECK-NEXT: store i32 0, i32* [[A]], align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_1 +; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_1 +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: ret void ; store i32 0, i32* %a ret void } define void @arg_nonnull_1_noundef_1(i32* nonnull noundef %a) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 -; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6]] { -; CHECK-NEXT: store i32 0, i32* [[A]], align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 +; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6]] { +; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: ret void ; store i32 0, i32* %a ret void } define void @arg_nonnull_12(i32* nonnull %a, i32* nonnull %b, i32* %c) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@arg_nonnull_12 -; CHECK-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { -; CHECK-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null -; CHECK-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i32 0, i32* [[A]], align 4 -; CHECK-NEXT: br label [[RET:%.*]] -; CHECK: f: -; CHECK-NEXT: store i32 1, i32* [[B]], align 4 -; CHECK-NEXT: br label [[RET]] -; CHECK: ret: -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_12 +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { +; IS__TUNIT____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null +; IS__TUNIT____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: br label [[RET:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i32 1, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: br label [[RET]] +; IS__TUNIT____: ret: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_12 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null +; IS__CGSCC____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: br label [[RET:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i32 1, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: br label [[RET]] +; IS__CGSCC____: ret: +; IS__CGSCC____-NEXT: ret void ; %d = icmp eq i32* %c, null br i1 %d, label %t, label %f @@ -504,19 +651,33 @@ ret: } define void @arg_nonnull_12_noundef_2(i32* nonnull %a, i32* noundef nonnull %b, i32* %c) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 -; CHECK-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { -; CHECK-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null -; CHECK-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i32 0, i32* [[A]], align 4 -; CHECK-NEXT: br label [[RET:%.*]] -; CHECK: f: -; CHECK-NEXT: store i32 1, i32* [[B]], align 4 -; CHECK-NEXT: br label [[RET]] -; CHECK: ret: -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { +; IS__TUNIT____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null +; IS__TUNIT____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: br label [[RET:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i32 1, i32* [[B]], align 4 +; IS__TUNIT____-NEXT: br label [[RET]] +; IS__TUNIT____: ret: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null +; IS__CGSCC____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: br label [[RET:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i32 1, i32* [[B]], align 4 +; IS__CGSCC____-NEXT: br label [[RET]] +; IS__CGSCC____: ret: +; IS__CGSCC____-NEXT: ret void ; %d = icmp eq i32* %c, null br i1 %d, label %t, label %f @@ -532,20 +693,30 @@ ret: ; Pass null directly to argument with nonnull attribute define void @arg_nonnull_violation1_1() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1 -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1 +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1 +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: unreachable ; call void @arg_nonnull_1(i32* null) ret void } define void @arg_nonnull_violation1_2() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2 -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2 +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2 +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: unreachable ; call void @arg_nonnull_1_noundef_1(i32* null) ret void @@ -553,10 +724,15 @@ define void @arg_nonnull_violation1_2() { ; A case that depends on value simplification define void @arg_nonnull_violation2_1(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1 +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC____-NEXT: unreachable ; %null = getelementptr i32, i32* null, i32 0 %mustnull = select i1 %c, i32* null, i32* %null @@ -565,10 +741,15 @@ define void @arg_nonnull_violation2_1(i1 %c) { } define void @arg_nonnull_violation2_2(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: unreachable +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: unreachable +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2 +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC____-NEXT: unreachable ; %null = getelementptr i32, i32* null, i32 0 %mustnull = select i1 %c, i32* null, i32* %null @@ -592,14 +773,14 @@ define void @arg_nonnull_violation3_1(i1 %c) { ; IS__TUNIT____: ret: ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR8:[0-9]+]] -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR8]] +; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR11:[0-9]+]] +; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR11]] ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable @@ -639,14 +820,14 @@ define void @arg_nonnull_violation3_2(i1 %c) { ; IS__TUNIT____: ret: ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR8]] -; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR8]] +; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR11]] +; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR11]] ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable @@ -794,10 +975,15 @@ define i32 @argument_noundef1(i32 noundef %c) { } define i32 @violate_noundef_nonpointer() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@violate_noundef_nonpointer -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: ret i32 undef +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32 undef +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: ret i32 undef ; %ret = call i32 @argument_noundef1(i32 undef) ret i32 %ret @@ -813,10 +999,15 @@ define i32* @argument_noundef2(i32* noundef %c) { } define i32* @violate_noundef_pointer() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@violate_noundef_pointer -; CHECK-SAME: () #[[ATTR0]] { -; CHECK-NEXT: ret i32* undef +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_pointer +; IS__TUNIT____-SAME: () #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32* undef +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_pointer +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: ret i32* undef ; %ret = call i32* @argument_noundef2(i32* undef) ret i32* %ret @@ -825,7 +1016,7 @@ define i32* @violate_noundef_pointer() { define internal noundef i32 @assumed_undef_is_ok(i1 %c, i32 %arg) { ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@assumed_undef_is_ok -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[REC:%.*]], label [[RET:%.*]] ; IS__CGSCC____: rec: ; IS__CGSCC____-NEXT: br label [[RET]] @@ -845,10 +1036,16 @@ ret: } define noundef i32 @assumed_undef_is_ok_caller(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @assumed_undef_is_ok(i1 [[C]]) #[[ATTR10]] +; IS__CGSCC____-NEXT: ret i32 [[CALL]] ; %call = call i32 @assumed_undef_is_ok(i1 %c, i32 undef) ret i32 %call @@ -866,11 +1063,14 @@ define noundef i32 @assumed_undef_is_ok_caller(i1 %c) { ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR4]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } -; IS__CGSCC____: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR6]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } +; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR10]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR11]] = { nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/value-simplify-assume.ll b/llvm/test/Transforms/Attributor/value-simplify-assume.ll index a6ee9be67226..c3e3ca6cf64d 100644 --- a/llvm/test/Transforms/Attributor/value-simplify-assume.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-assume.ll @@ -39,11 +39,17 @@ define i1 @keep_assume_1c_nr() norecurse { } define i1 @drop_assume_1c_nr() norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@drop_assume_1c_nr -; CHECK-SAME: () #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR4:[0-9]+]] -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@drop_assume_1c_nr +; IS__TUNIT____-SAME: () #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR4:[0-9]+]] +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@drop_assume_1c_nr +; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR5:[0-9]+]] +; IS__CGSCC____-NEXT: ret i1 true ; %stack = alloca i1 store i1 true, i1* %stack @@ -76,15 +82,25 @@ define i1 @keep_assume_2c_nr() norecurse { } define i1 @keep_assume_3c_nr() norecurse { -; CHECK: Function Attrs: norecurse -; CHECK-LABEL: define {{[^@]+}}@keep_assume_3c_nr -; CHECK-SAME: () #[[ATTR2]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) -; CHECK-NEXT: ret i1 [[L]] +; IS__TUNIT____: Function Attrs: norecurse +; IS__TUNIT____-LABEL: define {{[^@]+}}@keep_assume_3c_nr +; IS__TUNIT____-SAME: () #[[ATTR2]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) +; IS__TUNIT____-NEXT: ret i1 [[L]] +; +; IS__CGSCC____: Function Attrs: norecurse +; IS__CGSCC____-LABEL: define {{[^@]+}}@keep_assume_3c_nr +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) +; IS__CGSCC____-NEXT: ret i1 [[L]] ; %stack = alloca i1 store i1 true, i1* %stack @@ -94,15 +110,25 @@ define i1 @keep_assume_3c_nr() norecurse { ret i1 %l } define i1 @keep_assume_4c_nr() norecurse { -; CHECK: Function Attrs: norecurse -; CHECK-LABEL: define {{[^@]+}}@keep_assume_4c_nr -; CHECK-SAME: () #[[ATTR2]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] -; CHECK-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) -; CHECK-NEXT: ret i1 [[L4]] +; IS__TUNIT____: Function Attrs: norecurse +; IS__TUNIT____-LABEL: define {{[^@]+}}@keep_assume_4c_nr +; IS__TUNIT____-SAME: () #[[ATTR2]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) +; IS__TUNIT____-NEXT: ret i1 [[L4]] +; +; IS__CGSCC____: Function Attrs: norecurse +; IS__CGSCC____-LABEL: define {{[^@]+}}@keep_assume_4c_nr +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) +; IS__CGSCC____-NEXT: ret i1 [[L4]] ; %stack = alloca i1 store i1 true, i1* %stack @@ -132,13 +158,21 @@ define i1 @keep_assume_1_nr(i1 %arg) norecurse { } define i1 @drop_assume_1_nr(i1 %arg) norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@drop_assume_1_nr -; CHECK-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]] -; CHECK-NEXT: ret i1 [[ARG]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@drop_assume_1_nr +; IS__TUNIT____-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret i1 [[ARG]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@drop_assume_1_nr +; IS__CGSCC____-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: ret i1 [[ARG]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -171,15 +205,25 @@ define i1 @keep_assume_2_nr(i1 %arg) norecurse { } define i1 @keep_assume_3_nr(i1 %arg) norecurse { -; CHECK: Function Attrs: norecurse -; CHECK-LABEL: define {{[^@]+}}@keep_assume_3_nr -; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) -; CHECK-NEXT: ret i1 [[L]] +; IS__TUNIT____: Function Attrs: norecurse +; IS__TUNIT____-LABEL: define {{[^@]+}}@keep_assume_3_nr +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) +; IS__TUNIT____-NEXT: ret i1 [[L]] +; +; IS__CGSCC____: Function Attrs: norecurse +; IS__CGSCC____-LABEL: define {{[^@]+}}@keep_assume_3_nr +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) +; IS__CGSCC____-NEXT: ret i1 [[L]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -190,15 +234,25 @@ define i1 @keep_assume_3_nr(i1 %arg) norecurse { } define i1 @keep_assume_4_nr(i1 %arg) norecurse { -; CHECK: Function Attrs: norecurse -; CHECK-LABEL: define {{[^@]+}}@keep_assume_4_nr -; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) -; CHECK-NEXT: ret i1 [[L]] +; IS__TUNIT____: Function Attrs: norecurse +; IS__TUNIT____-LABEL: define {{[^@]+}}@keep_assume_4_nr +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) +; IS__TUNIT____-NEXT: ret i1 [[L]] +; +; IS__CGSCC____: Function Attrs: norecurse +; IS__CGSCC____-LABEL: define {{[^@]+}}@keep_assume_4_nr +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) +; IS__CGSCC____-NEXT: ret i1 [[L]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -209,19 +263,33 @@ define i1 @keep_assume_4_nr(i1 %arg) norecurse { } define i1 @assume_1_nr(i1 %arg, i1 %cond) norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_1_nr -; CHECK-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: ret i1 [[ARG]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_1_nr +; IS__TUNIT____-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: ret i1 [[ARG]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_1_nr +; IS__CGSCC____-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: ret i1 [[ARG]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -239,20 +307,35 @@ m: } define void @assume_1b_nr(i1 %arg, i1 %cond) norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_1b_nr -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_1b_nr +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_1b_nr +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: ret void ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -270,22 +353,39 @@ m: } define i1 @assume_2_nr(i1 %arg, i1 %cond) norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_2_nr -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: ret i1 [[L]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_2_nr +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret i1 [[L]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_2_nr +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: ret i1 [[L]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -303,22 +403,39 @@ m: } define void @assume_2b_nr(i1 %arg, i1 %cond) norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_2b_nr -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_2b_nr +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_2b_nr +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: ret void ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -336,23 +453,41 @@ m: } define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_3_nr -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5:[0-9]+]] -; CHECK-NEXT: ret i1 [[R]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_3_nr +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5:[0-9]+]] +; IS__TUNIT____-NEXT: ret i1 [[R]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_3_nr +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6:[0-9]+]] +; IS__CGSCC____-NEXT: ret i1 [[R]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -371,23 +506,41 @@ m: } define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_4_nr -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] -; CHECK-NEXT: ret i1 [[R]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_4_nr +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] +; IS__TUNIT____-NEXT: ret i1 [[R]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_4_nr +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; IS__CGSCC____-NEXT: ret i1 [[R]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -406,29 +559,53 @@ m: } define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_5_nr -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]] -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]] -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] -; CHECK-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] -; CHECK-NEXT: ret i1 [[R]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_5_nr +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] +; IS__TUNIT____-NEXT: ret i1 [[R]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_5_nr +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; IS__CGSCC____-NEXT: ret i1 [[R]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -453,29 +630,53 @@ m: } define i1 @assume_5c_nr(i1 %cond) norecurse { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_5c_nr -; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]] -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]] -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] -; CHECK-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] -; CHECK-NEXT: ret i1 [[R]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_5c_nr +; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] +; IS__TUNIT____-NEXT: ret i1 [[R]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_5c_nr +; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; IS__CGSCC____-NEXT: ret i1 [[R]] ; %stack = alloca i1 store i1 true, i1* %stack @@ -518,11 +719,17 @@ define i1 @keep_assume_1c() { } define i1 @drop_assume_1c() { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@drop_assume_1c -; CHECK-SAME: () #[[ATTR3]] { -; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR4]] -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@drop_assume_1c +; IS__TUNIT____-SAME: () #[[ATTR3]] { +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@drop_assume_1c +; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR5]] +; IS__CGSCC____-NEXT: ret i1 true ; %stack = alloca i1 store i1 true, i1* %stack @@ -553,13 +760,21 @@ define i1 @keep_assume_2c() { } define i1 @keep_assume_3c() { -; CHECK-LABEL: define {{[^@]+}}@keep_assume_3c() { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) -; CHECK-NEXT: ret i1 [[L]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@keep_assume_3c() { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) +; IS__TUNIT____-NEXT: ret i1 [[L]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@keep_assume_3c() { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) +; IS__CGSCC____-NEXT: ret i1 [[L]] ; %stack = alloca i1 store i1 true, i1* %stack @@ -569,13 +784,21 @@ define i1 @keep_assume_3c() { ret i1 %l } define i1 @keep_assume_4c() { -; CHECK-LABEL: define {{[^@]+}}@keep_assume_4c() { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] -; CHECK-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) -; CHECK-NEXT: ret i1 [[L4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@keep_assume_4c() { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) +; IS__TUNIT____-NEXT: ret i1 [[L4]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@keep_assume_4c() { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) +; IS__CGSCC____-NEXT: ret i1 [[L4]] ; %stack = alloca i1 store i1 true, i1* %stack @@ -604,8 +827,21 @@ define i1 @keep_assume_1(i1 %arg) { } define i1 @drop_assume_1(i1 %arg) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@drop_assume_1 +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@drop_assume_1 +; IS__TUNIT____-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret i1 [[ARG]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@drop_assume_1 +; IS__CGSCC____-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: ret i1 [[ARG]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -637,14 +873,23 @@ define i1 @keep_assume_2(i1 %arg) { } define i1 @keep_assume_3(i1 %arg) { -; CHECK-LABEL: define {{[^@]+}}@keep_assume_3 -; CHECK-SAME: (i1 [[ARG:%.*]]) { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) -; CHECK-NEXT: ret i1 [[L]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@keep_assume_3 +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]]) { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) +; IS__TUNIT____-NEXT: ret i1 [[L]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@keep_assume_3 +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]]) { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]]) +; IS__CGSCC____-NEXT: ret i1 [[L]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -655,14 +900,23 @@ define i1 @keep_assume_3(i1 %arg) { } define i1 @keep_assume_4(i1 %arg) { -; CHECK-LABEL: define {{[^@]+}}@keep_assume_4 -; CHECK-SAME: (i1 [[ARG:%.*]]) { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) -; CHECK-NEXT: ret i1 [[L]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@keep_assume_4 +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]]) { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) +; IS__TUNIT____-NEXT: ret i1 [[L]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@keep_assume_4 +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]]) { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]]) +; IS__CGSCC____-NEXT: ret i1 [[L]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -673,19 +927,33 @@ define i1 @keep_assume_4(i1 %arg) { } define i1 @assume_1(i1 %arg, i1 %cond) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_1 -; CHECK-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: ret i1 [[ARG]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_1 +; IS__TUNIT____-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: ret i1 [[ARG]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_1 +; IS__CGSCC____-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: ret i1 [[ARG]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -703,20 +971,35 @@ m: } define void @assume_1b(i1 %arg, i1 %cond) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_1b -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_1b +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_1b +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: ret void ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -734,22 +1017,39 @@ m: } define i1 @assume_2(i1 %arg, i1 %cond) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_2 -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: ret i1 [[L]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_2 +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret i1 [[L]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_2 +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: ret i1 [[L]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -767,22 +1067,39 @@ m: } define void @assume_2b(i1 %arg, i1 %cond) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_2b -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_2b +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_2b +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: ret void ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -800,23 +1117,41 @@ m: } define i1 @assume_3(i1 %arg, i1 %cond) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_3 -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] -; CHECK-NEXT: ret i1 [[R]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_3 +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] +; IS__TUNIT____-NEXT: ret i1 [[R]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_3 +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; IS__CGSCC____-NEXT: ret i1 [[R]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -835,23 +1170,41 @@ m: } define i1 @assume_4(i1 %arg, i1 %cond) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_4 -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] -; CHECK-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] -; CHECK-NEXT: ret i1 [[R]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_4 +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] +; IS__TUNIT____-NEXT: ret i1 [[R]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_4 +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; IS__CGSCC____-NEXT: ret i1 [[R]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -870,29 +1223,53 @@ m: } define i1 @assume_5(i1 %arg, i1 %cond) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_5 -; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 -; CHECK-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]] -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]] -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] -; CHECK-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] -; CHECK-NEXT: ret i1 [[R]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_5 +; IS__TUNIT____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] +; IS__TUNIT____-NEXT: ret i1 [[R]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_5 +; IS__CGSCC____-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; IS__CGSCC____-NEXT: ret i1 [[R]] ; %stack = alloca i1 store i1 %arg, i1* %stack @@ -917,29 +1294,53 @@ m: } define i1 @assume_5c(i1 %cond) { -; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn -; CHECK-LABEL: define {{[^@]+}}@assume_5c -; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1 -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]] -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i1 true, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]] -; CHECK-NEXT: br label [[M:%.*]] -; CHECK: f: -; CHECK-NEXT: store i1 false, i1* [[STACK]], align 1 -; CHECK-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]] -; CHECK-NEXT: br label [[M]] -; CHECK: m: -; CHECK-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 -; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] -; CHECK-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] -; CHECK-NEXT: ret i1 [[R]] +; IS__TUNIT____: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@assume_5c +; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br label [[M:%.*]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: br label [[M]] +; IS__TUNIT____: m: +; IS__TUNIT____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]] +; IS__TUNIT____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]] +; IS__TUNIT____-NEXT: ret i1 [[R]] +; +; IS__CGSCC____: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@assume_5c +; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: [[STACK:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i1 true, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br label [[M:%.*]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1 false, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: br label [[M]] +; IS__CGSCC____: m: +; IS__CGSCC____-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1 +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR6]] +; IS__CGSCC____-NEXT: ret i1 [[R]] ; %stack = alloca i1 store i1 true, i1* %stack @@ -975,6 +1376,7 @@ m: ; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { norecurse } ; IS__CGSCC____: attributes #[[ATTR3]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR4]] = { willreturn } -; IS__CGSCC____: attributes #[[ATTR5]] = { readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR4]] = { inaccessiblememonly nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR5]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR6]] = { readonly willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/value-simplify-gpu.ll b/llvm/test/Transforms/Attributor/value-simplify-gpu.ll index df674920df0d..fa19fe63622d 100644 --- a/llvm/test/Transforms/Attributor/value-simplify-gpu.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-gpu.ll @@ -18,12 +18,19 @@ target triple = "amdgcn-amd-amdhsa" ; CHECK: @[[UNREACHABLENONKERNEL:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 0, align 4 ;. define dso_local void @kernel(i32 %C) norecurse "kernel" { -; CHECK: Function Attrs: norecurse nosync nounwind -; CHECK-LABEL: define {{[^@]+}}@kernel -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @level1Kernel(i32 [[C]]) #[[ATTR3:[0-9]+]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: norecurse nosync nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@kernel +; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: call void @level1Kernel(i32 [[C]]) #[[ATTR3:[0-9]+]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: norecurse nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@kernel +; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: call void @level1Kernel(i32 [[C]]) #[[ATTR4:[0-9]+]] +; IS__CGSCC____-NEXT: ret void ; entry: call void @level1Kernel(i32 %C) @@ -52,16 +59,17 @@ define internal void @level1Kernel(i32 %C) { ; IS__CGSCC____-LABEL: define {{[^@]+}}@level1Kernel ; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: call void @level2Kernelall_early() #[[ATTR4:[0-9]+]] +; IS__CGSCC____-NEXT: call void @level2Kernelall_early() #[[ATTR5:[0-9]+]] ; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0 ; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; IS__CGSCC____: if.then: -; IS__CGSCC____-NEXT: call void @level2Kernela() #[[ATTR3]] +; IS__CGSCC____-NEXT: call void @level2Kernela() #[[ATTR4]] ; IS__CGSCC____-NEXT: br label [[IF_END:%.*]] ; IS__CGSCC____: if.else: -; IS__CGSCC____-NEXT: call void @level2Kernelb() #[[ATTR3]] +; IS__CGSCC____-NEXT: call void @level2Kernelb() #[[ATTR4]] ; IS__CGSCC____-NEXT: br label [[IF_END]] ; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: call void @level2Kernelall_late() #[[ATTR6:[0-9]+]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -107,14 +115,14 @@ define internal void @level2Kernela() { ; IS__TUNIT____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR6:[0-9]+]] ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: norecurse nosync nounwind +; IS__CGSCC____: Function Attrs: nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@level2Kernela -; IS__CGSCC____-SAME: () #[[ATTR1]] { +; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4 ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4 ; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4 -; IS__CGSCC____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR4]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -135,14 +143,14 @@ define internal void @level2Kernelb() { ; IS__TUNIT____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR6]] ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: norecurse nosync nounwind +; IS__CGSCC____: Function Attrs: nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@level2Kernelb -; IS__CGSCC____-SAME: () #[[ATTR1]] { +; IS__CGSCC____-SAME: () #[[ATTR3]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4 ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4 ; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4 -; IS__CGSCC____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR3]] +; IS__CGSCC____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR4]] ; IS__CGSCC____-NEXT: ret void ; entry: @@ -154,11 +162,18 @@ entry: } define internal void @level2Kernelall_late() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@level2Kernelall_late -; CHECK-SAME: () #[[ATTR2]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@level2Kernelall_late +; IS__TUNIT____-SAME: () #[[ATTR2]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@level2Kernelall_late +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4 +; IS__CGSCC____-NEXT: ret void ; entry: store i32 1, i32 *addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4 @@ -169,12 +184,19 @@ entry: @UnreachableNonKernel = internal addrspace(3) global i32 0, align 4 define dso_local void @non_kernel(i32 %C) norecurse { -; CHECK: Function Attrs: norecurse nosync nounwind -; CHECK-LABEL: define {{[^@]+}}@non_kernel -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR1:[0-9]+]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @level1(i32 [[C]]) #[[ATTR3]] -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: norecurse nosync nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@non_kernel +; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: call void @level1(i32 [[C]]) #[[ATTR3]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: norecurse nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@non_kernel +; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: call void @level1(i32 [[C]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: ret void ; entry: call void @level1(i32 %C) @@ -200,41 +222,23 @@ define internal void @level1(i32 %C) { ; IS__TUNIT____-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR5]] ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: norecurse nosync nounwind -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@level1 -; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[LOCAL:%.*]] = alloca i32, align 4 -; IS__CGSCC_OPM-NEXT: call void @level2all_early(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]] -; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0 -; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] -; IS__CGSCC_OPM: if.then: -; IS__CGSCC_OPM-NEXT: call void @level2a(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: br label [[IF_END:%.*]] -; IS__CGSCC_OPM: if.else: -; IS__CGSCC_OPM-NEXT: call void @level2b(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: br label [[IF_END]] -; IS__CGSCC_OPM: if.end: -; IS__CGSCC_OPM-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR5:[0-9]+]] -; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: norecurse nosync nounwind -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@level1 -; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[LOCAL:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: call void @level2all_early(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]] -; IS__CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0 -; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] -; IS__CGSCC_NPM: if.then: -; IS__CGSCC_NPM-NEXT: call void @level2a(i32 noundef 17) #[[ATTR3]] -; IS__CGSCC_NPM-NEXT: br label [[IF_END:%.*]] -; IS__CGSCC_NPM: if.else: -; IS__CGSCC_NPM-NEXT: call void @level2b(i32 17) #[[ATTR3]] -; IS__CGSCC_NPM-NEXT: br label [[IF_END]] -; IS__CGSCC_NPM: if.end: -; IS__CGSCC_NPM-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR5:[0-9]+]] -; IS__CGSCC_NPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: norecurse nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@level1 +; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[LOCAL:%.*]] = alloca i32, align 4 +; IS__CGSCC____-NEXT: call void @level2all_early(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR5]] +; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0 +; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; IS__CGSCC____: if.then: +; IS__CGSCC____-NEXT: call void @level2a(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: br label [[IF_END:%.*]] +; IS__CGSCC____: if.else: +; IS__CGSCC____-NEXT: call void @level2b(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: br label [[IF_END]] +; IS__CGSCC____: if.end: +; IS__CGSCC____-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR6]] +; IS__CGSCC____-NEXT: ret void ; entry: %local = alloca i32 @@ -265,7 +269,7 @@ define internal void @level2all_early(i32* %addr) { ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@level2all_early -; IS__CGSCC____-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 ; IS__CGSCC____-NEXT: store i32 17, i32* [[ADDR]], align 4 @@ -287,27 +291,15 @@ define internal void @level2a(i32* %addr) { ; IS__TUNIT____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR6]] ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: norecurse nosync nounwind -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@level2a -; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR1]] { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 -; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4 -; IS__CGSCC_OPM-NEXT: [[QQQQ2:%.*]] = load i32, i32* [[ADDR]], align 4 -; IS__CGSCC_OPM-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[QQQQ2]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: norecurse nosync nounwind -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@level2a -; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[ADDR_PRIV:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[ADDR_PRIV]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 -; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4 -; IS__CGSCC_NPM-NEXT: [[QQQQ2:%.*]] = load i32, i32* [[ADDR_PRIV]], align 4 -; IS__CGSCC_NPM-NEXT: call void @use(i32 noundef [[TMP1]], i32 noundef [[TMP2]], i32 [[QQQQ2]]) #[[ATTR3]] -; IS__CGSCC_NPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@level2a +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4 +; IS__CGSCC____-NEXT: [[QQQQ2:%.*]] = load i32, i32* [[ADDR]], align 4 +; IS__CGSCC____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[QQQQ2]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: ret void ; entry: %0 = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 @@ -327,27 +319,15 @@ define internal void @level2b(i32* %addr) { ; IS__TUNIT____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR6]] ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: norecurse nosync nounwind -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@level2b -; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR1]] { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 -; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4 -; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[ADDR]], align 4 -; IS__CGSCC_OPM-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[TMP2]]) #[[ATTR3]] -; IS__CGSCC_OPM-NEXT: ret void -; -; IS__CGSCC_NPM: Function Attrs: norecurse nosync nounwind -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@level2b -; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { -; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[ADDR_PRIV:%.*]] = alloca i32, align 4 -; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[ADDR_PRIV]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 -; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4 -; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[ADDR_PRIV]], align 4 -; IS__CGSCC_NPM-NEXT: call void @use(i32 noundef [[TMP1]], i32 noundef [[TMP2]], i32 [[TMP3]]) #[[ATTR3]] -; IS__CGSCC_NPM-NEXT: ret void +; IS__CGSCC____: Function Attrs: nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@level2b +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4 +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* [[ADDR]], align 4 +; IS__CGSCC____-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[TMP2]]) #[[ATTR4]] +; IS__CGSCC____-NEXT: ret void ; entry: %0 = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4 @@ -393,7 +373,8 @@ declare dso_local void @use(i32, i32, i32) nosync norecurse nounwind ; IS__CGSCC____: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" } ; IS__CGSCC____: attributes #[[ATTR1]] = { norecurse nosync nounwind } ; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR3]] = { nounwind } -; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR5:[0-9]+]] = { nounwind writeonly } +; IS__CGSCC____: attributes #[[ATTR3]] = { nosync nounwind } +; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR5]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR6]] = { nounwind writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/value-simplify-instances.ll b/llvm/test/Transforms/Attributor/value-simplify-instances.ll index bb1ba258ca29..2b5d40e64d43 100644 --- a/llvm/test/Transforms/Attributor/value-simplify-instances.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-instances.ll @@ -157,10 +157,10 @@ define i1 @recursive_alloca_compare_caller(i1 %c) { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 [[C]], i1* undef) #[[ATTR1]] ; IS__TUNIT____-NEXT: ret i1 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 [[C]], i1* undef) #[[ATTR6:[0-9]+]] +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 [[C]], i1* undef) #[[ATTR4:[0-9]+]] ; IS__CGSCC____-NEXT: ret i1 [[CALL]] ; %call = call i1 @recursive_alloca_compare(i1 %c, i1* undef) @@ -169,19 +169,33 @@ define i1 @recursive_alloca_compare_caller(i1 %c) { ; Make sure we do *not* simplify this to return 0 or 1, return 42 is ok though. define internal i8 @recursive_alloca_load_return(i1 %c, i8* %p, i8 %v) { -; CHECK: Function Attrs: argmemonly nofree nosync nounwind -; CHECK-LABEL: define {{[^@]+}}@recursive_alloca_load_return -; CHECK-SAME: (i1 [[C:%.*]], i8* nocapture nofree nonnull readonly [[P:%.*]], i8 noundef [[V:%.*]]) #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 -; CHECK-NEXT: store i8 [[V]], i8* [[A]], align 1 -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: store i8 0, i8* [[A]], align 1 -; CHECK-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 -; CHECK-NEXT: ret i8 [[L]] -; CHECK: f: -; CHECK-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR4:[0-9]+]] -; CHECK-NEXT: ret i8 [[CALL]] +; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_load_return +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i8* nocapture nofree nonnull readonly [[P:%.*]], i8 noundef [[V:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i8, align 1 +; IS__TUNIT____-NEXT: store i8 [[V]], i8* [[A]], align 1 +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: store i8 0, i8* [[A]], align 1 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 +; IS__TUNIT____-NEXT: ret i8 [[L]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR4:[0-9]+]] +; IS__TUNIT____-NEXT: ret i8 [[CALL]] +; +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_load_return +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i8* nocapture nofree nonnull readonly [[P:%.*]], i8 noundef [[V:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i8, align 1 +; IS__CGSCC____-NEXT: store i8 [[V]], i8* [[A]], align 1 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: store i8 0, i8* [[A]], align 1 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 +; IS__CGSCC____-NEXT: ret i8 [[L]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR3:[0-9]+]] +; IS__CGSCC____-NEXT: ret i8 [[CALL]] ; %a = alloca i8 store i8 %v, i8* %a @@ -202,10 +216,10 @@ define i8 @recursive_alloca_load_return_caller(i1 %c) { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 [[C]], i8* undef, i8 noundef 42) #[[ATTR4]] ; IS__TUNIT____-NEXT: ret i8 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_load_return_caller -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 [[C]], i8* undef, i8 noundef 42) #[[ATTR7:[0-9]+]] +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 [[C]], i8* undef, i8 noundef 42) #[[ATTR5:[0-9]+]] ; IS__CGSCC____-NEXT: ret i8 [[CALL]] ; %call = call i8 @recursive_alloca_load_return(i1 %c, i8* undef, i8 42) @@ -218,19 +232,33 @@ define i8 @recursive_alloca_load_return_caller(i1 %c) { ; Make sure we do *not* return true. define internal i1 @recursive_alloca_compare_global1(i1 %c) { -; CHECK: Function Attrs: nofree nosync nounwind -; CHECK-LABEL: define {{[^@]+}}@recursive_alloca_compare_global1 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { -; CHECK-NEXT: [[A:%.*]] = alloca i1, align 1 -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: [[P:%.*]] = load i1*, i1** @G1, align 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] -; CHECK-NEXT: ret i1 [[CMP]] -; CHECK: f: -; CHECK-NEXT: store i1* [[A]], i1** @G1, align 8 -; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 noundef true) #[[ATTR4]] -; CHECK-NEXT: ret i1 [[CALL]] +; IS__TUNIT____: Function Attrs: nofree nosync nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_compare_global1 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { +; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: [[P:%.*]] = load i1*, i1** @G1, align 8 +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] +; IS__TUNIT____-NEXT: ret i1 [[CMP]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: store i1* [[A]], i1** @G1, align 8 +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 noundef true) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret i1 [[CALL]] +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_global1 +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: [[P:%.*]] = load i1*, i1** @G1, align 8 +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] +; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: store i1* [[A]], i1** @G1, align 8 +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 noundef true) #[[ATTR3]] +; IS__CGSCC____-NEXT: ret i1 [[CALL]] ; %a = alloca i1 br i1 %c, label %t, label %f @@ -252,10 +280,10 @@ define i1 @recursive_alloca_compare_caller_global1(i1 %c) { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 [[C]]) #[[ATTR4]] ; IS__TUNIT____-NEXT: ret i1 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind +; IS__CGSCC____: Function Attrs: nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global1 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR5:[0-9]+]] { -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 [[C]]) #[[ATTR7]] +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 [[C]]) #[[ATTR5]] ; IS__CGSCC____-NEXT: ret i1 [[CALL]] ; %call = call i1 @recursive_alloca_compare_global1(i1 %c) @@ -263,19 +291,33 @@ define i1 @recursive_alloca_compare_caller_global1(i1 %c) { } define internal i1 @recursive_alloca_compare_global2(i1 %c) { -; CHECK: Function Attrs: nofree nosync nounwind -; CHECK-LABEL: define {{[^@]+}}@recursive_alloca_compare_global2 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { -; CHECK-NEXT: [[A:%.*]] = alloca i1, align 1 -; CHECK-NEXT: [[P:%.*]] = load i1*, i1** @G2, align 8 -; CHECK-NEXT: store i1* [[A]], i1** @G2, align 8 -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] -; CHECK-NEXT: ret i1 [[CMP]] -; CHECK: f: -; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 noundef true) #[[ATTR4]] -; CHECK-NEXT: ret i1 [[CALL]] +; IS__TUNIT____: Function Attrs: nofree nosync nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_compare_global2 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { +; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i1, align 1 +; IS__TUNIT____-NEXT: [[P:%.*]] = load i1*, i1** @G2, align 8 +; IS__TUNIT____-NEXT: store i1* [[A]], i1** @G2, align 8 +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] +; IS__TUNIT____-NEXT: ret i1 [[CMP]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 noundef true) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret i1 [[CALL]] +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_global2 +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i1, align 1 +; IS__CGSCC____-NEXT: [[P:%.*]] = load i1*, i1** @G2, align 8 +; IS__CGSCC____-NEXT: store i1* [[A]], i1** @G2, align 8 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] +; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 noundef true) #[[ATTR3]] +; IS__CGSCC____-NEXT: ret i1 [[CALL]] ; %a = alloca i1 %p = load i1*, i1** @G2 @@ -297,10 +339,10 @@ define i1 @recursive_alloca_compare_caller_global2(i1 %c) { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 [[C]]) #[[ATTR4]] ; IS__TUNIT____-NEXT: ret i1 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind +; IS__CGSCC____: Function Attrs: nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global2 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR5]] { -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 [[C]]) #[[ATTR7]] +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 [[C]]) #[[ATTR5]] ; IS__CGSCC____-NEXT: ret i1 [[CALL]] ; %call = call i1 @recursive_alloca_compare_global2(i1 %c) @@ -308,18 +350,31 @@ define i1 @recursive_alloca_compare_caller_global2(i1 %c) { } define internal i1 @recursive_inst_compare_global3(i1 %c) { ; -; CHECK: Function Attrs: nofree nosync nounwind -; CHECK-LABEL: define {{[^@]+}}@recursive_inst_compare_global3 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { -; CHECK-NEXT: [[P:%.*]] = load i1, i1* @G3, align 1 -; CHECK-NEXT: store i1 [[C]], i1* @G3, align 1 -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[C]], [[P]] -; CHECK-NEXT: ret i1 [[CMP]] -; CHECK: f: -; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 noundef true) #[[ATTR4]] -; CHECK-NEXT: ret i1 [[CALL]] +; IS__TUNIT____: Function Attrs: nofree nosync nounwind +; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_inst_compare_global3 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { +; IS__TUNIT____-NEXT: [[P:%.*]] = load i1, i1* @G3, align 1 +; IS__TUNIT____-NEXT: store i1 [[C]], i1* @G3, align 1 +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i1 [[C]], [[P]] +; IS__TUNIT____-NEXT: ret i1 [[CMP]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 noundef true) #[[ATTR4]] +; IS__TUNIT____-NEXT: ret i1 [[CALL]] +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind +; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_inst_compare_global3 +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[P:%.*]] = load i1, i1* @G3, align 1 +; IS__CGSCC____-NEXT: store i1 [[C]], i1* @G3, align 1 +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i1 [[C]], [[P]] +; IS__CGSCC____-NEXT: ret i1 [[CMP]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 noundef true) #[[ATTR3]] +; IS__CGSCC____-NEXT: ret i1 [[CALL]] ; %p = load i1, i1* @G3 store i1 %c, i1* @G3 @@ -340,10 +395,10 @@ define i1 @recursive_inst_compare_caller_global3(i1 %c) { ; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 [[C]]) #[[ATTR4]] ; IS__TUNIT____-NEXT: ret i1 [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind +; IS__CGSCC____: Function Attrs: nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_inst_compare_caller_global3 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR5]] { -; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 [[C]]) #[[ATTR7]] +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 [[C]]) #[[ATTR5]] ; IS__CGSCC____-NEXT: ret i1 [[CALL]] ; %call = call i1 @recursive_inst_compare_global3(i1 %c) @@ -360,10 +415,8 @@ define i1 @recursive_inst_compare_caller_global3(i1 %c) { ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly nofree nosync nounwind } -; IS__CGSCC____: attributes #[[ATTR4]] = { nofree nosync nounwind } -; IS__CGSCC____: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind } -; IS__CGSCC____: attributes #[[ATTR6]] = { nounwind readnone } -; IS__CGSCC____: attributes #[[ATTR7]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR2]] = { argmemonly nofree nosync nounwind } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree nosync nounwind } +; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind readnone } +; IS__CGSCC____: attributes #[[ATTR5]] = { nounwind } ;. diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll index 3bc689b3d55f..7dbec07af97f 100644 --- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll @@ -175,76 +175,114 @@ define void @local_alloca_simplifiable_1(%struct.S* noalias sret(%struct.S) alig ; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR12]] ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@local_alloca_simplifiable_1 ; IS__CGSCC_OPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4 ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR13:[0-9]+]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR15:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 +; IS__CGSCC_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7:![0-9]+]] ; IS__CGSCC_OPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 +; IS__CGSCC_OPM-NEXT: store float 0x40019999A0000000, float* [[F2]], align 4, !tbaa [[TBAA10:![0-9]+]] ; IS__CGSCC_OPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 +; IS__CGSCC_OPM-NEXT: store float 0x400A666660000000, float* [[F3]], align 4, !tbaa [[TBAA11:![0-9]+]] ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR14:[0-9]+]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR16:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR16]] ; IS__CGSCC_OPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR16]] +; IS__CGSCC_OPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 +; IS__CGSCC_OPM-NEXT: [[I4:%.*]] = load float, float* [[F11]], align 4, !tbaa [[TBAA7]] ; IS__CGSCC_OPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 -; IS__CGSCC_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]] -; IS__CGSCC_OPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 +; IS__CGSCC_OPM-NEXT: store float [[I4]], float* [[F12]], align 4, !tbaa [[TBAA7]] +; IS__CGSCC_OPM-NEXT: [[F23:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 +; IS__CGSCC_OPM-NEXT: [[I5:%.*]] = load float, float* [[F23]], align 4, !tbaa [[TBAA10]] +; IS__CGSCC_OPM-NEXT: [[MUL:%.*]] = fmul float [[I5]], 2.000000e+00 ; IS__CGSCC_OPM-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 4 -; IS__CGSCC_OPM-NEXT: store float [[MUL]], float* [[F24]], align 4, !tbaa [[TBAA10:![0-9]+]] -; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = fadd float 0x400A666660000000, 0x3FF19999A0000000 +; IS__CGSCC_OPM-NEXT: store float [[MUL]], float* [[F24]], align 4, !tbaa [[TBAA10]] +; IS__CGSCC_OPM-NEXT: [[F35:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 +; IS__CGSCC_OPM-NEXT: [[I6:%.*]] = load float, float* [[F35]], align 4, !tbaa [[TBAA11]] +; IS__CGSCC_OPM-NEXT: [[F16:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 +; IS__CGSCC_OPM-NEXT: [[I7:%.*]] = load float, float* [[F16]], align 4, !tbaa [[TBAA7]] +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = fadd float [[I6]], [[I7]] ; IS__CGSCC_OPM-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 5 -; IS__CGSCC_OPM-NEXT: store float [[ADD]], float* [[F37]], align 4, !tbaa [[TBAA11:![0-9]+]] +; IS__CGSCC_OPM-NEXT: store float [[ADD]], float* [[F37]], align 4, !tbaa [[TBAA11]] +; IS__CGSCC_OPM-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[I8:%.*]] = load i32, i32* [[I18]], align 4, !tbaa [[TBAA12:![0-9]+]] ; IS__CGSCC_OPM-NEXT: [[I19:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 0 -; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[I19]], align 4, !tbaa [[TBAA12:![0-9]+]] -; IS__CGSCC_OPM-NEXT: [[MUL11:%.*]] = shl nsw i32 2, 1 +; IS__CGSCC_OPM-NEXT: store i32 [[I8]], i32* [[I19]], align 4, !tbaa [[TBAA12]] +; IS__CGSCC_OPM-NEXT: [[I210:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 +; IS__CGSCC_OPM-NEXT: [[I9:%.*]] = load i32, i32* [[I210]], align 4, !tbaa [[TBAA13:![0-9]+]] +; IS__CGSCC_OPM-NEXT: [[MUL11:%.*]] = shl nsw i32 [[I9]], 1 ; IS__CGSCC_OPM-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 1 -; IS__CGSCC_OPM-NEXT: store i32 [[MUL11]], i32* [[I212]], align 4, !tbaa [[TBAA13:![0-9]+]] -; IS__CGSCC_OPM-NEXT: [[ADD15:%.*]] = add nsw i32 3, 1 +; IS__CGSCC_OPM-NEXT: store i32 [[MUL11]], i32* [[I212]], align 4, !tbaa [[TBAA13]] +; IS__CGSCC_OPM-NEXT: [[I313:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 +; IS__CGSCC_OPM-NEXT: [[I10:%.*]] = load i32, i32* [[I313]], align 4, !tbaa [[TBAA14:![0-9]+]] +; IS__CGSCC_OPM-NEXT: [[I114:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[I11:%.*]] = load i32, i32* [[I114]], align 4, !tbaa [[TBAA12]] +; IS__CGSCC_OPM-NEXT: [[ADD15:%.*]] = add nsw i32 [[I10]], [[I11]] ; IS__CGSCC_OPM-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2 -; IS__CGSCC_OPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]] +; IS__CGSCC_OPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14]] ; IS__CGSCC_OPM-NEXT: [[I12:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR15]] ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@local_alloca_simplifiable_1 ; IS__CGSCC_NPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR12:[0-9]+]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I]]) #[[ATTR14:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 +; IS__CGSCC_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7:![0-9]+]] ; IS__CGSCC_NPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 +; IS__CGSCC_NPM-NEXT: store float 0x40019999A0000000, float* [[F2]], align 4, !tbaa [[TBAA10:![0-9]+]] ; IS__CGSCC_NPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 +; IS__CGSCC_NPM-NEXT: store float 0x400A666660000000, float* [[F3]], align 4, !tbaa [[TBAA11:![0-9]+]] ; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR13:[0-9]+]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR15:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR15]] ; IS__CGSCC_NPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 +; IS__CGSCC_NPM-NEXT: [[I4:%.*]] = load float, float* [[F11]], align 4, !tbaa [[TBAA7]] ; IS__CGSCC_NPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 -; IS__CGSCC_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]] -; IS__CGSCC_NPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 +; IS__CGSCC_NPM-NEXT: store float [[I4]], float* [[F12]], align 4, !tbaa [[TBAA7]] +; IS__CGSCC_NPM-NEXT: [[F23:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 4 +; IS__CGSCC_NPM-NEXT: [[I5:%.*]] = load float, float* [[F23]], align 4, !tbaa [[TBAA10]] +; IS__CGSCC_NPM-NEXT: [[MUL:%.*]] = fmul float [[I5]], 2.000000e+00 ; IS__CGSCC_NPM-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 4 -; IS__CGSCC_NPM-NEXT: store float [[MUL]], float* [[F24]], align 4, !tbaa [[TBAA10:![0-9]+]] -; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = fadd float 0x400A666660000000, 0x3FF19999A0000000 +; IS__CGSCC_NPM-NEXT: store float [[MUL]], float* [[F24]], align 4, !tbaa [[TBAA10]] +; IS__CGSCC_NPM-NEXT: [[F35:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 +; IS__CGSCC_NPM-NEXT: [[I6:%.*]] = load float, float* [[F35]], align 4, !tbaa [[TBAA11]] +; IS__CGSCC_NPM-NEXT: [[F16:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 +; IS__CGSCC_NPM-NEXT: [[I7:%.*]] = load float, float* [[F16]], align 4, !tbaa [[TBAA7]] +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = fadd float [[I6]], [[I7]] ; IS__CGSCC_NPM-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 5 -; IS__CGSCC_NPM-NEXT: store float [[ADD]], float* [[F37]], align 4, !tbaa [[TBAA11:![0-9]+]] +; IS__CGSCC_NPM-NEXT: store float [[ADD]], float* [[F37]], align 4, !tbaa [[TBAA11]] +; IS__CGSCC_NPM-NEXT: [[I18:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 +; IS__CGSCC_NPM-NEXT: [[I8:%.*]] = load i32, i32* [[I18]], align 4, !tbaa [[TBAA12:![0-9]+]] ; IS__CGSCC_NPM-NEXT: [[I19:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 0 -; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[I19]], align 4, !tbaa [[TBAA12:![0-9]+]] -; IS__CGSCC_NPM-NEXT: [[MUL11:%.*]] = shl nsw i32 2, 1 +; IS__CGSCC_NPM-NEXT: store i32 [[I8]], i32* [[I19]], align 4, !tbaa [[TBAA12]] +; IS__CGSCC_NPM-NEXT: [[I210:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[I9:%.*]] = load i32, i32* [[I210]], align 4, !tbaa [[TBAA13:![0-9]+]] +; IS__CGSCC_NPM-NEXT: [[MUL11:%.*]] = shl nsw i32 [[I9]], 1 ; IS__CGSCC_NPM-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 1 -; IS__CGSCC_NPM-NEXT: store i32 [[MUL11]], i32* [[I212]], align 4, !tbaa [[TBAA13:![0-9]+]] -; IS__CGSCC_NPM-NEXT: [[ADD15:%.*]] = add nsw i32 3, 1 +; IS__CGSCC_NPM-NEXT: store i32 [[MUL11]], i32* [[I212]], align 4, !tbaa [[TBAA13]] +; IS__CGSCC_NPM-NEXT: [[I313:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 +; IS__CGSCC_NPM-NEXT: [[I10:%.*]] = load i32, i32* [[I313]], align 4, !tbaa [[TBAA14:![0-9]+]] +; IS__CGSCC_NPM-NEXT: [[I114:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 +; IS__CGSCC_NPM-NEXT: [[I11:%.*]] = load i32, i32* [[I114]], align 4, !tbaa [[TBAA12]] +; IS__CGSCC_NPM-NEXT: [[ADD15:%.*]] = add nsw i32 [[I10]], [[I11]] ; IS__CGSCC_NPM-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2 -; IS__CGSCC_NPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]] +; IS__CGSCC_NPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14]] ; IS__CGSCC_NPM-NEXT: [[I12:%.*]] = bitcast %struct.S* [[S]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 24, i8* nocapture nofree noundef nonnull align 4 dereferenceable(24) [[I12]]) #[[ATTR14]] ; IS__CGSCC_NPM-NEXT: ret void ; entry: @@ -551,7 +589,7 @@ define void @local_alloca_simplifiable_2() { ; IS__CGSCC_OPM-NEXT: store i8 0, i8* [[ARRAYIDX25]], align 1, !tbaa [[TBAA15]] ; IS__CGSCC_OPM-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 500 ; IS__CGSCC_OPM-NEXT: [[I22:%.*]] = bitcast i8* [[ARRAYIDX26]] to i32* -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR15:[0-9]+]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR17:[0-9]+]] ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND28:%.*]] ; IS__CGSCC_OPM: for.cond28: ; IS__CGSCC_OPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ] @@ -577,7 +615,7 @@ define void @local_alloca_simplifiable_2() { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 0 -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1024, i8* nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[I]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 1024, i8* nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[I]]) #[[ATTR14]] ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND:%.*]] ; IS__CGSCC_NPM: for.cond: ; IS__CGSCC_NPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] @@ -634,7 +672,7 @@ define void @local_alloca_simplifiable_2() { ; IS__CGSCC_NPM-NEXT: store i8 0, i8* [[ARRAYIDX25]], align 1, !tbaa [[TBAA15]] ; IS__CGSCC_NPM-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[BYTES]], i64 0, i64 500 ; IS__CGSCC_NPM-NEXT: [[I22:%.*]] = bitcast i8* [[ARRAYIDX26]] to i32* -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR14:[0-9]+]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I22]], i32 noundef 0) #[[ATTR16:[0-9]+]] ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND28:%.*]] ; IS__CGSCC_NPM: for.cond28: ; IS__CGSCC_NPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ] @@ -867,7 +905,7 @@ define i32 @multi_obj_simplifiable_1(i32 %cnd) { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR15]] ; IS__CGSCC_OPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__CGSCC_OPM: cond.true: @@ -876,7 +914,7 @@ define i32 @multi_obj_simplifiable_1(i32 %cnd) { ; IS__CGSCC_OPM-NEXT: br label [[COND_END]] ; IS__CGSCC_OPM: cond.end: ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR15]] ; IS__CGSCC_OPM-NEXT: ret i32 5 ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -885,7 +923,7 @@ define i32 @multi_obj_simplifiable_1(i32 %cnd) { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR14]] ; IS__CGSCC_NPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__CGSCC_NPM: cond.true: @@ -894,7 +932,7 @@ define i32 @multi_obj_simplifiable_1(i32 %cnd) { ; IS__CGSCC_NPM-NEXT: br label [[COND_END]] ; IS__CGSCC_NPM: cond.end: ; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I2]]) #[[ATTR14]] ; IS__CGSCC_NPM-NEXT: ret i32 5 ; entry: @@ -971,7 +1009,7 @@ define i32 @multi_obj_simplifiable_2(i32 %cnd) { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR15]] ; IS__CGSCC_OPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__CGSCC_OPM: cond.true: @@ -980,7 +1018,7 @@ define i32 @multi_obj_simplifiable_2(i32 %cnd) { ; IS__CGSCC_OPM-NEXT: br label [[COND_END]] ; IS__CGSCC_OPM: cond.end: ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR15]] ; IS__CGSCC_OPM-NEXT: ret i32 5 ; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn @@ -989,7 +1027,7 @@ define i32 @multi_obj_simplifiable_2(i32 %cnd) { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[L:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR14]] ; IS__CGSCC_NPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0 ; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]] ; IS__CGSCC_NPM: cond.true: @@ -998,7 +1036,7 @@ define i32 @multi_obj_simplifiable_2(i32 %cnd) { ; IS__CGSCC_NPM-NEXT: br label [[COND_END]] ; IS__CGSCC_NPM: cond.end: ; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = bitcast i32* [[L]] to i8* -; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR14]] ; IS__CGSCC_NPM-NEXT: ret i32 5 ; entry: @@ -1092,52 +1130,74 @@ define void @static_global_simplifiable_1(%struct.S* noalias sret(%struct.S) ali ; IS__TUNIT_NPM-NEXT: store i32 [[ADD2]], i32* [[I3]], align 4, !tbaa [[TBAA14]] ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@static_global_simplifiable_1 ; IS__CGSCC_OPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR14]] -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR14]] -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: store float 0x3FF19999A0000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] +; IS__CGSCC_OPM-NEXT: store float 0x40019999A0000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]] +; IS__CGSCC_OPM-NEXT: store float 0x400A666660000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR16]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR16]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR16]] +; IS__CGSCC_OPM-NEXT: [[I:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] ; IS__CGSCC_OPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 -; IS__CGSCC_OPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7]] -; IS__CGSCC_OPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 +; IS__CGSCC_OPM-NEXT: store float [[I]], float* [[F1]], align 4, !tbaa [[TBAA7]] +; IS__CGSCC_OPM-NEXT: [[I4:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]] +; IS__CGSCC_OPM-NEXT: [[MUL:%.*]] = fmul float [[I4]], 2.000000e+00 ; IS__CGSCC_OPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 4 ; IS__CGSCC_OPM-NEXT: store float [[MUL]], float* [[F2]], align 4, !tbaa [[TBAA10]] -; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = fadd float 0x400A666660000000, 0x3FF19999A0000000 +; IS__CGSCC_OPM-NEXT: [[I5:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]] +; IS__CGSCC_OPM-NEXT: [[I6:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = fadd float [[I5]], [[I6]] ; IS__CGSCC_OPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 5 ; IS__CGSCC_OPM-NEXT: store float [[ADD]], float* [[F3]], align 4, !tbaa [[TBAA11]] +; IS__CGSCC_OPM-NEXT: [[I7:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 0), align 4, !tbaa [[TBAA12]] ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 0 -; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[I1]], align 4, !tbaa [[TBAA12]] -; IS__CGSCC_OPM-NEXT: [[MUL1:%.*]] = shl nsw i32 2, 1 +; IS__CGSCC_OPM-NEXT: store i32 [[I7]], i32* [[I1]], align 4, !tbaa [[TBAA12]] +; IS__CGSCC_OPM-NEXT: [[I8:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), align 4, !tbaa [[TBAA13]] +; IS__CGSCC_OPM-NEXT: [[MUL1:%.*]] = shl nsw i32 [[I8]], 1 ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 1 ; IS__CGSCC_OPM-NEXT: store i32 [[MUL1]], i32* [[I2]], align 4, !tbaa [[TBAA13]] -; IS__CGSCC_OPM-NEXT: [[ADD2:%.*]] = add nsw i32 3, 1 +; IS__CGSCC_OPM-NEXT: [[I9:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), align 4, !tbaa [[TBAA14]] +; IS__CGSCC_OPM-NEXT: [[I10:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 0), align 4, !tbaa [[TBAA12]] +; IS__CGSCC_OPM-NEXT: [[ADD2:%.*]] = add nsw i32 [[I9]], [[I10]] ; IS__CGSCC_OPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2 ; IS__CGSCC_OPM-NEXT: store i32 [[ADD2]], i32* [[I3]], align 4, !tbaa [[TBAA14]] ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@static_global_simplifiable_1 ; IS__CGSCC_NPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR13]] -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR13]] -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: store float 0x3FF19999A0000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] +; IS__CGSCC_NPM-NEXT: store float 0x40019999A0000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]] +; IS__CGSCC_NPM-NEXT: store float 0x400A666660000000, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i32 0, i32 0), i32 noundef 1) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: [[I:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] ; IS__CGSCC_NPM-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 -; IS__CGSCC_NPM-NEXT: store float 0x3FF19999A0000000, float* [[F1]], align 4, !tbaa [[TBAA7]] -; IS__CGSCC_NPM-NEXT: [[MUL:%.*]] = fmul float 0x40019999A0000000, 2.000000e+00 +; IS__CGSCC_NPM-NEXT: store float [[I]], float* [[F1]], align 4, !tbaa [[TBAA7]] +; IS__CGSCC_NPM-NEXT: [[I4:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]] +; IS__CGSCC_NPM-NEXT: [[MUL:%.*]] = fmul float [[I4]], 2.000000e+00 ; IS__CGSCC_NPM-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 4 ; IS__CGSCC_NPM-NEXT: store float [[MUL]], float* [[F2]], align 4, !tbaa [[TBAA10]] -; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = fadd float 0x400A666660000000, 0x3FF19999A0000000 +; IS__CGSCC_NPM-NEXT: [[I5:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]] +; IS__CGSCC_NPM-NEXT: [[I6:%.*]] = load float, float* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]] +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = fadd float [[I5]], [[I6]] ; IS__CGSCC_NPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 5 ; IS__CGSCC_NPM-NEXT: store float [[ADD]], float* [[F3]], align 4, !tbaa [[TBAA11]] +; IS__CGSCC_NPM-NEXT: [[I7:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 0), align 4, !tbaa [[TBAA12]] ; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 0 -; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[I1]], align 4, !tbaa [[TBAA12]] -; IS__CGSCC_NPM-NEXT: [[MUL1:%.*]] = shl nsw i32 2, 1 +; IS__CGSCC_NPM-NEXT: store i32 [[I7]], i32* [[I1]], align 4, !tbaa [[TBAA12]] +; IS__CGSCC_NPM-NEXT: [[I8:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 1), align 4, !tbaa [[TBAA13]] +; IS__CGSCC_NPM-NEXT: [[MUL1:%.*]] = shl nsw i32 [[I8]], 1 ; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 1 ; IS__CGSCC_NPM-NEXT: store i32 [[MUL1]], i32* [[I2]], align 4, !tbaa [[TBAA13]] -; IS__CGSCC_NPM-NEXT: [[ADD2:%.*]] = add nsw i32 3, 1 +; IS__CGSCC_NPM-NEXT: [[I9:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 2), align 4, !tbaa [[TBAA14]] +; IS__CGSCC_NPM-NEXT: [[I10:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_S]], %struct.S* @Gs1, i64 0, i32 0), align 4, !tbaa [[TBAA12]] +; IS__CGSCC_NPM-NEXT: [[ADD2:%.*]] = add nsw i32 [[I9]], [[I10]] ; IS__CGSCC_NPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 2 ; IS__CGSCC_NPM-NEXT: store i32 [[ADD2]], i32* [[I3]], align 4, !tbaa [[TBAA14]] ; IS__CGSCC_NPM-NEXT: ret void @@ -1395,7 +1455,7 @@ define void @static_global_simplifiable_2() { ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP26:![0-9]+]] ; IS__CGSCC_OPM: for.end23: ; IS__CGSCC_OPM-NEXT: store i8 0, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 1023), align 1, !tbaa [[TBAA15]] -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR17]] ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND25:%.*]] ; IS__CGSCC_OPM: for.cond25: ; IS__CGSCC_OPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ] @@ -1468,7 +1528,7 @@ define void @static_global_simplifiable_2() { ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP26:![0-9]+]] ; IS__CGSCC_NPM: for.end23: ; IS__CGSCC_NPM-NEXT: store i8 0, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 1023), align 1, !tbaa [[TBAA15]] -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) bitcast (i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @GBytes, i64 0, i64 500) to i32*), i32 noundef 0) #[[ATTR16]] ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND25:%.*]] ; IS__CGSCC_NPM: for.cond25: ; IS__CGSCC_NPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ] @@ -1731,7 +1791,7 @@ define void @noalias_arg_simplifiable_1(%struct.S* noalias sret(%struct.S) align ; IS__TUNIT_NPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14]] ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_1 ; IS__CGSCC_OPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]], %struct.S* noalias nocapture nofree nonnull byval([[STRUCT_S]]) align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR1]] { ; IS__CGSCC_OPM-NEXT: entry: @@ -1742,11 +1802,11 @@ define void @noalias_arg_simplifiable_1(%struct.S* noalias sret(%struct.S) align ; IS__CGSCC_OPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__CGSCC_OPM-NEXT: store float 0x400A666660000000, float* [[F3]], align 4, !tbaa [[TBAA11]] ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR16]] ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR16]] ; IS__CGSCC_OPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR14]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR16]] ; IS__CGSCC_OPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_OPM-NEXT: [[I:%.*]] = load float, float* [[F11]], align 4, !tbaa [[TBAA7]] ; IS__CGSCC_OPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 @@ -1781,7 +1841,7 @@ define void @noalias_arg_simplifiable_1(%struct.S* noalias sret(%struct.S) align ; IS__CGSCC_OPM-NEXT: store i32 [[ADD15]], i32* [[I316]], align 4, !tbaa [[TBAA14]] ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_1 ; IS__CGSCC_NPM-SAME: (%struct.S* noalias nocapture nofree nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]], %struct.S* noalias nocapture nofree nonnull byval([[STRUCT_S]]) align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR1]] { ; IS__CGSCC_NPM-NEXT: entry: @@ -1792,11 +1852,11 @@ define void @noalias_arg_simplifiable_1(%struct.S* noalias sret(%struct.S) align ; IS__CGSCC_NPM-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 5 ; IS__CGSCC_NPM-NEXT: store float 0x400A666660000000, float* [[F3]], align 4, !tbaa [[TBAA11]] ; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 0 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[I1]], i32 noundef 1) #[[ATTR15]] ; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 1 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR15]] ; IS__CGSCC_NPM-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 2 -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR13]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR15]] ; IS__CGSCC_NPM-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S]], i64 0, i32 3 ; IS__CGSCC_NPM-NEXT: [[I:%.*]] = load float, float* [[F11]], align 4, !tbaa [[TBAA7]] ; IS__CGSCC_NPM-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AGG_RESULT]], i64 0, i32 3 @@ -2113,7 +2173,7 @@ define void @noalias_arg_simplifiable_2(i8* %Bytes) { ; IS__CGSCC_OPM-NEXT: store i8 0, i8* [[ARRAYIDX24]], align 1, !tbaa [[TBAA15]] ; IS__CGSCC_OPM-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i64 500 ; IS__CGSCC_OPM-NEXT: [[I21:%.*]] = bitcast i8* [[ARRAYIDX25]] to i32* -; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR17]] ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND27:%.*]] ; IS__CGSCC_OPM: for.cond27: ; IS__CGSCC_OPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ] @@ -2192,7 +2252,7 @@ define void @noalias_arg_simplifiable_2(i8* %Bytes) { ; IS__CGSCC_NPM-NEXT: store i8 0, i8* [[ARRAYIDX24]], align 1, !tbaa [[TBAA15]] ; IS__CGSCC_NPM-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, i8* [[BYTES]], i64 500 ; IS__CGSCC_NPM-NEXT: [[I21:%.*]] = bitcast i8* [[ARRAYIDX25]] to i32* -; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: call void @write_arg(i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[I21]], i32 noundef 0) #[[ATTR16]] ; IS__CGSCC_NPM-NEXT: br label [[FOR_COND27:%.*]] ; IS__CGSCC_NPM: for.cond27: ; IS__CGSCC_NPM-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ] @@ -2320,55 +2380,105 @@ for.end37: ; preds = %for.cond.cleanup29 ; } ; define i32 @local_alloca_not_simplifiable_1() { -; IS________OPM-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[X:%.*]] = alloca i32, align 4 -; IS________OPM-NEXT: [[Y:%.*]] = alloca i32, align 4 -; IS________OPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR13:[0-9]+]] -; IS________OPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR13]] -; IS________OPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] -; IS________OPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] -; IS________OPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* -; IS________OPM-NEXT: call void @escape(i8* noundef nonnull align 4 dereferenceable(4) [[I2]]) -; IS________OPM-NEXT: call void @write_random(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Y]]) -; IS________OPM-NEXT: [[I3:%.*]] = load i32, i32* [[X]], align 4, !tbaa [[TBAA3]] -; IS________OPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0 -; IS________OPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1 -; IS________OPM-NEXT: [[I4:%.*]] = load i32, i32* [[Y]], align 4, !tbaa [[TBAA3]] -; IS________OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]] -; IS________OPM-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]] -; IS________OPM-NEXT: [[I5:%.*]] = bitcast i32* [[Y]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I5]]) -; IS________OPM-NEXT: [[I6:%.*]] = bitcast i32* [[X]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I6]]) -; IS________OPM-NEXT: ret i32 [[ADD1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[X:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: [[Y:%.*]] = alloca i32, align 4 +; IS__TUNIT_OPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR13]] +; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR13]] +; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] +; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] +; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* +; IS__TUNIT_OPM-NEXT: call void @escape(i8* noundef nonnull align 4 dereferenceable(4) [[I2]]) +; IS__TUNIT_OPM-NEXT: call void @write_random(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Y]]) +; IS__TUNIT_OPM-NEXT: [[I3:%.*]] = load i32, i32* [[X]], align 4, !tbaa [[TBAA3]] +; IS__TUNIT_OPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0 +; IS__TUNIT_OPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1 +; IS__TUNIT_OPM-NEXT: [[I4:%.*]] = load i32, i32* [[Y]], align 4, !tbaa [[TBAA3]] +; IS__TUNIT_OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]] +; IS__TUNIT_OPM-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]] +; IS__TUNIT_OPM-NEXT: [[I5:%.*]] = bitcast i32* [[Y]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I5]]) +; IS__TUNIT_OPM-NEXT: [[I6:%.*]] = bitcast i32* [[X]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I6]]) +; IS__TUNIT_OPM-NEXT: ret i32 [[ADD1]] ; -; IS________NPM-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[X:%.*]] = alloca i32, align 4 -; IS________NPM-NEXT: [[Y:%.*]] = alloca i32, align 4 -; IS________NPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR12:[0-9]+]] -; IS________NPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR12]] -; IS________NPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] -; IS________NPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] -; IS________NPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* -; IS________NPM-NEXT: call void @escape(i8* noundef nonnull align 4 dereferenceable(4) [[I2]]) -; IS________NPM-NEXT: call void @write_random(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Y]]) -; IS________NPM-NEXT: [[I3:%.*]] = load i32, i32* [[X]], align 4, !tbaa [[TBAA3]] -; IS________NPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0 -; IS________NPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1 -; IS________NPM-NEXT: [[I4:%.*]] = load i32, i32* [[Y]], align 4, !tbaa [[TBAA3]] -; IS________NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]] -; IS________NPM-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]] -; IS________NPM-NEXT: [[I5:%.*]] = bitcast i32* [[Y]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I5]]) -; IS________NPM-NEXT: [[I6:%.*]] = bitcast i32* [[X]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I6]]) -; IS________NPM-NEXT: ret i32 [[ADD1]] +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: [[Y:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] +; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* +; IS__TUNIT_NPM-NEXT: call void @escape(i8* noundef nonnull align 4 dereferenceable(4) [[I2]]) +; IS__TUNIT_NPM-NEXT: call void @write_random(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Y]]) +; IS__TUNIT_NPM-NEXT: [[I3:%.*]] = load i32, i32* [[X]], align 4, !tbaa [[TBAA3]] +; IS__TUNIT_NPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0 +; IS__TUNIT_NPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1 +; IS__TUNIT_NPM-NEXT: [[I4:%.*]] = load i32, i32* [[Y]], align 4, !tbaa [[TBAA3]] +; IS__TUNIT_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]] +; IS__TUNIT_NPM-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]] +; IS__TUNIT_NPM-NEXT: [[I5:%.*]] = bitcast i32* [[Y]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I5]]) +; IS__TUNIT_NPM-NEXT: [[I6:%.*]] = bitcast i32* [[X]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I6]]) +; IS__TUNIT_NPM-NEXT: ret i32 [[ADD1]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[X:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: [[Y:%.*]] = alloca i32, align 4 +; IS__CGSCC_OPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] +; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* +; IS__CGSCC_OPM-NEXT: call void @escape(i8* noundef nonnull align 4 dereferenceable(4) [[I2]]) +; IS__CGSCC_OPM-NEXT: call void @write_random(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Y]]) +; IS__CGSCC_OPM-NEXT: [[I3:%.*]] = load i32, i32* [[X]], align 4, !tbaa [[TBAA3]] +; IS__CGSCC_OPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0 +; IS__CGSCC_OPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1 +; IS__CGSCC_OPM-NEXT: [[I4:%.*]] = load i32, i32* [[Y]], align 4, !tbaa [[TBAA3]] +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]] +; IS__CGSCC_OPM-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]] +; IS__CGSCC_OPM-NEXT: [[I5:%.*]] = bitcast i32* [[Y]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I5]]) +; IS__CGSCC_OPM-NEXT: [[I6:%.*]] = bitcast i32* [[X]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I6]]) +; IS__CGSCC_OPM-NEXT: ret i32 [[ADD1]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[X:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[Y:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: [[I:%.*]] = bitcast i32* [[X]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: [[I1:%.*]] = bitcast i32* [[Y]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I1]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[Y]], align 4, !tbaa [[TBAA3]] +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[X]], align 4, !tbaa [[TBAA3]] +; IS__CGSCC_NPM-NEXT: [[I2:%.*]] = bitcast i32* [[X]] to i8* +; IS__CGSCC_NPM-NEXT: call void @escape(i8* noundef nonnull align 4 dereferenceable(4) [[I2]]) +; IS__CGSCC_NPM-NEXT: call void @write_random(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Y]]) +; IS__CGSCC_NPM-NEXT: [[I3:%.*]] = load i32, i32* [[X]], align 4, !tbaa [[TBAA3]] +; IS__CGSCC_NPM-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0 +; IS__CGSCC_NPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1 +; IS__CGSCC_NPM-NEXT: [[I4:%.*]] = load i32, i32* [[Y]], align 4, !tbaa [[TBAA3]] +; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]] +; IS__CGSCC_NPM-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]] +; IS__CGSCC_NPM-NEXT: [[I5:%.*]] = bitcast i32* [[Y]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I5]]) +; IS__CGSCC_NPM-NEXT: [[I6:%.*]] = bitcast i32* [[X]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[I6]]) +; IS__CGSCC_NPM-NEXT: ret i32 [[ADD1]] ; entry: %X = alloca i32, align 4 @@ -2663,11 +2773,17 @@ define void @write_global() { ; IS__TUNIT_OPM-NEXT: store i32 7, i32* @Gint2, align 4 ; IS__TUNIT_OPM-NEXT: ret void ; -; NOT_TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@write_global -; NOT_TUNIT_OPM-SAME: () #[[ATTR5:[0-9]+]] { -; NOT_TUNIT_OPM-NEXT: store i32 7, i32* @Gint2, align 4 -; NOT_TUNIT_OPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@write_global +; IS__TUNIT_NPM-SAME: () #[[ATTR5]] { +; IS__TUNIT_NPM-NEXT: store i32 7, i32* @Gint2, align 4 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@write_global +; IS__CGSCC____-SAME: () #[[ATTR7:[0-9]+]] { +; IS__CGSCC____-NEXT: store i32 7, i32* @Gint2, align 4 +; IS__CGSCC____-NEXT: ret void ; store i32 7, i32* @Gint2 ret void @@ -2722,11 +2838,17 @@ define void @write_static_global() { ; IS__TUNIT_OPM-NEXT: store i32 7, i32* @Gstatic_int2, align 4 ; IS__TUNIT_OPM-NEXT: ret void ; -; NOT_TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@write_static_global -; NOT_TUNIT_OPM-SAME: () #[[ATTR5]] { -; NOT_TUNIT_OPM-NEXT: store i32 7, i32* @Gstatic_int2, align 4 -; NOT_TUNIT_OPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@write_static_global +; IS__TUNIT_NPM-SAME: () #[[ATTR5]] { +; IS__TUNIT_NPM-NEXT: store i32 7, i32* @Gstatic_int2, align 4 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@write_static_global +; IS__CGSCC____-SAME: () #[[ATTR7]] { +; IS__CGSCC____-NEXT: store i32 7, i32* @Gstatic_int2, align 4 +; IS__CGSCC____-NEXT: ret void ; store i32 7, i32* @Gstatic_int2 ret void @@ -2753,10 +2875,15 @@ define i32 @write_read_static_undef_global() { ; IS__TUNIT_OPM-SAME: () #[[ATTR6]] { ; IS__TUNIT_OPM-NEXT: ret i32 7 ; -; NOT_TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@write_read_static_undef_global -; NOT_TUNIT_OPM-SAME: () #[[ATTR5]] { -; NOT_TUNIT_OPM-NEXT: ret i32 7 +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@write_read_static_undef_global +; IS__TUNIT_NPM-SAME: () #[[ATTR5]] { +; IS__TUNIT_NPM-NEXT: ret i32 7 +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@write_read_static_undef_global +; IS__CGSCC____-SAME: () #[[ATTR7]] { +; IS__CGSCC____-NEXT: ret i32 7 ; store i32 7, i32* @Gstatic_undef_int1 %l = load i32, i32* @Gstatic_undef_int1 @@ -2775,7 +2902,7 @@ define void @write_static_undef_global() { ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@write_static_undef_global -; IS__CGSCC____-SAME: () #[[ATTR5]] { +; IS__CGSCC____-SAME: () #[[ATTR7]] { ; IS__CGSCC____-NEXT: store i32 7, i32* @Gstatic_undef_int2, align 4 ; IS__CGSCC____-NEXT: ret void ; @@ -2813,24 +2940,24 @@ define i32 @single_read_of_static_global() { } define i8 @phi_store() { -; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone -; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@phi_store -; IS__TUNIT_OPM-SAME: () #[[ATTR8:[0-9]+]] { -; IS__TUNIT_OPM-NEXT: entry: -; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i16, align 2 -; IS__TUNIT_OPM-NEXT: [[B:%.*]] = bitcast i16* [[A]] to i8* -; IS__TUNIT_OPM-NEXT: br label [[LOOP:%.*]] -; IS__TUNIT_OPM: loop: -; IS__TUNIT_OPM-NEXT: [[P:%.*]] = phi i8* [ [[B]], [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] -; IS__TUNIT_OPM-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] -; IS__TUNIT_OPM-NEXT: [[G]] = getelementptr i8, i8* [[P]], i64 1 -; IS__TUNIT_OPM-NEXT: [[O]] = add nsw i8 [[I]], 1 -; IS__TUNIT_OPM-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 2 -; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] -; IS__TUNIT_OPM: end: -; IS__TUNIT_OPM-NEXT: [[S:%.*]] = getelementptr i8, i8* [[B]], i64 1 -; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i8, i8* [[S]], align 1 -; IS__TUNIT_OPM-NEXT: ret i8 [[L]] +; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone +; IS________OPM-LABEL: define {{[^@]+}}@phi_store +; IS________OPM-SAME: () #[[ATTR8:[0-9]+]] { +; IS________OPM-NEXT: entry: +; IS________OPM-NEXT: [[A:%.*]] = alloca i16, align 2 +; IS________OPM-NEXT: [[B:%.*]] = bitcast i16* [[A]] to i8* +; IS________OPM-NEXT: br label [[LOOP:%.*]] +; IS________OPM: loop: +; IS________OPM-NEXT: [[P:%.*]] = phi i8* [ [[B]], [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] +; IS________OPM-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] +; IS________OPM-NEXT: [[G]] = getelementptr i8, i8* [[P]], i64 1 +; IS________OPM-NEXT: [[O]] = add nsw i8 [[I]], 1 +; IS________OPM-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 2 +; IS________OPM-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] +; IS________OPM: end: +; IS________OPM-NEXT: [[S:%.*]] = getelementptr i8, i8* [[B]], i64 1 +; IS________OPM-NEXT: [[L:%.*]] = load i8, i8* [[S]], align 1 +; IS________OPM-NEXT: ret i8 [[L]] ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@phi_store @@ -2851,25 +2978,6 @@ define i8 @phi_store() { ; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i8, i8* [[S]], align 1 ; IS__TUNIT_NPM-NEXT: ret i8 [[L]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@phi_store -; IS__CGSCC_OPM-SAME: () #[[ATTR7:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: entry: -; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i16, align 2 -; IS__CGSCC_OPM-NEXT: [[B:%.*]] = bitcast i16* [[A]] to i8* -; IS__CGSCC_OPM-NEXT: br label [[LOOP:%.*]] -; IS__CGSCC_OPM: loop: -; IS__CGSCC_OPM-NEXT: [[P:%.*]] = phi i8* [ [[B]], [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ] -; IS__CGSCC_OPM-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] -; IS__CGSCC_OPM-NEXT: [[G]] = getelementptr i8, i8* [[P]], i64 1 -; IS__CGSCC_OPM-NEXT: [[O]] = add nsw i8 [[I]], 1 -; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 2 -; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] -; IS__CGSCC_OPM: end: -; IS__CGSCC_OPM-NEXT: [[S:%.*]] = getelementptr i8, i8* [[B]], i64 1 -; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i8, i8* [[S]], align 1 -; IS__CGSCC_OPM-NEXT: ret i8 [[L]] -; ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@phi_store ; IS__CGSCC_NPM-SAME: () #[[ATTR3]] { @@ -2948,7 +3056,7 @@ define i8 @phi_no_store_1() { ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@phi_no_store_1 -; IS__CGSCC_OPM-SAME: () #[[ATTR8:[0-9]+]] { +; IS__CGSCC_OPM-SAME: () #[[ATTR9:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: br label [[LOOP:%.*]] ; IS__CGSCC_OPM: loop: @@ -3041,7 +3149,7 @@ define i8 @phi_no_store_2() { ; ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@phi_no_store_2 -; IS__CGSCC_OPM-SAME: () #[[ATTR8]] { +; IS__CGSCC_OPM-SAME: () #[[ATTR9]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: br label [[LOOP:%.*]] ; IS__CGSCC_OPM: loop: @@ -3094,33 +3202,61 @@ end: } define i8 @phi_no_store_3() { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind writeonly -; IS________OPM-LABEL: define {{[^@]+}}@phi_no_store_3 -; IS________OPM-SAME: () #[[ATTR9:[0-9]+]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: br label [[LOOP:%.*]] -; IS________OPM: loop: -; IS________OPM-NEXT: [[P:%.*]] = phi i8* [ bitcast (i32* @a3 to i8*), [[ENTRY:%.*]] ], [ getelementptr (i8, i8* bitcast (i32* @a3 to i8*), i64 2), [[LOOP]] ] -; IS________OPM-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] -; IS________OPM-NEXT: [[O]] = add nsw i8 [[I]], 1 -; IS________OPM-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 -; IS________OPM-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] -; IS________OPM: end: -; IS________OPM-NEXT: ret i8 1 +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind writeonly +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@phi_no_store_3 +; IS__TUNIT_OPM-SAME: () #[[ATTR9:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: br label [[LOOP:%.*]] +; IS__TUNIT_OPM: loop: +; IS__TUNIT_OPM-NEXT: [[P:%.*]] = phi i8* [ bitcast (i32* @a3 to i8*), [[ENTRY:%.*]] ], [ getelementptr (i8, i8* bitcast (i32* @a3 to i8*), i64 2), [[LOOP]] ] +; IS__TUNIT_OPM-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] +; IS__TUNIT_OPM-NEXT: [[O]] = add nsw i8 [[I]], 1 +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 +; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] +; IS__TUNIT_OPM: end: +; IS__TUNIT_OPM-NEXT: ret i8 1 ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; IS________NPM-LABEL: define {{[^@]+}}@phi_no_store_3 -; IS________NPM-SAME: () #[[ATTR5]] { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: br label [[LOOP:%.*]] -; IS________NPM: loop: -; IS________NPM-NEXT: [[P:%.*]] = phi i8* [ bitcast (i32* @a3 to i8*), [[ENTRY:%.*]] ], [ getelementptr (i8, i8* bitcast (i32* @a3 to i8*), i64 2), [[LOOP]] ] -; IS________NPM-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] -; IS________NPM-NEXT: [[O]] = add nsw i8 [[I]], 1 -; IS________NPM-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 -; IS________NPM-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] -; IS________NPM: end: -; IS________NPM-NEXT: ret i8 1 +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@phi_no_store_3 +; IS__TUNIT_NPM-SAME: () #[[ATTR5]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: br label [[LOOP:%.*]] +; IS__TUNIT_NPM: loop: +; IS__TUNIT_NPM-NEXT: [[P:%.*]] = phi i8* [ bitcast (i32* @a3 to i8*), [[ENTRY:%.*]] ], [ getelementptr (i8, i8* bitcast (i32* @a3 to i8*), i64 2), [[LOOP]] ] +; IS__TUNIT_NPM-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] +; IS__TUNIT_NPM-NEXT: [[O]] = add nsw i8 [[I]], 1 +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 +; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] +; IS__TUNIT_NPM: end: +; IS__TUNIT_NPM-NEXT: ret i8 1 +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind writeonly +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@phi_no_store_3 +; IS__CGSCC_OPM-SAME: () #[[ATTR10:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: br label [[LOOP:%.*]] +; IS__CGSCC_OPM: loop: +; IS__CGSCC_OPM-NEXT: [[P:%.*]] = phi i8* [ bitcast (i32* @a3 to i8*), [[ENTRY:%.*]] ], [ getelementptr (i8, i8* bitcast (i32* @a3 to i8*), i64 2), [[LOOP]] ] +; IS__CGSCC_OPM-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] +; IS__CGSCC_OPM-NEXT: [[O]] = add nsw i8 [[I]], 1 +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] +; IS__CGSCC_OPM: end: +; IS__CGSCC_OPM-NEXT: ret i8 1 +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@phi_no_store_3 +; IS__CGSCC_NPM-SAME: () #[[ATTR7]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: br label [[LOOP:%.*]] +; IS__CGSCC_NPM: loop: +; IS__CGSCC_NPM-NEXT: [[P:%.*]] = phi i8* [ bitcast (i32* @a3 to i8*), [[ENTRY:%.*]] ], [ getelementptr (i8, i8* bitcast (i32* @a3 to i8*), i64 2), [[LOOP]] ] +; IS__CGSCC_NPM-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ] +; IS__CGSCC_NPM-NEXT: [[O]] = add nsw i8 [[I]], 1 +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7 +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]] +; IS__CGSCC_NPM: end: +; IS__CGSCC_NPM-NEXT: ret i8 1 ; entry: %b = bitcast i32* @a3 to i8* @@ -3202,35 +3338,65 @@ define i64 @cast_and_load_2() { define void @recursive_load_store(i64 %N, i32 %v) { ; -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind writeonly -; IS________OPM-LABEL: define {{[^@]+}}@recursive_load_store -; IS________OPM-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR9]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: br label [[FOR_COND:%.*]] -; IS________OPM: for.cond: -; IS________OPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] -; IS________OPM-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]] -; IS________OPM-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] -; IS________OPM: for.body: -; IS________OPM-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 -; IS________OPM-NEXT: br label [[FOR_COND]] -; IS________OPM: for.end: -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind writeonly +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@recursive_load_store +; IS__TUNIT_OPM-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR9]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: br label [[FOR_COND:%.*]] +; IS__TUNIT_OPM: for.cond: +; IS__TUNIT_OPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; IS__TUNIT_OPM-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]] +; IS__TUNIT_OPM-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; IS__TUNIT_OPM: for.body: +; IS__TUNIT_OPM-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; IS__TUNIT_OPM-NEXT: br label [[FOR_COND]] +; IS__TUNIT_OPM: for.end: +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind writeonly -; IS________NPM-LABEL: define {{[^@]+}}@recursive_load_store -; IS________NPM-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR7:[0-9]+]] { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: br label [[FOR_COND:%.*]] -; IS________NPM: for.cond: -; IS________NPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] -; IS________NPM-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]] -; IS________NPM-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] -; IS________NPM: for.body: -; IS________NPM-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 -; IS________NPM-NEXT: br label [[FOR_COND]] -; IS________NPM: for.end: -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind writeonly +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@recursive_load_store +; IS__TUNIT_NPM-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]] +; IS__TUNIT_NPM: for.cond: +; IS__TUNIT_NPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; IS__TUNIT_NPM-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]] +; IS__TUNIT_NPM-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; IS__TUNIT_NPM: for.body: +; IS__TUNIT_NPM-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; IS__TUNIT_NPM-NEXT: br label [[FOR_COND]] +; IS__TUNIT_NPM: for.end: +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind writeonly +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@recursive_load_store +; IS__CGSCC_OPM-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR10]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: br label [[FOR_COND:%.*]] +; IS__CGSCC_OPM: for.cond: +; IS__CGSCC_OPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; IS__CGSCC_OPM-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]] +; IS__CGSCC_OPM-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; IS__CGSCC_OPM: for.body: +; IS__CGSCC_OPM-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; IS__CGSCC_OPM-NEXT: br label [[FOR_COND]] +; IS__CGSCC_OPM: for.end: +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@recursive_load_store +; IS__CGSCC_NPM-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND:%.*]] +; IS__CGSCC_NPM: for.cond: +; IS__CGSCC_NPM-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ] +; IS__CGSCC_NPM-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]] +; IS__CGSCC_NPM-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; IS__CGSCC_NPM: for.body: +; IS__CGSCC_NPM-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND]] +; IS__CGSCC_NPM: for.end: +; IS__CGSCC_NPM-NEXT: ret void ; entry: store i32 %v, i32* @rec_storage @@ -3254,15 +3420,15 @@ for.end: } define dso_local i32 @round_trip_malloc(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_malloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16:[0-9]+]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_malloc +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16:[0-9]+]] +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; ; IS________NPM-LABEL: define {{[^@]+}}@round_trip_malloc ; IS________NPM-SAME: (i32 returned [[X:%.*]]) { @@ -3272,6 +3438,16 @@ define dso_local i32 @round_trip_malloc(i32 %x) { ; IS________NPM-NEXT: store i32 [[X]], i32* [[TMP1]], align 4 ; IS________NPM-NEXT: ret i32 [[X]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_malloc +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR18:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; entry: %call = call noalias i8* @malloc(i64 4) norecurse %0 = bitcast i8* %call to i32* @@ -3283,19 +3459,28 @@ entry: } define dso_local i32 @round_trip_malloc_constant() { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: store i32 7, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__TUNIT_OPM-NEXT: store i32 7, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; ; IS________NPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: ret i32 7 ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_constant() { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__CGSCC_OPM-NEXT: store i32 7, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: call void @free(i8* noundef [[CALL]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; entry: %call = call noalias i8* @malloc(i64 4) norecurse %0 = bitcast i8* %call to i32* @@ -3311,19 +3496,19 @@ declare noalias i8* @malloc(i64) declare void @free(i8*) define dso_local i32 @conditional_malloc(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@conditional_malloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 -; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] -; IS________OPM: if.then: -; IS________OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 -; IS________OPM-NEXT: br label [[IF_END]] -; IS________OPM: if.end: -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@conditional_malloc +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__TUNIT_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__TUNIT_OPM: if.then: +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: br label [[IF_END]] +; IS__TUNIT_OPM: if.end: +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; ; IS________NPM-LABEL: define {{[^@]+}}@conditional_malloc ; IS________NPM-SAME: (i32 returned [[X:%.*]]) { @@ -3338,6 +3523,20 @@ define dso_local i32 @conditional_malloc(i32 %x) { ; IS________NPM: if.end: ; IS________NPM-NEXT: ret i32 [[X]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@conditional_malloc +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; IS__CGSCC_OPM: if.then: +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: br label [[IF_END]] +; IS__CGSCC_OPM: if.end: +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; entry: %call = call noalias i8* @malloc(i64 4) norecurse %0 = bitcast i8* %call to i32* @@ -3354,14 +3553,14 @@ if.end: ; preds = %if.then, %entry } define dso_local i32 @round_trip_calloc(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_calloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_calloc +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; ; IS________NPM-LABEL: define {{[^@]+}}@round_trip_calloc ; IS________NPM-SAME: (i32 [[X:%.*]]) { @@ -3373,6 +3572,15 @@ define dso_local i32 @round_trip_calloc(i32 %x) { ; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 ; IS________NPM-NEXT: ret i32 [[TMP2]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_calloc +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; entry: %call = call noalias i8* @calloc(i64 4, i64 1) norecurse %0 = bitcast i8* %call to i32* @@ -3382,13 +3590,13 @@ entry: } define dso_local i32 @round_trip_calloc_constant() { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: store i32 11, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__TUNIT_OPM-NEXT: store i32 11, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; ; IS________NPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { ; IS________NPM-NEXT: entry: @@ -3399,6 +3607,14 @@ define dso_local i32 @round_trip_calloc_constant() { ; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 ; IS________NPM-NEXT: ret i32 [[TMP2]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_calloc_constant() { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 4, i64 noundef 1) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__CGSCC_OPM-NEXT: store i32 11, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; entry: %call = call noalias i8* @calloc(i64 4, i64 1) norecurse %0 = bitcast i8* %call to i32* @@ -3410,21 +3626,21 @@ entry: declare noalias i8* @calloc(i64, i64) define dso_local i32 @conditional_calloc(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@conditional_calloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 -; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; IS________OPM: if.then: -; IS________OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 -; IS________OPM-NEXT: br label [[IF_END]] -; IS________OPM: if.end: -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* -; IS________OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@conditional_calloc +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__TUNIT_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__TUNIT_OPM: if.then: +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: br label [[IF_END]] +; IS__TUNIT_OPM: if.end: +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* +; IS__TUNIT_OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; ; IS________NPM-LABEL: define {{[^@]+}}@conditional_calloc ; IS________NPM-SAME: (i32 [[X:%.*]]) { @@ -3442,6 +3658,22 @@ define dso_local i32 @conditional_calloc(i32 %x) { ; IS________NPM-NEXT: [[TMP3:%.*]] = bitcast i32* [[TMP1]] to i8* ; IS________NPM-NEXT: ret i32 [[TMP2]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@conditional_calloc +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__CGSCC_OPM: if.then: +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: br label [[IF_END]] +; IS__CGSCC_OPM: if.end: +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* +; IS__CGSCC_OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; entry: %call = call noalias i8* @calloc(i64 1, i64 4) norecurse %0 = bitcast i8* %call to i32* @@ -3460,20 +3692,20 @@ if.end: ; preds = %if.then, %entry } define dso_local i32 @conditional_calloc_zero(i1 %c) { -; IS________OPM-LABEL: define {{[^@]+}}@conditional_calloc_zero -; IS________OPM-SAME: (i1 [[C:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; IS________OPM: if.then: -; IS________OPM-NEXT: store i32 0, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: br label [[IF_END]] -; IS________OPM: if.end: -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 -; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* -; IS________OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@conditional_calloc_zero +; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__TUNIT_OPM: if.then: +; IS__TUNIT_OPM-NEXT: store i32 0, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: br label [[IF_END]] +; IS__TUNIT_OPM: if.end: +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* +; IS__TUNIT_OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; ; IS________NPM-LABEL: define {{[^@]+}}@conditional_calloc_zero ; IS________NPM-SAME: (i1 [[C:%.*]]) { @@ -3488,6 +3720,21 @@ define dso_local i32 @conditional_calloc_zero(i1 %c) { ; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP1]] to i8* ; IS________NPM-NEXT: ret i32 0 ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@conditional_calloc_zero +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @calloc(i64 noundef 1, i64 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__CGSCC_OPM: if.then: +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: br label [[IF_END]] +; IS__CGSCC_OPM: if.end: +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP0]] to i8* +; IS__CGSCC_OPM-NEXT: call void @free(i8* [[TMP2]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; entry: %call = call noalias i8* @calloc(i64 1, i64 4) norecurse %0 = bitcast i8* %call to i32* @@ -3505,13 +3752,13 @@ if.end: ; preds = %if.then, %entry } define dso_local i32* @malloc_like(i32 %s) { -; IS________OPM-LABEL: define {{[^@]+}}@malloc_like -; IS________OPM-SAME: (i32 [[S:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR16]] -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* -; IS________OPM-NEXT: ret i32* [[TMP0]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@malloc_like +; IS__TUNIT_OPM-SAME: (i32 [[S:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__TUNIT_OPM-NEXT: ret i32* [[TMP0]] ; ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@malloc_like ; IS__TUNIT_NPM-SAME: (i32 [[S:%.*]]) { @@ -3521,11 +3768,19 @@ define dso_local i32* @malloc_like(i32 %s) { ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__TUNIT_NPM-NEXT: ret i32* [[TMP0]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@malloc_like +; IS__CGSCC_OPM-SAME: (i32 [[S:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* +; IS__CGSCC_OPM-NEXT: ret i32* [[TMP0]] +; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@malloc_like ; IS__CGSCC_NPM-SAME: (i32 [[S:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64 -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR15:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i8* @malloc(i64 [[CONV]]) #[[ATTR17:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL]] to i32* ; IS__CGSCC_NPM-NEXT: ret i32* [[TMP0]] ; @@ -3537,15 +3792,15 @@ entry: } define dso_local i32 @round_trip_malloc_like(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_malloc_like -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS________OPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP0]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_like +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__TUNIT_OPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP0]] ; ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@round_trip_malloc_like ; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) { @@ -3557,14 +3812,24 @@ define dso_local i32 @round_trip_malloc_like(i32 %x) { ; IS__TUNIT_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR14]] ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP0]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_malloc_like +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__CGSCC_OPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP0]] +; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@round_trip_malloc_like ; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @malloc_like(i32 noundef 4) #[[ATTR17]] ; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS__CGSCC_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR17]] ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] ; entry: @@ -3577,15 +3842,15 @@ entry: } define dso_local i32 @round_trip_unknown_alloc(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS________OPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP0]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__TUNIT_OPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP0]] ; ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc ; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) { @@ -3597,14 +3862,24 @@ define dso_local i32 @round_trip_unknown_alloc(i32 %x) { ; IS__TUNIT_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR14]] ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP0]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__CGSCC_OPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP0]] +; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@round_trip_unknown_alloc ; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @unknown_alloc(i32 noundef 4) #[[ATTR17]] ; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS__CGSCC_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @free(i8* noundef [[TMP1]]) #[[ATTR17]] ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] ; entry: @@ -3619,20 +3894,20 @@ entry: declare noalias i32* @unknown_alloc(i32) define dso_local i32 @conditional_unknown_alloc(i32 %x) { -; IS________OPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc -; IS________OPM-SAME: (i32 [[X:%.*]]) { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR16]] -; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 -; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] -; IS________OPM: if.then: -; IS________OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 -; IS________OPM-NEXT: br label [[IF_END]] -; IS________OPM: if.end: -; IS________OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 -; IS________OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS________OPM-NEXT: call void @free(i8* [[TMP1]]) #[[ATTR16]] -; IS________OPM-NEXT: ret i32 [[TMP0]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc +; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]]) { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__TUNIT_OPM: if.then: +; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: br label [[IF_END]] +; IS__TUNIT_OPM: if.end: +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__TUNIT_OPM-NEXT: call void @free(i8* [[TMP1]]) #[[ATTR16]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP0]] ; ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc ; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]]) { @@ -3649,10 +3924,25 @@ define dso_local i32 @conditional_unknown_alloc(i32 %x) { ; IS__TUNIT_NPM-NEXT: call void @free(i8* [[TMP1]]) #[[ATTR14]] ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP0]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc +; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 +; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; IS__CGSCC_OPM: if.then: +; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: br label [[IF_END]] +; IS__CGSCC_OPM: if.end: +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* +; IS__CGSCC_OPM-NEXT: call void @free(i8* [[TMP1]]) #[[ATTR18]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP0]] +; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@conditional_unknown_alloc ; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: -; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias i32* @unknown_alloc(i32 noundef 4) #[[ATTR17]] ; IS__CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0 ; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; IS__CGSCC_NPM: if.then: @@ -3661,7 +3951,7 @@ define dso_local i32 @conditional_unknown_alloc(i32 %x) { ; IS__CGSCC_NPM: if.end: ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[CALL]], align 4 ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i32* [[CALL]] to i8* -; IS__CGSCC_NPM-NEXT: call void @free(i8* [[TMP1]]) #[[ATTR15]] +; IS__CGSCC_NPM-NEXT: call void @free(i8* [[TMP1]]) #[[ATTR17]] ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] ; entry: @@ -3719,11 +4009,12 @@ define dso_local void @test_nested_memory(float* %dst, double* %src) { ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_nested_memory -; IS__CGSCC_OPM-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) { +; IS__CGSCC_OPM-SAME: (float* nofree [[DST:%.*]], double* nofree [[SRC:%.*]]) { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 ; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast %struct.STy* [[LOCAL]] to i8* ; IS__CGSCC_OPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[LOCAL]], i64 0, i32 2 +; IS__CGSCC_OPM-NEXT: store %struct.STy* @global, %struct.STy** [[INNER]], align 8 ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noalias dereferenceable_or_null(24) i8* @malloc(i64 noundef 24) ; IS__CGSCC_OPM-NEXT: [[DST1:%.*]] = bitcast i8* [[CALL]] to float** ; IS__CGSCC_OPM-NEXT: store float* [[DST]], float** [[DST1]], align 8 @@ -3731,23 +4022,23 @@ define dso_local void @test_nested_memory(float* %dst, double* %src) { ; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[SRC2]] to double** ; IS__CGSCC_OPM-NEXT: store double* [[SRC]], double** [[TMP1]], align 8 ; IS__CGSCC_OPM-NEXT: store i8* [[CALL]], i8** bitcast (%struct.STy** getelementptr inbounds ([[STRUCT_STY]], %struct.STy* @global, i64 0, i32 2) to i8**), align 8 -; IS__CGSCC_OPM-NEXT: call fastcc void @nested_memory_callee() #[[ATTR15]] +; IS__CGSCC_OPM-NEXT: call fastcc void @nested_memory_callee(%struct.STy* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(24) [[LOCAL]]) #[[ATTR17]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_nested_memory -; IS__CGSCC_NPM-SAME: (float* nocapture nofree writeonly [[DST:%.*]], double* nocapture nofree readonly [[SRC:%.*]]) { +; IS__CGSCC_NPM-SAME: (float* nofree [[DST:%.*]], double* nofree [[SRC:%.*]]) { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 ; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast %struct.STy* [[LOCAL]] to i8* ; IS__CGSCC_NPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[LOCAL]], i64 0, i32 2 -; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 24, align 1 -; IS__CGSCC_NPM-NEXT: [[DST1:%.*]] = bitcast i8* [[TMP1]] to float** +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noalias dereferenceable_or_null(24) i8* @malloc(i64 noundef 24) +; IS__CGSCC_NPM-NEXT: [[DST1:%.*]] = bitcast i8* [[CALL]] to float** ; IS__CGSCC_NPM-NEXT: store float* [[DST]], float** [[DST1]], align 8 -; IS__CGSCC_NPM-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 8 -; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[SRC2]] to double** -; IS__CGSCC_NPM-NEXT: store double* [[SRC]], double** [[TMP2]], align 8 -; IS__CGSCC_NPM-NEXT: store i8* [[TMP1]], i8** bitcast (%struct.STy** getelementptr inbounds ([[STRUCT_STY]], %struct.STy* @global, i64 0, i32 2) to i8**), align 8 -; IS__CGSCC_NPM-NEXT: call fastcc void @nested_memory_callee() #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 8 +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[SRC2]] to double** +; IS__CGSCC_NPM-NEXT: store double* [[SRC]], double** [[TMP1]], align 8 +; IS__CGSCC_NPM-NEXT: store i8* [[CALL]], i8** bitcast (%struct.STy** getelementptr inbounds ([[STRUCT_STY]], %struct.STy* @global, i64 0, i32 2) to i8**), align 8 +; IS__CGSCC_NPM-NEXT: call fastcc void @nested_memory_callee(float* nofree nonnull align 4294967296 undef, double* nofree nonnull align 4294967296 undef, %struct.STy* nofree noundef nonnull align 8 dereferenceable(24) @global) #[[ATTR16]] ; IS__CGSCC_NPM-NEXT: ret void ; entry: @@ -3767,33 +4058,74 @@ entry: } define internal fastcc void @nested_memory_callee(%struct.STy* nocapture readonly %S) nofree norecurse nounwind uwtable { -; IS________OPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable -; IS________OPM-LABEL: define {{[^@]+}}@nested_memory_callee -; IS________OPM-SAME: () #[[ATTR10:[0-9]+]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** getelementptr inbounds ([[STRUCT_STY:%.*]], %struct.STy* @global, i64 0, i32 2), align 8 -; IS________OPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 1 -; IS________OPM-NEXT: [[TMP1:%.*]] = load double*, double** [[SRC]], align 8 -; IS________OPM-NEXT: [[TMP2:%.*]] = load double, double* [[TMP1]], align 8 -; IS________OPM-NEXT: [[CONV:%.*]] = fptrunc double [[TMP2]] to float -; IS________OPM-NEXT: [[DST:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 0 -; IS________OPM-NEXT: [[TMP3:%.*]] = load float*, float** [[DST]], align 8 -; IS________OPM-NEXT: store float [[CONV]], float* [[TMP3]], align 4 -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nested_memory_callee +; IS__TUNIT_OPM-SAME: () #[[ATTR10:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** getelementptr inbounds ([[STRUCT_STY:%.*]], %struct.STy* @global, i64 0, i32 2), align 8 +; IS__TUNIT_OPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 1 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load double*, double** [[SRC]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = load double, double* [[TMP1]], align 8 +; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = fptrunc double [[TMP2]] to float +; IS__TUNIT_OPM-NEXT: [[DST:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 0 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load float*, float** [[DST]], align 8 +; IS__TUNIT_OPM-NEXT: store float [[CONV]], float* [[TMP3]], align 4 +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable -; IS________NPM-LABEL: define {{[^@]+}}@nested_memory_callee -; IS________NPM-SAME: () #[[ATTR8:[0-9]+]] { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** getelementptr inbounds ([[STRUCT_STY:%.*]], %struct.STy* @global, i64 0, i32 2), align 8 -; IS________NPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 1 -; IS________NPM-NEXT: [[TMP1:%.*]] = load double*, double** [[SRC]], align 8 -; IS________NPM-NEXT: [[TMP2:%.*]] = load double, double* [[TMP1]], align 8 -; IS________NPM-NEXT: [[CONV:%.*]] = fptrunc double [[TMP2]] to float -; IS________NPM-NEXT: [[DST:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 0 -; IS________NPM-NEXT: [[TMP3:%.*]] = load float*, float** [[DST]], align 8 -; IS________NPM-NEXT: store float [[CONV]], float* [[TMP3]], align 4 -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@nested_memory_callee +; IS__TUNIT_NPM-SAME: () #[[ATTR8:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** getelementptr inbounds ([[STRUCT_STY:%.*]], %struct.STy* @global, i64 0, i32 2), align 8 +; IS__TUNIT_NPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 1 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load double*, double** [[SRC]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load double, double* [[TMP1]], align 8 +; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = fptrunc double [[TMP2]] to float +; IS__TUNIT_NPM-NEXT: [[DST:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 0 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load float*, float** [[DST]], align 8 +; IS__TUNIT_NPM-NEXT: store float [[CONV]], float* [[TMP3]], align 4 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nested_memory_callee +; IS__CGSCC_OPM-SAME: (%struct.STy* noalias nocapture nofree noundef nonnull readonly align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY:%.*]], %struct.STy* [[S]], i64 0, i32 2 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load %struct.STy*, %struct.STy** [[INNER]], align 8 +; IS__CGSCC_OPM-NEXT: [[INNER1:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP0]], i64 0, i32 2 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load %struct.STy*, %struct.STy** [[INNER1]], align 8 +; IS__CGSCC_OPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP1]], i64 0, i32 1 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load double*, double** [[SRC]], align 8 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = load double, double* [[TMP2]], align 8 +; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = fptrunc double [[TMP3]] to float +; IS__CGSCC_OPM-NEXT: [[DST:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP1]], i64 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load float*, float** [[DST]], align 8 +; IS__CGSCC_OPM-NEXT: store float [[CONV]], float* [[TMP4]], align 4 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind willreturn uwtable +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@nested_memory_callee +; IS__CGSCC_NPM-SAME: (float* [[TMP0:%.*]], double* [[TMP1:%.*]], %struct.STy* [[TMP2:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[S_PRIV:%.*]] = alloca [[STRUCT_STY:%.*]], align 8 +; IS__CGSCC_NPM-NEXT: [[S_PRIV_CAST:%.*]] = bitcast %struct.STy* [[S_PRIV]] to float** +; IS__CGSCC_NPM-NEXT: store float* [[TMP0]], float** [[S_PRIV_CAST]], align 8 +; IS__CGSCC_NPM-NEXT: [[S_PRIV_0_1:%.*]] = getelementptr [[STRUCT_STY]], %struct.STy* [[S_PRIV]], i64 0, i32 1 +; IS__CGSCC_NPM-NEXT: store double* [[TMP1]], double** [[S_PRIV_0_1]], align 8 +; IS__CGSCC_NPM-NEXT: [[S_PRIV_0_2:%.*]] = getelementptr [[STRUCT_STY]], %struct.STy* [[S_PRIV]], i64 0, i32 2 +; IS__CGSCC_NPM-NEXT: store %struct.STy* [[TMP2]], %struct.STy** [[S_PRIV_0_2]], align 8 +; IS__CGSCC_NPM-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[S_PRIV]], i64 0, i32 2 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load %struct.STy*, %struct.STy** [[INNER]], align 8 +; IS__CGSCC_NPM-NEXT: [[INNER1:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP3]], i64 0, i32 2 +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load %struct.STy*, %struct.STy** [[INNER1]], align 8 +; IS__CGSCC_NPM-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP4]], i64 0, i32 1 +; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = load double*, double** [[SRC]], align 8 +; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = load double, double* [[TMP5]], align 8 +; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = fptrunc double [[TMP6]] to float +; IS__CGSCC_NPM-NEXT: [[DST:%.*]] = getelementptr inbounds [[STRUCT_STY]], %struct.STy* [[TMP4]], i64 0, i32 0 +; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = load float*, float** [[DST]], align 8 +; IS__CGSCC_NPM-NEXT: store float [[CONV]], float* [[TMP7]], align 4 +; IS__CGSCC_NPM-NEXT: ret void ; entry: %inner = getelementptr inbounds %struct.STy, %struct.STy* %S, i64 0, i32 2 @@ -3813,91 +4145,177 @@ entry: ; Make sure the access %1 is not forwarded to the loads %2 and %3 as the indices are ; varying and the accesses thus not "exact". This used to simplify %cmp12 to true. define hidden void @no_propagation_of_unknown_index_access(i32* %in, i32* %out, i32 %idx) #0 { -; IS________OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind -; IS________OPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access -; IS________OPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR11:[0-9]+]] { -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 -; IS________OPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) -; IS________OPM-NEXT: br label [[FOR_COND:%.*]] -; IS________OPM: for.cond: -; IS________OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] -; IS________OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128 -; IS________OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] -; IS________OPM: for.cond.cleanup: -; IS________OPM-NEXT: br label [[FOR_COND4:%.*]] -; IS________OPM: for.body: -; IS________OPM-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64 -; IS________OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[IN]], i64 [[IDXPROM]] -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; IS________OPM-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM]] -; IS________OPM-NEXT: store i32 [[TMP1]], i32* [[ARRAYIDX2]], align 4 -; IS________OPM-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 -; IS________OPM-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]] -; IS________OPM: for.cond4: -; IS________OPM-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ] -; IS________OPM-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 -; IS________OPM-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] -; IS________OPM: for.cond.cleanup6: -; IS________OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) -; IS________OPM-NEXT: ret void -; IS________OPM: for.body7: -; IS________OPM-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 -; IS________OPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM8]] -; IS________OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX9]], align 4 -; IS________OPM-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64 -; IS________OPM-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM10]] -; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX11]], align 4 -; IS________OPM-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP2]], [[TMP3]] -; IS________OPM-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32 -; IS________OPM-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, i32* [[OUT]], i64 [[IDXPROM8]] -; IS________OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX14]], align 4 -; IS________OPM-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1 -; IS________OPM-NEXT: br label [[FOR_COND4]], !llvm.loop [[LOOP12:![0-9]+]] +; IS__TUNIT_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) +; IS__TUNIT_OPM-NEXT: br label [[FOR_COND:%.*]] +; IS__TUNIT_OPM: for.cond: +; IS__TUNIT_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] +; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128 +; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] +; IS__TUNIT_OPM: for.cond.cleanup: +; IS__TUNIT_OPM-NEXT: br label [[FOR_COND4:%.*]] +; IS__TUNIT_OPM: for.body: +; IS__TUNIT_OPM-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64 +; IS__TUNIT_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[IN]], i64 [[IDXPROM]] +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; IS__TUNIT_OPM-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM]] +; IS__TUNIT_OPM-NEXT: store i32 [[TMP1]], i32* [[ARRAYIDX2]], align 4 +; IS__TUNIT_OPM-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 +; IS__TUNIT_OPM-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]] +; IS__TUNIT_OPM: for.cond4: +; IS__TUNIT_OPM-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ] +; IS__TUNIT_OPM-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 +; IS__TUNIT_OPM-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] +; IS__TUNIT_OPM: for.cond.cleanup6: +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) +; IS__TUNIT_OPM-NEXT: ret void +; IS__TUNIT_OPM: for.body7: +; IS__TUNIT_OPM-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 +; IS__TUNIT_OPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM8]] +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX9]], align 4 +; IS__TUNIT_OPM-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64 +; IS__TUNIT_OPM-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM10]] +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX11]], align 4 +; IS__TUNIT_OPM-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP2]], [[TMP3]] +; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32 +; IS__TUNIT_OPM-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, i32* [[OUT]], i64 [[IDXPROM8]] +; IS__TUNIT_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX14]], align 4 +; IS__TUNIT_OPM-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1 +; IS__TUNIT_OPM-NEXT: br label [[FOR_COND4]], !llvm.loop [[TBAA12]] ; -; IS________NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn -; IS________NPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access -; IS________NPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR1:[0-9]+]] { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 -; IS________NPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR12]] -; IS________NPM-NEXT: br label [[FOR_COND:%.*]] -; IS________NPM: for.cond: -; IS________NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] -; IS________NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128 -; IS________NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] -; IS________NPM: for.cond.cleanup: -; IS________NPM-NEXT: br label [[FOR_COND4:%.*]] -; IS________NPM: for.body: -; IS________NPM-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64 -; IS________NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[IN]], i64 [[IDXPROM]] -; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 -; IS________NPM-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM]] -; IS________NPM-NEXT: store i32 [[TMP1]], i32* [[ARRAYIDX2]], align 4 -; IS________NPM-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 -; IS________NPM-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]] -; IS________NPM: for.cond4: -; IS________NPM-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ] -; IS________NPM-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 -; IS________NPM-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] -; IS________NPM: for.cond.cleanup6: -; IS________NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR12]] -; IS________NPM-NEXT: ret void -; IS________NPM: for.body7: -; IS________NPM-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 -; IS________NPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM8]] -; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX9]], align 4 -; IS________NPM-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64 -; IS________NPM-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM10]] -; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX11]], align 4 -; IS________NPM-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP2]], [[TMP3]] -; IS________NPM-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32 -; IS________NPM-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, i32* [[OUT]], i64 [[IDXPROM8]] -; IS________NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX14]], align 4 -; IS________NPM-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1 -; IS________NPM-NEXT: br label [[FOR_COND4]], !llvm.loop [[LOOP12:![0-9]+]] +; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR1]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]] +; IS__TUNIT_NPM: for.cond: +; IS__TUNIT_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] +; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128 +; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] +; IS__TUNIT_NPM: for.cond.cleanup: +; IS__TUNIT_NPM-NEXT: br label [[FOR_COND4:%.*]] +; IS__TUNIT_NPM: for.body: +; IS__TUNIT_NPM-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64 +; IS__TUNIT_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[IN]], i64 [[IDXPROM]] +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; IS__TUNIT_NPM-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM]] +; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[ARRAYIDX2]], align 4 +; IS__TUNIT_NPM-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 +; IS__TUNIT_NPM-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]] +; IS__TUNIT_NPM: for.cond4: +; IS__TUNIT_NPM-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ] +; IS__TUNIT_NPM-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 +; IS__TUNIT_NPM-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] +; IS__TUNIT_NPM: for.cond.cleanup6: +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR12]] +; IS__TUNIT_NPM-NEXT: ret void +; IS__TUNIT_NPM: for.body7: +; IS__TUNIT_NPM-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 +; IS__TUNIT_NPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM8]] +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX9]], align 4 +; IS__TUNIT_NPM-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64 +; IS__TUNIT_NPM-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM10]] +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX11]], align 4 +; IS__TUNIT_NPM-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP2]], [[TMP3]] +; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32 +; IS__TUNIT_NPM-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, i32* [[OUT]], i64 [[IDXPROM8]] +; IS__TUNIT_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX14]], align 4 +; IS__TUNIT_NPM-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1 +; IS__TUNIT_NPM-NEXT: br label [[FOR_COND4]], !llvm.loop [[TBAA12]] +; +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) +; IS__CGSCC_OPM-NEXT: br label [[FOR_COND:%.*]] +; IS__CGSCC_OPM: for.cond: +; IS__CGSCC_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] +; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128 +; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] +; IS__CGSCC_OPM: for.cond.cleanup: +; IS__CGSCC_OPM-NEXT: br label [[FOR_COND4:%.*]] +; IS__CGSCC_OPM: for.body: +; IS__CGSCC_OPM-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64 +; IS__CGSCC_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[IN]], i64 [[IDXPROM]] +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; IS__CGSCC_OPM-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM]] +; IS__CGSCC_OPM-NEXT: store i32 [[TMP1]], i32* [[ARRAYIDX2]], align 4 +; IS__CGSCC_OPM-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 +; IS__CGSCC_OPM-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]] +; IS__CGSCC_OPM: for.cond4: +; IS__CGSCC_OPM-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ] +; IS__CGSCC_OPM-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 +; IS__CGSCC_OPM-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] +; IS__CGSCC_OPM: for.cond.cleanup6: +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) +; IS__CGSCC_OPM-NEXT: ret void +; IS__CGSCC_OPM: for.body7: +; IS__CGSCC_OPM-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 +; IS__CGSCC_OPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM8]] +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX9]], align 4 +; IS__CGSCC_OPM-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64 +; IS__CGSCC_OPM-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM10]] +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX11]], align 4 +; IS__CGSCC_OPM-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP2]], [[TMP3]] +; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32 +; IS__CGSCC_OPM-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, i32* [[OUT]], i64 [[IDXPROM8]] +; IS__CGSCC_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX14]], align 4 +; IS__CGSCC_OPM-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1 +; IS__CGSCC_OPM-NEXT: br label [[FOR_COND4]], !llvm.loop [[TBAA12]] +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readonly [[IN:%.*]], i32* nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16 +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast [128 x i32]* [[BUF]] to i8* +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND:%.*]] +; IS__CGSCC_NPM: for.cond: +; IS__CGSCC_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ] +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128 +; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]] +; IS__CGSCC_NPM: for.cond.cleanup: +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND4:%.*]] +; IS__CGSCC_NPM: for.body: +; IS__CGSCC_NPM-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64 +; IS__CGSCC_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[IN]], i64 [[IDXPROM]] +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; IS__CGSCC_NPM-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM]] +; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[ARRAYIDX2]], align 4 +; IS__CGSCC_NPM-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]] +; IS__CGSCC_NPM: for.cond4: +; IS__CGSCC_NPM-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ] +; IS__CGSCC_NPM-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128 +; IS__CGSCC_NPM-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]] +; IS__CGSCC_NPM: for.cond.cleanup6: +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 512, i8* nocapture nofree noundef nonnull align 16 dereferenceable(512) [[TMP0]]) #[[ATTR14]] +; IS__CGSCC_NPM-NEXT: ret void +; IS__CGSCC_NPM: for.body7: +; IS__CGSCC_NPM-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64 +; IS__CGSCC_NPM-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM8]] +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX9]], align 4 +; IS__CGSCC_NPM-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64 +; IS__CGSCC_NPM-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], [128 x i32]* [[BUF]], i64 0, i64 [[IDXPROM10]] +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX11]], align 4 +; IS__CGSCC_NPM-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP2]], [[TMP3]] +; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32 +; IS__CGSCC_NPM-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, i32* [[OUT]], i64 [[IDXPROM8]] +; IS__CGSCC_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX14]], align 4 +; IS__CGSCC_NPM-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1 +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND4]], !llvm.loop [[TBAA12]] ; entry: %buf = alloca [128 x i32], align 16 @@ -3962,33 +4380,47 @@ define internal i1 @alloca_non_unique(i32* %p, i32 %in, i1 %c) { ; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]] ; IS__TUNIT_OPM-NEXT: ret i1 [[CMP]] ; -; IS________NPM: Function Attrs: argmemonly nofree nosync nounwind -; IS________NPM-LABEL: define {{[^@]+}}@alloca_non_unique -; IS________NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] { -; IS________NPM-NEXT: [[A:%.*]] = alloca i32, align 4 -; IS________NPM-NEXT: store i32 [[IN]], i32* [[A]], align 4 -; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; IS________NPM: t: -; IS________NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR16:[0-9]+]] -; IS________NPM-NEXT: ret i1 [[R]] -; IS________NPM: f: -; IS________NPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 -; IS________NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]] -; IS________NPM-NEXT: ret i1 [[CMP]] +; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@alloca_non_unique +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__TUNIT_NPM-NEXT: store i32 [[IN]], i32* [[A]], align 4 +; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT_NPM: t: +; IS__TUNIT_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR16:[0-9]+]] +; IS__TUNIT_NPM-NEXT: ret i1 [[R]] +; IS__TUNIT_NPM: f: +; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 +; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]] +; IS__TUNIT_NPM-NEXT: ret i1 [[CMP]] ; ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@alloca_non_unique -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR13:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: store i32 [[IN]], i32* [[A]], align 4 ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_OPM: t: -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR17:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR19:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; IS__CGSCC_OPM: f: ; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 ; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]] ; IS__CGSCC_OPM-NEXT: ret i1 [[CMP]] +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@alloca_non_unique +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32, align 4 +; IS__CGSCC_NPM-NEXT: store i32 [[IN]], i32* [[A]], align 4 +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_NPM: t: +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR18:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i1 [[R]] +; IS__CGSCC_NPM: f: +; IS__CGSCC_NPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 4 +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]] +; IS__CGSCC_NPM-NEXT: ret i1 [[CMP]] ; %a = alloca i32 store i32 %in, i32* %a @@ -4016,16 +4448,16 @@ define i1 @alloca_non_unique_caller(i32 %in, i1 %c) { ; IS__TUNIT_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR16]] ; IS__TUNIT_NPM-NEXT: ret i1 [[R]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@alloca_non_unique_caller -; IS__CGSCC_OPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR7]] { -; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR15]] +; IS__CGSCC_OPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR14:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR17]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@alloca_non_unique_caller -; IS__CGSCC_NPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR10:[0-9]+]] { -; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR14]] +; IS__CGSCC_NPM-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(i32* undef, i32 [[IN]], i1 [[C]]) #[[ATTR16]] ; IS__CGSCC_NPM-NEXT: ret i1 [[R]] ; %r = call i1 @alloca_non_unique(i32* undef, i32 %in, i1 %c) @@ -4107,41 +4539,45 @@ define i1 @alloca_non_unique_caller(i32 %in, i1 %c) { ; IS__TUNIT_NPM: attributes #[[ATTR16]] = { nofree nosync nounwind } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind willreturn uwtable } -; IS__CGSCC_OPM: attributes #[[ATTR11]] = { argmemonly nofree norecurse nosync nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR12]] = { argmemonly nofree nosync nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR13]] = { willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nounwind willreturn writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR15]] = { nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR16]] = { norecurse } -; IS__CGSCC_OPM: attributes #[[ATTR17]] = { nofree nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind readnone } +; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind willreturn uwtable } +; IS__CGSCC_OPM: attributes #[[ATTR12]] = { argmemonly nofree norecurse nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR13]] = { argmemonly nofree nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree nosync nounwind readnone } +; IS__CGSCC_OPM: attributes #[[ATTR15]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR17]] = { nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR18]] = { norecurse } +; IS__CGSCC_OPM: attributes #[[ATTR19]] = { nofree nosync nounwind } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR2:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn uwtable } -; IS__CGSCC_NPM: attributes #[[ATTR9]] = { argmemonly nofree nosync nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR12]] = { willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR13]] = { nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR14]] = { nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR15]] = { norecurse } -; IS__CGSCC_NPM: attributes #[[ATTR16]] = { nofree nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR10]] = { argmemonly nofree norecurse nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR11]] = { argmemonly nofree nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nofree nosync nounwind readnone } +; IS__CGSCC_NPM: attributes #[[ATTR13:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR14]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR16]] = { nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR17]] = { norecurse } +; IS__CGSCC_NPM: attributes #[[ATTR18]] = { nofree nosync nounwind } ;. ; CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} ; CHECK: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1} diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll index 5e042c832e22..0279911cedd8 100644 --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -72,18 +72,48 @@ define i32 @return1() { } define i32 @test2_1(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@test2_1 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] -; CHECK: if.true: -; CHECK-NEXT: [[RET0:%.*]] = add i32 0, 1 -; CHECK-NEXT: br label [[END:%.*]] -; CHECK: if.false: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] -; CHECK-NEXT: ret i32 1 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_1 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__TUNIT____: if.true: +; IS__TUNIT____-NEXT: [[RET0:%.*]] = add i32 0, 1 +; IS__TUNIT____-NEXT: br label [[END:%.*]] +; IS__TUNIT____: if.false: +; IS__TUNIT____-NEXT: br label [[END]] +; IS__TUNIT____: end: +; IS__TUNIT____-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] +; IS__TUNIT____-NEXT: ret i32 1 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2_1 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__CGSCC_OPM: if.true: +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @return0() #[[ATTR12:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[RET0:%.*]] = add i32 [[CALL]], 1 +; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] +; IS__CGSCC_OPM: if.false: +; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: br label [[END]] +; IS__CGSCC_OPM: end: +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] +; IS__CGSCC_OPM-NEXT: ret i32 1 +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2_1 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__CGSCC_NPM: if.true: +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = tail call i32 @return0() #[[ATTR11:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[RET0:%.*]] = add i32 [[CALL]], 1 +; IS__CGSCC_NPM-NEXT: br label [[END:%.*]] +; IS__CGSCC_NPM: if.false: +; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: br label [[END]] +; IS__CGSCC_NPM: end: +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] +; IS__CGSCC_NPM-NEXT: ret i32 1 ; br i1 %c, label %if.true, label %if.false if.true: @@ -103,10 +133,22 @@ end: define i32 @test2_2(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@test2_2 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i32 1 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_2 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i32 1 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2_2 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call noundef i32 @test2_1(i1 [[C]]) #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i32 [[RET]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2_2 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = tail call noundef i32 @test2_1(i1 [[C]]) #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i32 [[RET]] ; %ret = tail call i32 @test2_1(i1 %c) ret i32 %ret @@ -114,17 +156,43 @@ define i32 @test2_2(i1 %c) { declare void @use(i32) define void @test3(i1 %c) { -; CHECK-LABEL: define {{[^@]+}}@test3 -; CHECK-SAME: (i1 [[C:%.*]]) { -; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] -; CHECK: if.true: -; CHECK-NEXT: br label [[END:%.*]] -; CHECK: if.false: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] -; CHECK-NEXT: tail call void @use(i32 noundef 1) -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test3 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) { +; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__TUNIT____: if.true: +; IS__TUNIT____-NEXT: br label [[END:%.*]] +; IS__TUNIT____: if.false: +; IS__TUNIT____-NEXT: br label [[END]] +; IS__TUNIT____: end: +; IS__TUNIT____-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] +; IS__TUNIT____-NEXT: tail call void @use(i32 noundef 1) +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) { +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__CGSCC_OPM: if.true: +; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] +; IS__CGSCC_OPM: if.false: +; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: br label [[END]] +; IS__CGSCC_OPM: end: +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] +; IS__CGSCC_OPM-NEXT: tail call void @use(i32 noundef [[R]]) +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test3 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) { +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] +; IS__CGSCC_NPM: if.true: +; IS__CGSCC_NPM-NEXT: br label [[END:%.*]] +; IS__CGSCC_NPM: if.false: +; IS__CGSCC_NPM-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: br label [[END]] +; IS__CGSCC_NPM: end: +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] +; IS__CGSCC_NPM-NEXT: tail call void @use(i32 noundef [[R]]) +; IS__CGSCC_NPM-NEXT: ret void ; br i1 %c, label %if.true, label %if.false if.true: @@ -233,10 +301,22 @@ f: } define i1 @ipccp2() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@ipccp2 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp2 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp2 +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2i() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i1 [[R]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp2 +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2i() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i1 [[R]] ; %r = call i1 @ipccp2i(i1 true) ret i1 %r @@ -261,10 +341,22 @@ f: } define i1 @ipccp2b() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@ipccp2b -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp2b +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp2b +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2ib() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i1 [[R]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp2b +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i1 @ipccp2ib() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i1 [[R]] ; %r = call i1 @ipccp2ib(i1 true) ret i1 %r @@ -290,10 +382,22 @@ f: } define i32 @ipccp3() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@ipccp3 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i32 7 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp3 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i32 7 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp3 +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp3i() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i32 [[R]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp3 +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp3i() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i32 [[R]] ; %r = call i32 @ipccp3i(i32 7) ret i32 %r @@ -302,12 +406,12 @@ define i32 @ipccp3() { define internal i32 @ipccp4ia(i1 %c) { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp4ia -; IS__CGSCC____-SAME: () #[[ATTR1]] { -; IS__CGSCC____-NEXT: br label [[T:%.*]] +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: ret i32 0 ; IS__CGSCC____: f: -; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____-NEXT: ret i32 1 ; br i1 %c, label %t, label %f t: @@ -316,14 +420,25 @@ f: ret i32 1 } define internal i32 @ipccp4ib(i32 %a) { -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp4ib -; IS__CGSCC____-SAME: () #[[ATTR1]] { -; IS__CGSCC____-NEXT: br label [[T:%.*]] -; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: ret i32 0 -; IS__CGSCC____: f: -; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp4ib +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: br label [[T:%.*]] +; IS__CGSCC_OPM: t: +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ia(i1 noundef true) #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i32 [[R]] +; IS__CGSCC_OPM: f: +; IS__CGSCC_OPM-NEXT: unreachable +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp4ib +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: br label [[T:%.*]] +; IS__CGSCC_NPM: t: +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ia(i1 noundef true) #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i32 [[R]] +; IS__CGSCC_NPM: f: +; IS__CGSCC_NPM-NEXT: unreachable ; %c = icmp eq i32 %a, 7 br i1 %c, label %t, label %f @@ -335,14 +450,34 @@ f: } define i32 @ipccp4(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@ipccp4 -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: br label [[F]] -; CHECK: f: -; CHECK-NEXT: ret i32 0 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp4 +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: br label [[F]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ipccp4 +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_OPM: t: +; IS__CGSCC_OPM-NEXT: br label [[F]] +; IS__CGSCC_OPM: f: +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ib() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i32 [[R]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ipccp4 +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC_NPM: t: +; IS__CGSCC_NPM-NEXT: br label [[F]] +; IS__CGSCC_NPM: f: +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ib() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i32 [[R]] ; br i1 %c, label %t, label %f t: @@ -376,9 +511,9 @@ define i32* @complicated_args_inalloca(i32* %arg) { ; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call nonnull dereferenceable(4) i32* @test_inalloca(i32* noalias nofree writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR10:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_inalloca -; IS__CGSCC____-SAME: (i32* nofree noundef nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-SAME: (i32* nofree noundef nonnull readnone returned dereferenceable(4) [[ARG:%.*]]) #[[ATTR2:[0-9]+]] { ; IS__CGSCC____-NEXT: ret i32* [[ARG]] ; %call = call i32* @test_inalloca(i32* inalloca(i32) %arg) @@ -408,11 +543,17 @@ define i32* @complicated_args_preallocated() { ; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noundef nonnull align 4294967296 dereferenceable(4) i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 4294967296 null) #[[ATTR10]] [ "preallocated"(token [[C]]) ] ; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_preallocated -; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR12:[0-9]+]] -; IS__CGSCC____-NEXT: ret i32* null +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated +; IS__CGSCC_OPM-SAME: () #[[ATTR3:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR13:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret i32* null +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated +; IS__CGSCC_NPM-SAME: () #[[ATTR3:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR12:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret i32* null ; %c = call token @llvm.call.preallocated.setup(i32 1) %call = call i32* @test_preallocated(i32* preallocated(i32) null) ["preallocated"(token %c)] @@ -421,11 +562,17 @@ define i32* @complicated_args_preallocated() { define internal void @test_sret(%struct.X* sret(%struct.X) %a, %struct.X** %b) { ; -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@test_sret -; CHECK-SAME: (%struct.X* noalias nofree noundef nonnull writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_sret +; IS__TUNIT____-SAME: (%struct.X* noalias nofree noundef nonnull writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_sret +; IS__CGSCC____-SAME: (%struct.X* noalias nofree noundef nonnull writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC____-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8 +; IS__CGSCC____-NEXT: ret void ; store %struct.X* %a, %struct.X** %b ret void @@ -446,9 +593,9 @@ define void @complicated_args_sret(%struct.X** %b) { ; IS__TUNIT_NPM-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 null, %struct.X** nocapture nofree writeonly align 8 [[B]]) #[[ATTR12:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_sret -; IS__CGSCC____-SAME: (%struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-SAME: (%struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR5:[0-9]+]] { ; IS__CGSCC____-NEXT: unreachable ; call void @test_sret(%struct.X* sret(%struct.X) null, %struct.X** %b) @@ -464,10 +611,15 @@ define internal %struct.X* @test_nest(%struct.X* nest %a) { ret %struct.X* %a } define %struct.X* @complicated_args_nest() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@complicated_args_nest -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret %struct.X* null +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_nest +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret %struct.X* null +; +; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_nest +; IS__CGSCC____-SAME: () #[[ATTR2]] { +; IS__CGSCC____-NEXT: ret %struct.X* null ; %call = call %struct.X* @test_nest(%struct.X* null) ret %struct.X* %call @@ -475,22 +627,39 @@ define %struct.X* @complicated_args_nest() { @S = external global %struct.X define internal void @test_byval(%struct.X* byval(%struct.X) %a) { -; IS________OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; IS________OPM-LABEL: define {{[^@]+}}@test_byval -; IS________OPM-SAME: (%struct.X* noalias nocapture nofree noundef nonnull writeonly byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR3]] { -; IS________OPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A]], i32 0, i32 0 -; IS________OPM-NEXT: store i8* null, i8** [[G0]], align 8 -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test_byval +; IS__TUNIT_OPM-SAME: (%struct.X* noalias nocapture nofree noundef nonnull writeonly byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR3]] { +; IS__TUNIT_OPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: store i8* null, i8** [[G0]], align 8 +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; IS________NPM-LABEL: define {{[^@]+}}@test_byval -; IS________NPM-SAME: (i8* [[TMP0:%.*]]) #[[ATTR3]] { -; IS________NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 -; IS________NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** -; IS________NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8 -; IS________NPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A_PRIV]], i32 0, i32 0 -; IS________NPM-NEXT: store i8* null, i8** [[G0]], align 8 -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test_byval +; IS__TUNIT_NPM-SAME: (i8* [[TMP0:%.*]]) #[[ATTR3]] { +; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 +; IS__TUNIT_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** +; IS__TUNIT_NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8 +; IS__TUNIT_NPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A_PRIV]], i32 0, i32 0 +; IS__TUNIT_NPM-NEXT: store i8* null, i8** [[G0]], align 8 +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_byval +; IS__CGSCC_OPM-SAME: (%struct.X* noalias nocapture nofree noundef nonnull writeonly byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] { +; IS__CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: store i8* null, i8** [[G0]], align 8 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_byval +; IS__CGSCC_NPM-SAME: (i8* [[TMP0:%.*]]) #[[ATTR4]] { +; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 +; IS__CGSCC_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X* [[A_PRIV]] to i8** +; IS__CGSCC_NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]], align 8 +; IS__CGSCC_NPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]], %struct.X* [[A_PRIV]], i32 0, i32 0 +; IS__CGSCC_NPM-NEXT: store i8* null, i8** [[G0]], align 8 +; IS__CGSCC_NPM-NEXT: ret void ; %g0 = getelementptr %struct.X, %struct.X* %a, i32 0, i32 0 store i8* null, i8** %g0 @@ -511,15 +680,17 @@ define void @complicated_args_byval() { ; IS__TUNIT_NPM-NEXT: call void @test_byval(i8* [[TMP1]]) #[[ATTR12]] ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_byval -; IS__CGSCC_OPM-SAME: () #[[ATTR1]] { -; IS__CGSCC_OPM-NEXT: call void @test_byval(%struct.X* noalias nocapture nofree noundef nonnull readnone byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) @S) #[[ATTR13:[0-9]+]] +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: call void @test_byval(%struct.X* noalias nocapture nofree noundef nonnull readnone byval([[STRUCT_X:%.*]]) align 8 dereferenceable(8) @S) #[[ATTR14:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval -; IS__CGSCC_NPM-SAME: () #[[ATTR4:[0-9]+]] { +; IS__CGSCC_NPM-SAME: () #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0), align 8 +; IS__CGSCC_NPM-NEXT: call void @test_byval(i8* nofree writeonly [[TMP1]]) #[[ATTR13:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret void ; call void @test_byval(%struct.X* byval(%struct.X) @S) @@ -569,7 +740,7 @@ define i8* @complicated_args_byval2() { ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval2() { ; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0), align 8 -; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2(i8* noalias nofree readnone "no-capture-maybe-returned" [[TMP1]]) +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2(i8* [[TMP1]]) ; IS__CGSCC_NPM-NEXT: ret i8* [[C]] ; %c = call i8* @test_byval2(%struct.X* byval(%struct.X) @S) @@ -600,32 +771,32 @@ define void @fixpoint_changed(i32* %p) { ; IS__TUNIT_OPM: for.end: ; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; IS________NPM-LABEL: define {{[^@]+}}@fixpoint_changed -; IS________NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] { -; IS________NPM-NEXT: entry: -; IS________NPM-NEXT: br label [[FOR_COND:%.*]] -; IS________NPM: for.cond: -; IS________NPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ] -; IS________NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30 -; IS________NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] -; IS________NPM: for.body: -; IS________NPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [ -; IS________NPM-NEXT: i32 1, label [[SW_BB:%.*]] -; IS________NPM-NEXT: ] -; IS________NPM: sw.bb: -; IS________NPM-NEXT: br label [[SW_EPILOG]] -; IS________NPM: sw.epilog: -; IS________NPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ] -; IS________NPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4 -; IS________NPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1 -; IS________NPM-NEXT: br label [[FOR_COND]] -; IS________NPM: for.end: -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fixpoint_changed +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] { +; IS__TUNIT_NPM-NEXT: entry: +; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]] +; IS__TUNIT_NPM: for.cond: +; IS__TUNIT_NPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ] +; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30 +; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +; IS__TUNIT_NPM: for.body: +; IS__TUNIT_NPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [ +; IS__TUNIT_NPM-NEXT: i32 1, label [[SW_BB:%.*]] +; IS__TUNIT_NPM-NEXT: ] +; IS__TUNIT_NPM: sw.bb: +; IS__TUNIT_NPM-NEXT: br label [[SW_EPILOG]] +; IS__TUNIT_NPM: sw.epilog: +; IS__TUNIT_NPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ] +; IS__TUNIT_NPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4 +; IS__TUNIT_NPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1 +; IS__TUNIT_NPM-NEXT: br label [[FOR_COND]] +; IS__TUNIT_NPM: for.end: +; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fixpoint_changed -; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR4:[0-9]+]] { +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR6:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: br label [[FOR_COND:%.*]] ; IS__CGSCC_OPM: for.cond: @@ -646,6 +817,29 @@ define void @fixpoint_changed(i32* %p) { ; IS__CGSCC_OPM: for.end: ; IS__CGSCC_OPM-NEXT: ret void ; +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fixpoint_changed +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR4]] { +; IS__CGSCC_NPM-NEXT: entry: +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND:%.*]] +; IS__CGSCC_NPM: for.cond: +; IS__CGSCC_NPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ] +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30 +; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] +; IS__CGSCC_NPM: for.body: +; IS__CGSCC_NPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [ +; IS__CGSCC_NPM-NEXT: i32 1, label [[SW_BB:%.*]] +; IS__CGSCC_NPM-NEXT: ] +; IS__CGSCC_NPM: sw.bb: +; IS__CGSCC_NPM-NEXT: br label [[SW_EPILOG]] +; IS__CGSCC_NPM: sw.epilog: +; IS__CGSCC_NPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ] +; IS__CGSCC_NPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4 +; IS__CGSCC_NPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1 +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND]] +; IS__CGSCC_NPM: for.end: +; IS__CGSCC_NPM-NEXT: ret void +; entry: br label %for.cond @@ -674,55 +868,127 @@ for.end: ; Check we merge undef and a constant properly. define i8 @caller0() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller0 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 49 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller0 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 49 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller0 +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i8 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller0 +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c } define i8 @caller1() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller1 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 49 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller1 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 49 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller1 +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i8 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller1 +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c } define i8 @caller2() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller2 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 49 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 49 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller2 +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i8 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller2 +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c } define i8 @caller_middle() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller_middle -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 49 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller_middle +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 49 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller_middle +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i8 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller_middle +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 42) ret i8 %c } define i8 @caller3() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller3 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 49 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller3 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 49 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller3 +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i8 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller3 +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c } define i8 @caller4() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@caller4 -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i8 49 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller4 +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i8 49 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller4 +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i8 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller4 +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i8 [[C]] ; %c = call i8 @callee(i8 undef) ret i8 %c @@ -744,11 +1010,19 @@ define void @user_as3() { ; IS__TUNIT____-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC____-LABEL: define {{[^@]+}}@user_as3 -; IS__CGSCC____-SAME: () #[[ATTR5:[0-9]+]] { -; IS__CGSCC____-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4 -; IS__CGSCC____-NEXT: ret void +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@user_as3 +; IS__CGSCC_OPM-SAME: () #[[ATTR7:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call fastcc align 4 i32 addrspace(3)* @const_ptr_return_as3() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: store i32 0, i32 addrspace(3)* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@user_as3 +; IS__CGSCC_NPM-SAME: () #[[ATTR6:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call fastcc align 4 i32 addrspace(3)* @const_ptr_return_as3() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: store i32 0, i32 addrspace(3)* [[CALL]], align 4 +; IS__CGSCC_NPM-NEXT: ret void ; %call = call fastcc i32 addrspace(3)* @const_ptr_return_as3() store i32 0, i32 addrspace(3)* %call @@ -761,11 +1035,19 @@ define void @user() { ; IS__TUNIT____-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly -; IS__CGSCC____-LABEL: define {{[^@]+}}@user -; IS__CGSCC____-SAME: () #[[ATTR5]] { -; IS__CGSCC____-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4 -; IS__CGSCC____-NEXT: ret void +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@user +; IS__CGSCC_OPM-SAME: () #[[ATTR7]] { +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call fastcc align 4 i32* @const_ptr_return() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[CALL]], align 4 +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@user +; IS__CGSCC_NPM-SAME: () #[[ATTR6]] { +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call fastcc align 4 i32* @const_ptr_return() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[CALL]], align 4 +; IS__CGSCC_NPM-NEXT: ret void ; %call = call fastcc i32* @const_ptr_return() store i32 0, i32* %call @@ -774,10 +1056,22 @@ define void @user() { define i1 @test_merge_with_undef_values_ptr(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i1 false +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 false +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_null(i1 [[C]]) #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i1 [[R1]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_null(i1 [[C]]) #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i1 [[R1]] ; %r1 = call i1 @undef_then_null(i1 %c, i32* undef, i32* undef) ret i1 %r1 @@ -785,7 +1079,7 @@ define i1 @test_merge_with_undef_values_ptr(i1 %c) { define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) { ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_then_null -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; IS__CGSCC____: a: ; IS__CGSCC____-NEXT: ret i1 false @@ -804,10 +1098,22 @@ b: } define i1 @test_merge_with_undef_values(i1 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@test_merge_with_undef_values -; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i1 false +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_merge_with_undef_values +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 false +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_1(i1 [[C]]) #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i1 [[R1]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_1(i1 [[C]]) #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i1 [[R1]] ; %r1 = call i1 @undef_then_1(i1 %c, i32 undef, i32 undef) ret i1 %r1 @@ -816,7 +1122,7 @@ define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) { ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_then_1 -; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR6]] { +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; IS__CGSCC____: a: ; IS__CGSCC____-NEXT: ret i1 false @@ -835,10 +1141,22 @@ b: } define i32 @test_select(i32 %c) { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@test_select -; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { -; CHECK-NEXT: ret i32 42 +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_select +; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i32 42 +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_select +; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call noundef i32 @select() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_select +; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call noundef i32 @select() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i32 [[CALL]] ; %call = call i32 @select(i1 1, i32 42, i32 %c) ret i32 %call @@ -907,13 +1225,21 @@ define internal void @unknown_calle_arg_is_undef(void (i32)* %fn, i32 %arg) { @g = internal constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (void (i8***)* @f1 to i8*), i8* bitcast (void (i1 (i8*)*)* @f2 to i8*)] } define internal void @f1(i8*** %a) { -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly -; CHECK-LABEL: define {{[^@]+}}@f1 -; CHECK-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR3]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[X:%.*]] = getelementptr { [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0 -; CHECK-NEXT: store i8** [[X]], i8*** [[A]], align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__TUNIT____-LABEL: define {{[^@]+}}@f1 +; IS__TUNIT____-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[X:%.*]] = getelementptr { [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0 +; IS__TUNIT____-NEXT: store i8** [[X]], i8*** [[A]], align 8 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly +; IS__CGSCC____-LABEL: define {{[^@]+}}@f1 +; IS__CGSCC____-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] { +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[X:%.*]] = getelementptr { [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0 +; IS__CGSCC____-NEXT: store i8** [[X]], i8*** [[A]], align 8 +; IS__CGSCC____-NEXT: ret void ; entry: %x = getelementptr { [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0 @@ -972,10 +1298,22 @@ entry: define i1 @test_cmp_null_after_cast() { -; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn -; CHECK-LABEL: define {{[^@]+}}@test_cmp_null_after_cast -; CHECK-SAME: () #[[ATTR1]] { -; CHECK-NEXT: ret i1 true +; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_cmp_null_after_cast +; IS__TUNIT____-SAME: () #[[ATTR1]] { +; IS__TUNIT____-NEXT: ret i1 true +; +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_cmp_null_after_cast +; IS__CGSCC_OPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call noundef i1 @cmp_null_after_cast() #[[ATTR12]] +; IS__CGSCC_OPM-NEXT: ret i1 [[C]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_cmp_null_after_cast +; IS__CGSCC_NPM-SAME: () #[[ATTR2]] { +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call noundef i1 @cmp_null_after_cast() #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i1 [[C]] ; %c = call i1 @cmp_null_after_cast(i32 0, i8 0) ret i1 %c @@ -995,12 +1333,19 @@ define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) { declare i8* @m() define i32 @test(i1 %c) { -; CHECK-LABEL: define {{[^@]+}}@test -; CHECK-SAME: (i1 [[C:%.*]]) { -; CHECK-NEXT: [[R1:%.*]] = call i32 @ctx_test1(i1 [[C]]) -; CHECK-NEXT: [[R2:%.*]] = call i32 @ctx_test2(i1 [[C]]), !range [[RNG0:![0-9]+]] -; CHECK-NEXT: [[ADD:%.*]] = add i32 [[R1]], [[R2]] -; CHECK-NEXT: ret i32 [[ADD]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) { +; IS__TUNIT____-NEXT: [[R1:%.*]] = call i32 @ctx_test1(i1 [[C]]) +; IS__TUNIT____-NEXT: [[R2:%.*]] = call i32 @ctx_test2(i1 [[C]]), !range [[RNG0:![0-9]+]] +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add i32 [[R1]], [[R2]] +; IS__TUNIT____-NEXT: ret i32 [[ADD]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) { +; IS__CGSCC____-NEXT: [[R1:%.*]] = call i32 @ctx_test1(i1 [[C]]) +; IS__CGSCC____-NEXT: [[R2:%.*]] = call i32 @ctx_test2(i1 [[C]]) +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add i32 [[R1]], [[R2]] +; IS__CGSCC____-NEXT: ret i32 [[ADD]] ; %r1 = call i32 @ctx_test1(i1 %c) %r2 = call i32 @ctx_test2(i1 %c) @@ -1091,27 +1436,29 @@ define i1 @test_liveness(i1 %c) { ; IS__TUNIT_NPM-NEXT: [[RC1:%.*]] = call noundef i1 @ret(i1 noundef [[P]]) #[[ATTR10]] ; IS__TUNIT_NPM-NEXT: ret i1 [[RC1]] ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_liveness -; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_OPM: t: ; IS__CGSCC_OPM-NEXT: br label [[F]] ; IS__CGSCC_OPM: f: ; IS__CGSCC_OPM-NEXT: [[P:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[T]] ] -; IS__CGSCC_OPM-NEXT: [[RC1:%.*]] = call noundef i1 @ret(i1 noundef [[P]]) #[[ATTR14:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[RC1:%.*]] = call noundef i1 @ret(i1 noundef [[P]]) #[[ATTR12]] ; IS__CGSCC_OPM-NEXT: ret i1 [[RC1]] ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_liveness -; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { +; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_NPM: t: ; IS__CGSCC_NPM-NEXT: br label [[F]] ; IS__CGSCC_NPM: f: -; IS__CGSCC_NPM-NEXT: ret i1 false +; IS__CGSCC_NPM-NEXT: [[P:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[T]] ] +; IS__CGSCC_NPM-NEXT: [[RC1:%.*]] = call noundef i1 @ret(i1 noundef [[P]]) #[[ATTR11]] +; IS__CGSCC_NPM-NEXT: ret i1 [[RC1]] ; entry: br i1 %c, label %t, label %f @@ -1197,15 +1544,25 @@ define internal i8 @memcpy_uses_store(i8 %arg) { ; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 ; IS__TUNIT_NPM-NEXT: ret i8 [[L]] ; -; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn -; IS__CGSCC____-LABEL: define {{[^@]+}}@memcpy_uses_store -; IS__CGSCC____-SAME: (i8 [[ARG:%.*]]) #[[ATTR7:[0-9]+]] { -; IS__CGSCC____-NEXT: [[SRC:%.*]] = alloca i8, align 1 -; IS__CGSCC____-NEXT: [[DST:%.*]] = alloca i8, align 1 -; IS__CGSCC____-NEXT: store i8 [[ARG]], i8* [[SRC]], align 1 -; IS__CGSCC____-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR12]] -; IS__CGSCC____-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 -; IS__CGSCC____-NEXT: ret i8 [[L]] +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@memcpy_uses_store +; IS__CGSCC_OPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] { +; IS__CGSCC_OPM-NEXT: [[SRC:%.*]] = alloca i8, align 1 +; IS__CGSCC_OPM-NEXT: [[DST:%.*]] = alloca i8, align 1 +; IS__CGSCC_OPM-NEXT: store i8 [[ARG]], i8* [[SRC]], align 1 +; IS__CGSCC_OPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR13]] +; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 +; IS__CGSCC_OPM-NEXT: ret i8 [[L]] +; +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@memcpy_uses_store +; IS__CGSCC_NPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[SRC:%.*]] = alloca i8, align 1 +; IS__CGSCC_NPM-NEXT: [[DST:%.*]] = alloca i8, align 1 +; IS__CGSCC_NPM-NEXT: store i8 [[ARG]], i8* [[SRC]], align 1 +; IS__CGSCC_NPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree noundef nonnull writeonly dereferenceable(1) [[DST]], i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR12]] +; IS__CGSCC_NPM-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 +; IS__CGSCC_NPM-NEXT: ret i8 [[L]] ; %src = alloca i8 %dst = alloca i8 @@ -1228,16 +1585,16 @@ define i8 @memcpy_uses_store_caller(i8 %arg) { ; IS__TUNIT_NPM-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR5]] ; IS__TUNIT_NPM-NEXT: ret i8 [[R]] ; -; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@memcpy_uses_store_caller -; IS__CGSCC_OPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR6]] { +; IS__CGSCC_OPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] { ; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR15:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i8 [[R]] ; -; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@memcpy_uses_store_caller -; IS__CGSCC_NPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR6]] { -; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR13:[0-9]+]] +; IS__CGSCC_NPM-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] { +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR14:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret i8 [[R]] ; %r = call i8 @memcpy_uses_store(i8 %arg) @@ -1275,17 +1632,18 @@ define i32 @test_speculatable_expr() norecurse { ; IS__CGSCC_OPM-NEXT: [[STACK:%.*]] = alloca i32, align 4 ; IS__CGSCC_OPM-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() ; IS__CGSCC_OPM-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1 -; IS__CGSCC_OPM-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32* noalias nocapture nofree noundef nonnull readnone align 4 dereferenceable(4) [[STACK]]) #[[ATTR16:[0-9]+]] +; IS__CGSCC_OPM-NEXT: store i32 [[PLUS1]], i32* [[STACK]], align 4 +; IS__CGSCC_OPM-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[STACK]]) #[[ATTR16:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RSPEC]] ; ; IS__CGSCC_NPM: Function Attrs: norecurse nosync readnone ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_speculatable_expr -; IS__CGSCC_NPM-SAME: () #[[ATTR9:[0-9]+]] { +; IS__CGSCC_NPM-SAME: () #[[ATTR8:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: [[STACK:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() ; IS__CGSCC_NPM-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1 ; IS__CGSCC_NPM-NEXT: store i32 [[PLUS1]], i32* [[STACK]], align 4 -; IS__CGSCC_NPM-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[PLUS1]]) #[[ATTR14:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[PLUS1]]) #[[ATTR15:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret i32 [[RSPEC]] ; %stack = alloca i32 @@ -1320,20 +1678,18 @@ define internal i32 @ret_speculatable_expr(i32* %mem, i32 %a2) { ; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ret_speculatable_expr ; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[MEM:%.*]]) #[[ATTR10:[0-9]+]] { -; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i32 @speculatable() -; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; IS__CGSCC_OPM-NEXT: [[MUL:%.*]] = mul i32 [[TMP2]], 13 +; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[MEM]], align 4 +; IS__CGSCC_OPM-NEXT: [[MUL:%.*]] = mul i32 [[L]], 13 ; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 7 ; IS__CGSCC_OPM-NEXT: ret i32 [[ADD]] ; ; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ret_speculatable_expr -; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR9:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: [[MEM_PRIV:%.*]] = alloca i32, align 4 ; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[MEM_PRIV]], align 4 -; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = call i32 @speculatable() -; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = add i32 [[TMP2]], 1 -; IS__CGSCC_NPM-NEXT: [[MUL:%.*]] = mul i32 [[TMP3]], 13 +; IS__CGSCC_NPM-NEXT: [[L:%.*]] = load i32, i32* [[MEM_PRIV]], align 4 +; IS__CGSCC_NPM-NEXT: [[MUL:%.*]] = mul i32 [[L]], 13 ; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 7 ; IS__CGSCC_NPM-NEXT: ret i32 [[ADD]] ; @@ -1378,37 +1734,38 @@ define internal i32 @ret_speculatable_expr(i32* %mem, i32 %a2) { ;. ; IS__CGSCC_OPM: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn writeonly } ; IS__CGSCC_OPM: attributes #[[ATTR8:[0-9]+]] = { readnone speculatable } ; IS__CGSCC_OPM: attributes #[[ATTR9]] = { norecurse nosync readnone } ; IS__CGSCC_OPM: attributes #[[ATTR10]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR11:[0-9]+]] = { argmemonly nofree nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR12]] = { willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR13]] = { nounwind willreturn writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR14]] = { readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR15]] = { nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR16]] = { readnone } +; IS__CGSCC_OPM: attributes #[[ATTR12]] = { readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR13]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR15]] = { nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR16]] = { readonly } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR3]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR8:[0-9]+]] = { readnone speculatable } -; IS__CGSCC_NPM: attributes #[[ATTR9]] = { norecurse nosync readnone } -; IS__CGSCC_NPM: attributes #[[ATTR10]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { argmemonly nofree nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR7:[0-9]+]] = { readnone speculatable } +; IS__CGSCC_NPM: attributes #[[ATTR8]] = { norecurse nosync readnone } +; IS__CGSCC_NPM: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR10:[0-9]+]] = { argmemonly nofree nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR11]] = { readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR12]] = { willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR13]] = { nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR14]] = { readnone } +; IS__CGSCC_NPM: attributes #[[ATTR13]] = { nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR14]] = { nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR15]] = { readonly } ;. -; CHECK: [[RNG0]] = !{i32 0, i32 -2147483648} +; IS__TUNIT____: [[RNG0]] = !{i32 0, i32 -2147483648} ;. diff --git a/llvm/test/Transforms/Attributor/willreturn.ll b/llvm/test/Transforms/Attributor/willreturn.ll index b8336c1d5120..00caa5f77151 100644 --- a/llvm/test/Transforms/Attributor/willreturn.ll +++ b/llvm/test/Transforms/Attributor/willreturn.ll @@ -30,35 +30,65 @@ define void @only_return() #0 { ; FIXME: missing willreturn define i32 @fib(i32 %0) local_unnamed_addr #0 { -; IS________OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; IS________OPM-LABEL: define {{[^@]+}}@fib -; IS________OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { -; IS________OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 -; IS________OPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] -; IS________OPM: 3: -; IS________OPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 -; IS________OPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR24:[0-9]+]] -; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 -; IS________OPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR24]] -; IS________OPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] -; IS________OPM-NEXT: ret i32 [[TMP8]] -; IS________OPM: 9: -; IS________OPM-NEXT: ret i32 [[TMP0]] +; IS__TUNIT_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fib +; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 +; IS__TUNIT_OPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] +; IS__TUNIT_OPM: 3: +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 +; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR24:[0-9]+]] +; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 +; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR24]] +; IS__TUNIT_OPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP8]] +; IS__TUNIT_OPM: 9: +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP0]] ; -; IS________NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; IS________NPM-LABEL: define {{[^@]+}}@fib -; IS________NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { -; IS________NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 -; IS________NPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] -; IS________NPM: 3: -; IS________NPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 -; IS________NPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR26:[0-9]+]] -; IS________NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 -; IS________NPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR26]] -; IS________NPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] -; IS________NPM-NEXT: ret i32 [[TMP8]] -; IS________NPM: 9: -; IS________NPM-NEXT: ret i32 [[TMP0]] +; IS__TUNIT_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fib +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 +; IS__TUNIT_NPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] +; IS__TUNIT_NPM: 3: +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 +; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR26:[0-9]+]] +; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 +; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR26]] +; IS__TUNIT_NPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP8]] +; IS__TUNIT_NPM: 9: +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP0]] +; +; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fib +; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 +; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] +; IS__CGSCC_OPM: 3: +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 +; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR17:[0-9]+]] +; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 +; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR17]] +; IS__CGSCC_OPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP8]] +; IS__CGSCC_OPM: 9: +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP0]] +; +; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fib +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 +; IS__CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] +; IS__CGSCC_NPM: 3: +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 +; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR19:[0-9]+]] +; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 +; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR19]] +; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP8]] +; IS__CGSCC_NPM: 9: +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] ; %2 = icmp slt i32 %0, 2 br i1 %2, label %9, label %3 @@ -1352,9 +1382,9 @@ define void @non_loop_cycle(i32 %n) { ; IS__TUNIT_NPM: exit: ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@non_loop_cycle -; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16]] { +; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR29:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 @@ -1382,9 +1412,9 @@ define void @non_loop_cycle(i32 %n) { ; IS__CGSCC_OPM: exit: ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone +; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@non_loop_cycle -; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { +; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR19]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) ; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 @@ -1456,49 +1486,85 @@ declare void @unknown_mustprogress() mustprogress declare void @readonly_mustprogress() readonly mustprogress define void @willreturn_mustprogress_caller_1() mustprogress { -; IS________OPM: Function Attrs: mustprogress -; IS________OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 -; IS________OPM-SAME: () #[[ATTR19:[0-9]+]] { -; IS________OPM-NEXT: call void @unknown() -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: mustprogress +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 +; IS__TUNIT_OPM-SAME: () #[[ATTR19:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: call void @unknown() +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: mustprogress -; IS________NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 -; IS________NPM-SAME: () #[[ATTR21:[0-9]+]] { -; IS________NPM-NEXT: call void @unknown() -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: mustprogress +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 +; IS__TUNIT_NPM-SAME: () #[[ATTR21:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: call void @unknown() +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: mustprogress +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 +; IS__CGSCC_OPM-SAME: () #[[ATTR20:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: call void @unknown() +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: mustprogress +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 +; IS__CGSCC_NPM-SAME: () #[[ATTR22:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: call void @unknown() +; IS__CGSCC_NPM-NEXT: ret void ; call void @unknown() ret void } define void @willreturn_mustprogress_caller_2() mustprogress { -; IS________OPM: Function Attrs: mustprogress readonly willreturn -; IS________OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 -; IS________OPM-SAME: () #[[ATTR21:[0-9]+]] { -; IS________OPM-NEXT: call void @readonly() #[[ATTR17:[0-9]+]] -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: mustprogress readonly willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 +; IS__TUNIT_OPM-SAME: () #[[ATTR21:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: call void @readonly() #[[ATTR17:[0-9]+]] +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: mustprogress readonly willreturn -; IS________NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 -; IS________NPM-SAME: () #[[ATTR23:[0-9]+]] { -; IS________NPM-NEXT: call void @readonly() #[[ATTR19:[0-9]+]] -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: mustprogress readonly willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 +; IS__TUNIT_NPM-SAME: () #[[ATTR23:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: call void @readonly() #[[ATTR19:[0-9]+]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: mustprogress readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 +; IS__CGSCC_OPM-SAME: () #[[ATTR22:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: call void @readonly() #[[ATTR18:[0-9]+]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: mustprogress readonly willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 +; IS__CGSCC_NPM-SAME: () #[[ATTR24:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: call void @readonly() #[[ATTR20:[0-9]+]] +; IS__CGSCC_NPM-NEXT: ret void ; call void @readonly() ret void } define void @willreturn_mustprogress_caller_3() mustprogress { -; IS________OPM: Function Attrs: mustprogress nosync readnone willreturn -; IS________OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 -; IS________OPM-SAME: () #[[ATTR22:[0-9]+]] { -; IS________OPM-NEXT: call void @readnone() -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: mustprogress nosync readnone willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 +; IS__TUNIT_OPM-SAME: () #[[ATTR22:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: call void @readnone() +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: mustprogress nosync readnone willreturn -; IS________NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 -; IS________NPM-SAME: () #[[ATTR24:[0-9]+]] { -; IS________NPM-NEXT: call void @readnone() -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: mustprogress nosync readnone willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 +; IS__TUNIT_NPM-SAME: () #[[ATTR24:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: call void @readnone() +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: mustprogress nosync readnone willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 +; IS__CGSCC_OPM-SAME: () #[[ATTR23:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: call void @readnone() +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: mustprogress nosync readnone willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 +; IS__CGSCC_NPM-SAME: () #[[ATTR25:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: call void @readnone() +; IS__CGSCC_NPM-NEXT: ret void ; call void @readnone() ret void @@ -1512,17 +1578,29 @@ define void @willreturn_mustprogress_callee_1() { ret void } define void @willreturn_mustprogress_callee_2() { -; IS________OPM: Function Attrs: readonly willreturn -; IS________OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 -; IS________OPM-SAME: () #[[ATTR23:[0-9]+]] { -; IS________OPM-NEXT: call void @readonly_mustprogress() #[[ATTR23]] -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: readonly willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 +; IS__TUNIT_OPM-SAME: () #[[ATTR23:[0-9]+]] { +; IS__TUNIT_OPM-NEXT: call void @readonly_mustprogress() #[[ATTR23]] +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: readonly willreturn -; IS________NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 -; IS________NPM-SAME: () #[[ATTR25:[0-9]+]] { -; IS________NPM-NEXT: call void @readonly_mustprogress() #[[ATTR25]] -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: readonly willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 +; IS__TUNIT_NPM-SAME: () #[[ATTR25:[0-9]+]] { +; IS__TUNIT_NPM-NEXT: call void @readonly_mustprogress() #[[ATTR25]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 +; IS__CGSCC_OPM-SAME: () #[[ATTR24:[0-9]+]] { +; IS__CGSCC_OPM-NEXT: call void @readonly_mustprogress() #[[ATTR24]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: readonly willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 +; IS__CGSCC_NPM-SAME: () #[[ATTR26:[0-9]+]] { +; IS__CGSCC_NPM-NEXT: call void @readonly_mustprogress() #[[ATTR26]] +; IS__CGSCC_NPM-NEXT: ret void ; call void @readonly_mustprogress() ret void @@ -1536,17 +1614,29 @@ define void @willreturn_mustprogress_callee_3() { ret void } define void @willreturn_mustprogress_callee_4() { -; IS________OPM: Function Attrs: readonly willreturn -; IS________OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 -; IS________OPM-SAME: () #[[ATTR23]] { -; IS________OPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR23]] -; IS________OPM-NEXT: ret void +; IS__TUNIT_OPM: Function Attrs: readonly willreturn +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 +; IS__TUNIT_OPM-SAME: () #[[ATTR23]] { +; IS__TUNIT_OPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR23]] +; IS__TUNIT_OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: readonly willreturn -; IS________NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 -; IS________NPM-SAME: () #[[ATTR25]] { -; IS________NPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR25]] -; IS________NPM-NEXT: ret void +; IS__TUNIT_NPM: Function Attrs: readonly willreturn +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 +; IS__TUNIT_NPM-SAME: () #[[ATTR25]] { +; IS__TUNIT_NPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR25]] +; IS__TUNIT_NPM-NEXT: ret void +; +; IS__CGSCC_OPM: Function Attrs: readonly willreturn +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 +; IS__CGSCC_OPM-SAME: () #[[ATTR24]] { +; IS__CGSCC_OPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR24]] +; IS__CGSCC_OPM-NEXT: ret void +; +; IS__CGSCC_NPM: Function Attrs: readonly willreturn +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 +; IS__CGSCC_NPM-SAME: () #[[ATTR26]] { +; IS__CGSCC_NPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR26]] +; IS__CGSCC_NPM-NEXT: ret void ; call void @willreturn_mustprogress_callee_2() ret void @@ -1585,37 +1675,37 @@ attributes #1 = { uwtable noinline } ; IS__TUNIT_OPM: attributes #[[ATTR27]] = { nounwind } ; IS__TUNIT_OPM: attributes #[[ATTR28]] = { willreturn } ;. -; IS________NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } -; IS________NPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } -; IS________NPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } -; IS________NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } -; IS________NPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } -; IS________NPM: attributes #[[ATTR5]] = { noreturn } -; IS________NPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } -; IS________NPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } -; IS________NPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } -; IS________NPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } -; IS________NPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } -; IS________NPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } -; IS________NPM: attributes #[[ATTR12]] = { nounwind willreturn } -; IS________NPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } -; IS________NPM: attributes #[[ATTR14]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } -; IS________NPM: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } -; IS________NPM: attributes #[[ATTR16:[0-9]+]] = { noreturn nounwind } -; IS________NPM: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind readnone } -; IS________NPM: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS________NPM: attributes #[[ATTR19]] = { readonly } -; IS________NPM: attributes #[[ATTR20:[0-9]+]] = { readnone } -; IS________NPM: attributes #[[ATTR21]] = { mustprogress } -; IS________NPM: attributes #[[ATTR22:[0-9]+]] = { mustprogress readonly } -; IS________NPM: attributes #[[ATTR23]] = { mustprogress readonly willreturn } -; IS________NPM: attributes #[[ATTR24]] = { mustprogress nosync readnone willreturn } -; IS________NPM: attributes #[[ATTR25]] = { readonly willreturn } -; IS________NPM: attributes #[[ATTR26]] = { nofree nosync nounwind readnone } -; IS________NPM: attributes #[[ATTR27]] = { nofree nosync nounwind } -; IS________NPM: attributes #[[ATTR28]] = { readnone willreturn } -; IS________NPM: attributes #[[ATTR29]] = { nounwind } -; IS________NPM: attributes #[[ATTR30]] = { willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR5]] = { noreturn } +; IS__TUNIT_NPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR12]] = { nounwind willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR14]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } +; IS__TUNIT_NPM: attributes #[[ATTR16:[0-9]+]] = { noreturn nounwind } +; IS__TUNIT_NPM: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind readnone } +; IS__TUNIT_NPM: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR19]] = { readonly } +; IS__TUNIT_NPM: attributes #[[ATTR20:[0-9]+]] = { readnone } +; IS__TUNIT_NPM: attributes #[[ATTR21]] = { mustprogress } +; IS__TUNIT_NPM: attributes #[[ATTR22:[0-9]+]] = { mustprogress readonly } +; IS__TUNIT_NPM: attributes #[[ATTR23]] = { mustprogress readonly willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR24]] = { mustprogress nosync readnone willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR25]] = { readonly willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR26]] = { nofree nosync nounwind readnone } +; IS__TUNIT_NPM: attributes #[[ATTR27]] = { nofree nosync nounwind } +; IS__TUNIT_NPM: attributes #[[ATTR28]] = { readnone willreturn } +; IS__TUNIT_NPM: attributes #[[ATTR29]] = { nounwind } +; IS__TUNIT_NPM: attributes #[[ATTR30]] = { willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } @@ -1634,17 +1724,49 @@ attributes #1 = { uwtable noinline } ; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR15:[0-9]+]] = { noreturn nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind readnone } -; IS__CGSCC_OPM: attributes #[[ATTR17]] = { readonly } -; IS__CGSCC_OPM: attributes #[[ATTR18:[0-9]+]] = { readnone } -; IS__CGSCC_OPM: attributes #[[ATTR19]] = { mustprogress } -; IS__CGSCC_OPM: attributes #[[ATTR20:[0-9]+]] = { mustprogress readonly } -; IS__CGSCC_OPM: attributes #[[ATTR21]] = { mustprogress readonly willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR22]] = { mustprogress nosync readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR23]] = { readonly willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR24]] = { nofree nosync nounwind readnone } +; IS__CGSCC_OPM: attributes #[[ATTR17]] = { nofree nosync nounwind readnone } +; IS__CGSCC_OPM: attributes #[[ATTR18]] = { readonly } +; IS__CGSCC_OPM: attributes #[[ATTR19:[0-9]+]] = { readnone } +; IS__CGSCC_OPM: attributes #[[ATTR20]] = { mustprogress } +; IS__CGSCC_OPM: attributes #[[ATTR21:[0-9]+]] = { mustprogress readonly } +; IS__CGSCC_OPM: attributes #[[ATTR22]] = { mustprogress readonly willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR23]] = { mustprogress nosync readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR24]] = { readonly willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR25]] = { nofree nosync nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR26]] = { readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR27]] = { nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR28]] = { willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR29]] = { nounwind readnone } ;. +; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR5]] = { noreturn } +; IS__CGSCC_NPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR14]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR16:[0-9]+]] = { noreturn nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind readnone } +; IS__CGSCC_NPM: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR19]] = { nofree nosync nounwind readnone } +; IS__CGSCC_NPM: attributes #[[ATTR20]] = { readonly } +; IS__CGSCC_NPM: attributes #[[ATTR21:[0-9]+]] = { readnone } +; IS__CGSCC_NPM: attributes #[[ATTR22]] = { mustprogress } +; IS__CGSCC_NPM: attributes #[[ATTR23:[0-9]+]] = { mustprogress readonly } +; IS__CGSCC_NPM: attributes #[[ATTR24]] = { mustprogress readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR25]] = { mustprogress nosync readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR26]] = { readonly willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR27]] = { nofree nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR28]] = { readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR29]] = { nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR30]] = { willreturn } +;. diff --git a/llvm/test/Transforms/OpenMP/icv_tracking.ll b/llvm/test/Transforms/OpenMP/icv_tracking.ll index 6c769c2373bf..c51071742327 100644 --- a/llvm/test/Transforms/OpenMP/icv_tracking.ll +++ b/llvm/test/Transforms/OpenMP/icv_tracking.ll @@ -1,6 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature -; RUN: opt -S -openmp-opt-cgscc < %s | FileCheck %s -; RUN: opt -S -passes=openmp-opt-cgscc < %s | FileCheck %s +; RUN: opt -S -passes=openmp-opt < %s | FileCheck %s %struct.ident_t = type { i32, i32, i32, i32, i8* }