diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -1868,6 +1868,12 @@ (void)Success; assert(Success && "Expected the check call to be successful!"); + // Load & store alignment is used late in the pipeline. Since the module pass + // is run early and the CGSCC pass is run late we wait for the latter to + // derive them. This mainly avoids redundant duplication in case we fail. + if (isModulePass()) + return; + auto LoadStorePred = [&](Instruction &I) -> bool { if (isa(I)) getOrCreateAAFor( diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll @@ -9,17 +9,29 @@ ; because there is a load of %A in the entry block define internal i32 @callee(i1 %C, i32* %A) { ; -; CHECK-LABEL: define {{[^@]+}}@callee -; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) -; CHECK-NEXT: entry: -; CHECK-NEXT: [[A_0:%.*]] = load i32, i32* [[A]], align 4 -; CHECK-NEXT: br label [[F:%.*]] -; CHECK: T: -; CHECK-NEXT: unreachable -; CHECK: F: -; CHECK-NEXT: [[A_2:%.*]] = getelementptr i32, i32* [[A]], i32 2 -; CHECK-NEXT: [[R:%.*]] = load i32, i32* [[A_2]], align 4 -; CHECK-NEXT: ret i32 [[R]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@callee +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[A_0:%.*]] = load i32, i32* [[A]], align 4 +; IS__TUNIT____-NEXT: br label [[F:%.*]] +; IS__TUNIT____: T: +; IS__TUNIT____-NEXT: unreachable +; IS__TUNIT____: F: +; IS__TUNIT____-NEXT: [[A_2:%.*]] = getelementptr i32, i32* [[A]], i32 2 +; IS__TUNIT____-NEXT: [[R:%.*]] = load i32, i32* [[A_2]] +; IS__TUNIT____-NEXT: ret i32 [[R]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@callee +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[A_0:%.*]] = load i32, i32* [[A]], align 4 +; IS__CGSCC____-NEXT: br label [[F:%.*]] +; IS__CGSCC____: T: +; IS__CGSCC____-NEXT: unreachable +; IS__CGSCC____: F: +; IS__CGSCC____-NEXT: [[A_2:%.*]] = getelementptr i32, i32* [[A]], i32 2 +; IS__CGSCC____-NEXT: [[R:%.*]] = load i32, i32* [[A_2]], align 4 +; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: ; Unconditonally load the element at %A diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll @@ -8,14 +8,23 @@ @G = constant %T { i32 0, i32 0, i32 17, i32 25 } define internal i32 @test(%T* %p) { -; CHECK-LABEL: define {{[^@]+}}@test() -; CHECK-NEXT: entry: -; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 3 -; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* @G, 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: ret i32 [[V]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test() +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 3 +; IS__TUNIT____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* @G, i64 0, i32 2 +; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]] +; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]] +; IS__TUNIT____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] +; IS__TUNIT____-NEXT: ret i32 [[V]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 3 +; IS__CGSCC____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* @G, 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: ret i32 [[V]] ; entry: %a.gep = getelementptr %T, %T* %p, i64 0, i32 3 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll @@ -13,9 +13,9 @@ ; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree nonnull byval align 4 dereferenceable(4) [[X:%.*]], i32 [[I:%.*]]) ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 -; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 ; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; IS__TUNIT_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 +; IS__TUNIT_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 ; IS__TUNIT_OPM-NEXT: store i32 0, i32* [[X]], align 4 ; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i32, i32* [[X]], align 4 ; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]] @@ -32,9 +32,9 @@ ; IS__TUNIT_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 ; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] ; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 ; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 ; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[X_PRIV]], align 4 ; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i32, i32* [[X_PRIV]], align 4 ; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]] diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll @@ -9,14 +9,14 @@ %struct.ss = type { i32, i64 } define internal i32 @f(%struct.ss* byval %b) nounwind { -; IS________OPM-LABEL: define {{[^@]+}}@f -; IS________OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]]) -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 -; IS________OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 -; IS________OPM-NEXT: ret i32 [[TMP1]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f +; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__TUNIT_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]] ; ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f ; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) @@ -27,11 +27,20 @@ ; IS__TUNIT_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 ; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] ; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 ; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP1]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]] +; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f ; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) ; IS__CGSCC_NPM-NEXT: entry: @@ -56,14 +65,14 @@ define internal i32 @g(%struct.ss* byval align 32 %b) nounwind { -; IS________OPM-LABEL: define {{[^@]+}}@g -; IS________OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 32 dereferenceable(12) [[B:%.*]]) -; IS________OPM-NEXT: entry: -; IS________OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 -; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32 -; IS________OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32 -; IS________OPM-NEXT: ret i32 [[TMP2]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@g +; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 32 dereferenceable(12) [[B:%.*]]) +; IS__TUNIT_OPM-NEXT: entry: +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__TUNIT_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP2]] ; ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@g ; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) @@ -74,11 +83,20 @@ ; IS__TUNIT_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1 ; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]] ; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0 -; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32 +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 ; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 -; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32 +; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4 ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP2]] ; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 32 dereferenceable(12) [[B:%.*]]) +; IS__CGSCC_OPM-NEXT: entry: +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0 +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32 +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32 +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP2]] +; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g ; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) ; IS__CGSCC_NPM-NEXT: entry: diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll @@ -9,11 +9,17 @@ define internal i32 @test(i32** %x) { ; -; CHECK-LABEL: define {{[^@]+}}@test() -; CHECK-NEXT: entry: -; CHECK-NEXT: [[Y:%.*]] = load i32*, i32** @G2, align 8 -; CHECK-NEXT: [[Z:%.*]] = load i32, i32* [[Y]], align 4 -; CHECK-NEXT: ret i32 [[Z]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test() +; IS__TUNIT____-NEXT: entry: +; IS__TUNIT____-NEXT: [[Y:%.*]] = load i32*, i32** @G2, align 8 +; IS__TUNIT____-NEXT: [[Z:%.*]] = load i32, i32* [[Y]] +; IS__TUNIT____-NEXT: ret i32 [[Z]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test() +; IS__CGSCC____-NEXT: entry: +; IS__CGSCC____-NEXT: [[Y:%.*]] = load i32*, i32** @G2, align 8 +; IS__CGSCC____-NEXT: [[Z:%.*]] = load i32, i32* [[Y]], align 4 +; IS__CGSCC____-NEXT: ret i32 [[Z]] ; entry: %y = load i32*, i32** %x diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll @@ -10,14 +10,23 @@ %T = type { i32, i32, i32, i32 } define internal i32 @test(%T* %p) { -; CHECK-LABEL: define {{[^@]+}}@test -; CHECK-SAME: (%T* nocapture nofree readonly [[P:%.*]]) -; 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: ret i32 [[V]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test +; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[P:%.*]]) +; 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]] +; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]] +; IS__TUNIT____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] +; IS__TUNIT____-NEXT: ret i32 [[V]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]]) +; 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: ret i32 [[V]] ; %a.gep = getelementptr %T, %T* %p, i64 0, i32 3 %b.gep = getelementptr %T, %T* %p, i64 0, i32 2 @@ -86,11 +95,17 @@ ; is kept as well. define i32 @bar(%T* %p, i32 %v) { -; CHECK-LABEL: define {{[^@]+}}@bar -; CHECK-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) -; 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____-LABEL: define {{[^@]+}}@bar +; IS__TUNIT____-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) +; IS__TUNIT____-NEXT: [[I32PTR:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 0 +; IS__TUNIT____-NEXT: store i32 [[V]], i32* [[I32PTR]] +; IS__TUNIT____-NEXT: ret i32 0 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@bar +; IS__CGSCC____-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) +; 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 @@ -98,15 +113,25 @@ } define internal i32 @test2b(%T* %p, i32 %p2) { -; CHECK-LABEL: define {{[^@]+}}@test2b -; CHECK-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) -; 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]]) -; CHECK-NEXT: ret i32 [[CA]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2b +; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) +; 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]] +; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]] +; IS__TUNIT____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] +; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i32 @bar(%T* undef, i32 [[V]]) +; IS__TUNIT____-NEXT: ret i32 [[CA]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2b +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]]) +; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3 +; IS__CGSCC____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2 +; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4 +; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4 +; IS__CGSCC____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call i32 @bar(%T* undef, i32 [[V]]) +; IS__CGSCC____-NEXT: ret i32 [[CA]] ; %a.gep = getelementptr %T, %T* %p, i64 0, i32 3 %b.gep = getelementptr %T, %T* %p, i64 0, i32 2 diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll @@ -14,10 +14,15 @@ %fun_t = type void (%p_t)* define void @foo() { -; CHECK-LABEL: define {{[^@]+}}@foo() -; CHECK-NEXT: [[TMP:%.*]] = alloca void (i16*)* -; CHECK-NEXT: store void (i16*)* @bar, void (i16*)** [[TMP]], align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo() +; IS__TUNIT____-NEXT: [[TMP:%.*]] = alloca void (i16*)* +; IS__TUNIT____-NEXT: store void (i16*)* @bar, void (i16*)** [[TMP]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo() +; IS__CGSCC____-NEXT: [[TMP:%.*]] = alloca void (i16*)* +; IS__CGSCC____-NEXT: store void (i16*)* @bar, void (i16*)** [[TMP]], align 8 +; IS__CGSCC____-NEXT: ret void ; %tmp = alloca %fun_t store %fun_t @bar, %fun_t* %tmp diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll @@ -13,8 +13,8 @@ ; IS__TUNIT_OPM-SAME: ({ i32, i32 }* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]]) ; IS__TUNIT_OPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 ; IS__TUNIT_OPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1 -; IS__TUNIT_OPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8 -; IS__TUNIT_OPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4 +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]] +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]] ; IS__TUNIT_OPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]] ; IS__TUNIT_OPM-NEXT: store i32 [[AB]], i32* [[R]], align 4 ; IS__TUNIT_OPM-NEXT: ret void @@ -23,8 +23,8 @@ ; IS__TUNIT_NPM-SAME: ({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]]) ; IS__TUNIT_NPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0 ; IS__TUNIT_NPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8 -; IS__TUNIT_NPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4 +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]] +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]] ; IS__TUNIT_NPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]] ; IS__TUNIT_NPM-NEXT: store i32 [[AB]], i32* [[R]], align 4 ; IS__TUNIT_NPM-NEXT: ret void diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll @@ -52,9 +52,9 @@ ; IS__TUNIT_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(8) [[U:%.*]]) ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1 -; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]] ; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0 -; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]] ; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32 ; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]] ; IS__TUNIT_OPM-NEXT: ret i32 [[TMP5]] @@ -68,9 +68,9 @@ ; IS__TUNIT_NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 ; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]] ; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] ; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0 -; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]] ; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 ; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]] ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP7]] @@ -128,9 +128,9 @@ ; IS__TUNIT_OPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1 ; IS__TUNIT_OPM-NEXT: store i32 99, i32* [[Z]], align 4 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1 -; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4 +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]] ; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0 -; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8 +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]] ; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32 ; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]] ; IS__TUNIT_OPM-NEXT: ret i32 [[TMP5]] @@ -146,9 +146,9 @@ ; IS__TUNIT_NPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 ; IS__TUNIT_NPM-NEXT: store i32 99, i32* [[Z]], align 4 ; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1 -; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] ; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0 -; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8 +; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]] ; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 ; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]] ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP7]] diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll @@ -66,7 +66,7 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@caller ; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #2 personality i32 (...)* @__gxx_personality_v0 ; IS__TUNIT____-NEXT: [[Q:%.*]] = alloca i32 -; IS__TUNIT____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) +; IS__TUNIT____-NEXT: [[W:%.*]] = call i32* @incdec(i1 [[C]], i32* noalias nofree nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) ; IS__TUNIT____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2) ; IS__TUNIT____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 ; IS__TUNIT____-NEXT: [[S2:%.*]] = invoke { i32, i32 } @foo(i32 3, i32 4) @@ -74,7 +74,7 @@ ; IS__TUNIT____: OK: ; IS__TUNIT____-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0 ; IS__TUNIT____-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]] -; IS__TUNIT____-NEXT: store i32 [[Z]], i32* [[W]], align 4 +; IS__TUNIT____-NEXT: store i32 [[Z]], i32* [[W]] ; IS__TUNIT____-NEXT: br label [[RET:%.*]] ; IS__TUNIT____: LPAD: ; IS__TUNIT____-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 } diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll --- a/llvm/test/Transforms/Attributor/align.ll +++ b/llvm/test/Transforms/Attributor/align.ll @@ -116,7 +116,7 @@ ; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null ; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] ; IS__TUNIT____: 3: -; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2() +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call i8* @f2() ; IS__TUNIT____-NEXT: br label [[TMP5]] ; IS__TUNIT____: 5: ; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] @@ -225,8 +225,8 @@ ; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null ; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] ; IS__TUNIT____: 3: -; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() -; IS__TUNIT____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call i8* @f2b() +; IS__TUNIT____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]] ; IS__TUNIT____-NEXT: store i8 [[L]], i8* @a1, align 8 ; IS__TUNIT____-NEXT: br label [[TMP5]] ; IS__TUNIT____: 5: @@ -579,17 +579,29 @@ } define void @test13(i1 %c, i32* align 32 %dst) #0 { -; CHECK-LABEL: define {{[^@]+}}@test13 -; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) -; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; CHECK: truebb: -; CHECK-NEXT: br label [[END:%.*]] -; CHECK: falsebb: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] -; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test13 +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; 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]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13 +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; 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: @@ -603,17 +615,29 @@ } define void @test13-1(i1 %c, i32* align 32 %dst) { -; CHECK-LABEL: define {{[^@]+}}@test13-1 -; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) -; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; CHECK: truebb: -; CHECK-NEXT: br label [[END:%.*]] -; CHECK: falsebb: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] -; CHECK-NEXT: store i32 0, i32* [[PTR]], align 16 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-1 +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; 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]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-1 +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; 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: @@ -627,17 +651,29 @@ } define void @test13-2(i1 %c, i32* align 32 %dst) { -; CHECK-LABEL: define {{[^@]+}}@test13-2 -; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) -; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; CHECK: truebb: -; CHECK-NEXT: br label [[END:%.*]] -; CHECK: falsebb: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] -; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-2 +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; 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]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-2 +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; 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: @@ -651,17 +687,29 @@ } define void @test13-3(i1 %c, i32* align 32 %dst) { -; CHECK-LABEL: define {{[^@]+}}@test13-3 -; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) -; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] -; CHECK: truebb: -; CHECK-NEXT: br label [[END:%.*]] -; CHECK: falsebb: -; CHECK-NEXT: br label [[END]] -; CHECK: end: -; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] -; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-3 +; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; 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]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-3 +; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) +; 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: @@ -719,11 +767,17 @@ } define void @align_store_after_bc(i32* align 2048 %arg) { ; -; CHECK-LABEL: define {{[^@]+}}@align_store_after_bc -; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) -; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* -; CHECK-NEXT: store i8 0, i8* [[BC]], align 2048 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@align_store_after_bc +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) +; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* +; IS__TUNIT____-NEXT: store i8 0, i8* [[BC]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@align_store_after_bc +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) +; 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 @@ -745,7 +799,7 @@ define i32 @musttail_caller_1(i32* %p) { ; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_caller_1 ; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) -; IS__TUNIT____-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 +; IS__TUNIT____-NEXT: [[C:%.*]] = load i1, i1* @cnd ; IS__TUNIT____-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] ; IS__TUNIT____: mt: ; IS__TUNIT____-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree readonly [[P]]) diff --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll --- a/llvm/test/Transforms/Attributor/callbacks.ll +++ b/llvm/test/Transforms/Attributor/callbacks.ll @@ -23,7 +23,7 @@ ; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 ; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 4 ; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 ; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__TUNIT_OPM-NEXT: ret void @@ -35,7 +35,7 @@ ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 ; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 4 ; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 ; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__TUNIT_NPM-NEXT: ret void @@ -131,7 +131,7 @@ ; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 ; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 4 ; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 ; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__TUNIT_OPM-NEXT: ret void @@ -143,7 +143,7 @@ ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 ; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 4 ; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 ; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__TUNIT_NPM-NEXT: ret void @@ -238,7 +238,7 @@ ; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 ; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 4 ; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 ; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__TUNIT_OPM-NEXT: ret void @@ -250,7 +250,7 @@ ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 ; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 4 ; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 ; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__TUNIT_NPM-NEXT: ret void @@ -347,7 +347,7 @@ ; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64 ; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 ; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 4 ; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64 ; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) @@ -360,7 +360,7 @@ ; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64 ; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128 ; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8* -; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32 +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 4 ; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64 ; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) ; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]]) diff --git a/llvm/test/Transforms/Attributor/dereferenceable-2.ll b/llvm/test/Transforms/Attributor/dereferenceable-2.ll --- a/llvm/test/Transforms/Attributor/dereferenceable-2.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-2.ll @@ -208,11 +208,17 @@ ; The 2nd and 3rd loads may never execute. define void @volatile_is_not_dereferenceable(i16* %ptr) { -; CHECK-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable -; CHECK-SAME: (i16* nofree align 2 [[PTR:%.*]]) -; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0 -; CHECK-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable +; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]]) +; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0 +; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable +; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]]) +; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0 +; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2 +; IS__CGSCC____-NEXT: ret void ; %arrayidx0 = getelementptr i16, i16* %ptr, i64 0 %arrayidx1 = getelementptr i16, i16* %ptr, i64 1 @@ -429,14 +435,23 @@ } define void @stores(i32* %arg) { -; CHECK-LABEL: define {{[^@]+}}@stores -; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) -; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* -; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr float, float* [[PTR]], i64 0 -; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1 -; CHECK-NEXT: store float 1.000000e+00, float* [[ARRAYIDX0]], align 4 -; CHECK-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@stores +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) +; IS__TUNIT____-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* +; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr float, float* [[PTR]], i64 0 +; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1 +; IS__TUNIT____-NEXT: store float 1.000000e+00, float* [[ARRAYIDX0]] +; IS__TUNIT____-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@stores +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) +; IS__CGSCC____-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* +; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr float, float* [[PTR]], i64 0 +; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1 +; IS__CGSCC____-NEXT: store float 1.000000e+00, float* [[ARRAYIDX0]], align 4 +; IS__CGSCC____-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4 +; IS__CGSCC____-NEXT: ret void ; %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 @@ -447,12 +462,19 @@ } define void @load_store(i32* %arg) { -; CHECK-LABEL: define {{[^@]+}}@load_store -; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) -; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* -; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1 -; CHECK-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@load_store +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) +; IS__TUNIT____-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* +; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1 +; IS__TUNIT____-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@load_store +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]]) +; IS__CGSCC____-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float* +; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1 +; IS__CGSCC____-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4 +; IS__CGSCC____-NEXT: ret void ; %ptr = bitcast i32* %arg to float* %arrayidx0 = getelementptr float, float* %ptr, i64 0 @@ -463,12 +485,19 @@ } define void @different_size1(i32* %arg) { -; CHECK-LABEL: define {{[^@]+}}@different_size1 -; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) -; CHECK-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* -; CHECK-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8 -; CHECK-NEXT: store i32 0, i32* [[ARG]], align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@different_size1 +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) +; IS__TUNIT____-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* +; IS__TUNIT____-NEXT: store double 0.000000e+00, double* [[ARG_CAST]] +; IS__TUNIT____-NEXT: store i32 0, i32* [[ARG]], align 8 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@different_size1 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) +; IS__CGSCC____-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* +; IS__CGSCC____-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8 +; IS__CGSCC____-NEXT: store i32 0, i32* [[ARG]], align 8 +; IS__CGSCC____-NEXT: ret void ; %arg-cast = bitcast i32* %arg to double* store double 0.000000e+00, double* %arg-cast @@ -477,12 +506,19 @@ } define void @different_size2(i32* %arg) { -; CHECK-LABEL: define {{[^@]+}}@different_size2 -; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) -; CHECK-NEXT: store i32 0, i32* [[ARG]], align 8 -; CHECK-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* -; CHECK-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@different_size2 +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) +; IS__TUNIT____-NEXT: store i32 0, i32* [[ARG]], align 8 +; IS__TUNIT____-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* +; IS__TUNIT____-NEXT: store double 0.000000e+00, double* [[ARG_CAST]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@different_size2 +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]]) +; IS__CGSCC____-NEXT: store i32 0, i32* [[ARG]], align 8 +; IS__CGSCC____-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double* +; IS__CGSCC____-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8 +; IS__CGSCC____-NEXT: ret void ; store i32 0, i32* %arg %arg-cast = bitcast i32* %arg to double* diff --git a/llvm/test/Transforms/Attributor/heap_to_stack.ll b/llvm/test/Transforms/Attributor/heap_to_stack.ll --- a/llvm/test/Transforms/Attributor/heap_to_stack.ll +++ b/llvm/test/Transforms/Attributor/heap_to_stack.ll @@ -385,22 +385,39 @@ ; TEST 10 - 1 malloc, 1 free define i32 @test10() { -; IS________OPM-LABEL: define {{[^@]+}}@test10() -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) -; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) -; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* -; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 -; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; IS________OPM-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________OPM-NEXT: ret i32 [[TMP3]] -; -; IS________NPM-LABEL: define {{[^@]+}}@test10() -; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 -; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) -; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* -; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 -; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; IS________NPM-NEXT: ret i32 [[TMP3]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test10() +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS__TUNIT_OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__TUNIT_OPM-NEXT: store i32 10, i32* [[TMP2]] +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP3]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test10() +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS__TUNIT_NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__TUNIT_NPM-NEXT: store i32 10, i32* [[TMP2]] +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test10() +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS__CGSCC_OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__CGSCC_OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test10() +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS__CGSCC_NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__CGSCC_NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP3]] ; %1 = tail call noalias i8* @malloc(i64 4) tail call void @no_sync_func(i8* %1) @@ -412,24 +429,43 @@ } define i32 @test_lifetime() { -; IS________OPM-LABEL: define {{[^@]+}}@test_lifetime() -; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) -; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) -; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* -; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 -; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; IS________OPM-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________OPM-NEXT: ret i32 [[TMP3]] -; -; IS________NPM-LABEL: define {{[^@]+}}@test_lifetime() -; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 -; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) -; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) -; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* -; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 -; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; IS________NPM-NEXT: ret i32 [[TMP3]] +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test_lifetime() +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS__TUNIT_OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__TUNIT_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__TUNIT_OPM-NEXT: store i32 10, i32* [[TMP2]] +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT_OPM-NEXT: ret i32 [[TMP3]] +; +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test_lifetime() +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS__TUNIT_NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS__TUNIT_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__TUNIT_NPM-NEXT: store i32 10, i32* [[TMP2]] +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_lifetime() +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4) +; IS__CGSCC_OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__CGSCC_OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__CGSCC_OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_lifetime() +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4 +; IS__CGSCC_NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) +; IS__CGSCC_NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__CGSCC_NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP3]] ; %1 = tail call noalias i8* @malloc(i64 4) tail call void @no_sync_func(i8* %1) @@ -627,14 +663,23 @@ ; Malloc/Calloc too large define i32 @test13() { -; CHECK-LABEL: define {{[^@]+}}@test13() -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 256) -; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* -; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; CHECK-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) -; CHECK-NEXT: ret i32 [[TMP3]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test13() +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 256) +; IS__TUNIT____-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__TUNIT____-NEXT: store i32 10, i32* [[TMP2]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] +; IS__TUNIT____-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT____-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test13() +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 256) +; IS__CGSCC____-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__CGSCC____-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = tail call noalias i8* @malloc(i64 256) tail call void @no_sync_func(i8* %1) @@ -646,14 +691,23 @@ } define i32 @test_sle() { -; CHECK-LABEL: define {{[^@]+}}@test_sle() -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 -1) -; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* -; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; CHECK-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) -; CHECK-NEXT: ret i32 [[TMP3]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_sle() +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 -1) +; IS__TUNIT____-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__TUNIT____-NEXT: store i32 10, i32* [[TMP2]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] +; IS__TUNIT____-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT____-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_sle() +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 -1) +; IS__CGSCC____-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__CGSCC____-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = tail call noalias i8* @malloc(i64 -1) tail call void @no_sync_func(i8* %1) @@ -665,14 +719,23 @@ } define i32 @test_overflow() { -; CHECK-LABEL: define {{[^@]+}}@test_overflow() -; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 65537, i64 65537) -; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* -; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 -; CHECK-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) -; CHECK-NEXT: ret i32 [[TMP3]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_overflow() +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 65537, i64 65537) +; IS__TUNIT____-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__TUNIT____-NEXT: store i32 10, i32* [[TMP2]] +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]] +; IS__TUNIT____-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__TUNIT____-NEXT: ret i32 [[TMP3]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_overflow() +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 65537, i64 65537) +; IS__CGSCC____-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]]) +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* +; IS__CGSCC____-NEXT: store i32 10, i32* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 +; IS__CGSCC____-NEXT: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]]) +; IS__CGSCC____-NEXT: ret i32 [[TMP3]] ; %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) tail call void @no_sync_func(i8* %1) diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll --- a/llvm/test/Transforms/Attributor/liveness.ll +++ b/llvm/test/Transforms/Attributor/liveness.ll @@ -477,13 +477,21 @@ ; FIXME: Should be able to detect undefined behavior. define void @ub(i32* %0) { -; CHECK-LABEL: define {{[^@]+}}@ub -; CHECK-SAME: (i32* nocapture nofree writeonly [[TMP0:%.*]]) -; CHECK-NEXT: [[POISON:%.*]] = sub nuw i32 0, 1 -; CHECK-NEXT: [[STILL_POISON:%.*]] = and i32 [[POISON]], 0 -; CHECK-NEXT: [[POISON_YET_AGAIN:%.*]] = getelementptr i32, i32* [[TMP0]], i32 [[STILL_POISON]] -; CHECK-NEXT: store i32 0, i32* [[POISON_YET_AGAIN]], align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@ub +; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[TMP0:%.*]]) +; IS__TUNIT____-NEXT: [[POISON:%.*]] = sub nuw i32 0, 1 +; IS__TUNIT____-NEXT: [[STILL_POISON:%.*]] = and i32 [[POISON]], 0 +; IS__TUNIT____-NEXT: [[POISON_YET_AGAIN:%.*]] = getelementptr i32, i32* [[TMP0]], i32 [[STILL_POISON]] +; IS__TUNIT____-NEXT: store i32 0, i32* [[POISON_YET_AGAIN]] +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@ub +; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly [[TMP0:%.*]]) +; IS__CGSCC____-NEXT: [[POISON:%.*]] = sub nuw i32 0, 1 +; IS__CGSCC____-NEXT: [[STILL_POISON:%.*]] = and i32 [[POISON]], 0 +; IS__CGSCC____-NEXT: [[POISON_YET_AGAIN:%.*]] = getelementptr i32, i32* [[TMP0]], i32 [[STILL_POISON]] +; IS__CGSCC____-NEXT: store i32 0, i32* [[POISON_YET_AGAIN]], align 4 +; IS__CGSCC____-NEXT: ret void ; %poison = sub nuw i32 0, 1 ; Results in a poison value. %still_poison = and i32 %poison, 0 ; 0, but also poison. diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll --- a/llvm/test/Transforms/Attributor/noalias.ll +++ b/llvm/test/Transforms/Attributor/noalias.ll @@ -644,10 +644,15 @@ @alias_of_p = external global i32* define void @make_alias(i32* %p) { -; CHECK-LABEL: define {{[^@]+}}@make_alias -; CHECK-SAME: (i32* nofree writeonly [[P:%.*]]) -; CHECK-NEXT: store i32* [[P]], i32** @alias_of_p, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@make_alias +; IS__TUNIT____-SAME: (i32* nofree writeonly [[P:%.*]]) +; IS__TUNIT____-NEXT: store i32* [[P]], i32** @alias_of_p +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@make_alias +; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]]) +; 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 diff --git a/llvm/test/Transforms/Attributor/nocapture-1.ll b/llvm/test/Transforms/Attributor/nocapture-1.ll --- a/llvm/test/Transforms/Attributor/nocapture-1.ll +++ b/llvm/test/Transforms/Attributor/nocapture-1.ll @@ -16,10 +16,15 @@ ; It would also be acceptable to mark %q as readnone. Update @c3 too. define void @c2(i32* %q) { -; CHECK-LABEL: define {{[^@]+}}@c2 -; CHECK-SAME: (i32* nofree writeonly [[Q:%.*]]) -; CHECK-NEXT: store i32* [[Q]], i32** @g, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@c2 +; IS__TUNIT____-SAME: (i32* nofree writeonly [[Q:%.*]]) +; IS__TUNIT____-NEXT: store i32* [[Q]], i32** @g +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@c2 +; IS__CGSCC____-SAME: (i32* nofree writeonly [[Q:%.*]]) +; IS__CGSCC____-NEXT: store i32* [[Q]], i32** @g, align 8 +; IS__CGSCC____-NEXT: ret void ; store i32* %q, i32** @g ret void @@ -168,19 +173,33 @@ define i32 @nc1(i32* %q, i32* %p, i1 %b) { -; CHECK-LABEL: define {{[^@]+}}@nc1 -; CHECK-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) -; CHECK-NEXT: e: -; CHECK-NEXT: br label [[L:%.*]] -; CHECK: l: -; CHECK-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ] -; CHECK-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ] -; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[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____-LABEL: define {{[^@]+}}@nc1 +; IS__TUNIT____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) +; IS__TUNIT____-NEXT: e: +; IS__TUNIT____-NEXT: br label [[L:%.*]] +; IS__TUNIT____: l: +; IS__TUNIT____-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ] +; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ] +; IS__TUNIT____-NEXT: [[TMP:%.*]] = bitcast i32* [[X]] to i32* +; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]] +; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]] +; IS__TUNIT____-NEXT: store i32 0, i32* [[TMP]] +; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g +; IS__TUNIT____-NEXT: ret i32 [[VAL]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@nc1 +; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) +; IS__CGSCC____-NEXT: e: +; IS__CGSCC____-NEXT: br label [[L:%.*]] +; IS__CGSCC____: l: +; IS__CGSCC____-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ] +; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ] +; IS__CGSCC____-NEXT: [[TMP:%.*]] = bitcast i32* [[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 @@ -196,19 +215,33 @@ } define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* %p, i1 %b) { -; CHECK-LABEL: define {{[^@]+}}@nc1_addrspace -; CHECK-SAME: (i32* nofree [[Q:%.*]], i32 addrspace(1)* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) -; 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____-LABEL: define {{[^@]+}}@nc1_addrspace +; IS__TUNIT____-SAME: (i32* nofree [[Q:%.*]], i32 addrspace(1)* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) +; 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]] +; IS__TUNIT____-NEXT: store i32 0, i32* [[TMP]] +; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g +; IS__TUNIT____-NEXT: ret i32 [[VAL]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@nc1_addrspace +; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32 addrspace(1)* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) +; 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 @@ -270,11 +303,17 @@ ; 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-LABEL: define {{[^@]+}}@test1_1 -; CHECK-SAME: (i8* nocapture nofree readnone [[X1_1:%.*]], i8* nocapture nofree readnone [[Y1_1:%.*]], i1 [[C:%.*]]) -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_1 +; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[X1_1:%.*]], i8* nocapture nofree readnone [[Y1_1:%.*]], i1 [[C:%.*]]) +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) +; IS__TUNIT____-NEXT: store i32* null, i32** @g +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_1 +; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[X1_1:%.*]], i8* nocapture nofree readnone [[Y1_1:%.*]], i1 [[C:%.*]]) +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]]) +; 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 @@ -282,15 +321,25 @@ } define i8* @test1_2(i8* %x1_2, i8* %y1_2, i1 %c) { -; CHECK-LABEL: define {{[^@]+}}@test1_2 -; CHECK-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: call void @test1_1(i8* noalias nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 [[C]]) -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: br label [[F]] -; CHECK: f: -; CHECK-NEXT: ret i8* [[Y1_2]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_2 +; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: call void @test1_1(i8* noalias nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 [[C]]) +; IS__TUNIT____-NEXT: store i32* null, i32** @g +; IS__TUNIT____-NEXT: br label [[F]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: ret i8* [[Y1_2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_2 +; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]]) +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: call void @test1_1(i8* noalias nofree readnone undef, i8* noalias nocapture nofree readnone [[Y1_2]], i1 [[C]]) +; IS__CGSCC____-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC____-NEXT: br label [[F]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: ret i8* [[Y1_2]] ; br i1 %c, label %t, label %f t: @@ -322,11 +371,17 @@ } define void @test4_1(i8* %x4_1, i1 %c) { -; CHECK-LABEL: define {{[^@]+}}@test4_1 -; CHECK-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]]) -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nofree readnone undef, i1 [[C]]) -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test4_1 +; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]]) +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nofree readnone undef, i1 [[C]]) +; IS__TUNIT____-NEXT: store i32* null, i32** @g +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test4_1 +; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]]) +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nofree readnone undef, i1 [[C]]) +; 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 @@ -334,15 +389,25 @@ } define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2, i1 %c) { -; CHECK-LABEL: define {{[^@]+}}@test4_2 -; CHECK-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:%.*]]) -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] -; CHECK: t: -; CHECK-NEXT: call void @test4_1(i8* noalias nofree readnone align 536870912 null, i1 [[C]]) -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: br label [[F]] -; CHECK: f: -; CHECK-NEXT: ret i8* [[Y4_2]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test4_2 +; IS__TUNIT____-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:%.*]]) +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: call void @test4_1(i8* noalias nofree readnone align 536870912 null, i1 [[C]]) +; IS__TUNIT____-NEXT: store i32* null, i32** @g +; IS__TUNIT____-NEXT: br label [[F]] +; IS__TUNIT____: f: +; IS__TUNIT____-NEXT: ret i8* [[Y4_2]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test4_2 +; IS__CGSCC____-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:%.*]]) +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: call void @test4_1(i8* noalias nofree readnone align 536870912 null, i1 [[C]]) +; IS__CGSCC____-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC____-NEXT: br label [[F]] +; IS__CGSCC____: f: +; IS__CGSCC____-NEXT: ret i8* [[Y4_2]] ; br i1 %c, label %t, label %f t: @@ -356,11 +421,17 @@ declare i8* @test5_1(i8* %x5_1) define void @test5_2(i8* %x5_2) { -; CHECK-LABEL: define {{[^@]+}}@test5_2 -; CHECK-SAME: (i8* [[X5_2:%.*]]) -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test5_1(i8* [[X5_2]]) -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test5_2 +; IS__TUNIT____-SAME: (i8* [[X5_2:%.*]]) +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i8* @test5_1(i8* [[X5_2]]) +; IS__TUNIT____-NEXT: store i32* null, i32** @g +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test5_2 +; IS__CGSCC____-SAME: (i8* [[X5_2:%.*]]) +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i8* @test5_1(i8* [[X5_2]]) +; IS__CGSCC____-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC____-NEXT: ret void ; call i8* @test5_1(i8* %x5_2) store i32* null, i32** @g @@ -370,11 +441,17 @@ declare void @test6_1(i8* %x6_1, i8* nocapture %y6_1, ...) define void @test6_2(i8* %x6_2, i8* %y6_2, i8* %z6_2) { -; CHECK-LABEL: define {{[^@]+}}@test6_2 -; CHECK-SAME: (i8* [[X6_2:%.*]], i8* nocapture [[Y6_2:%.*]], i8* [[Z6_2:%.*]]) -; CHECK-NEXT: call void (i8*, i8*, ...) @test6_1(i8* [[X6_2]], i8* nocapture [[Y6_2]], i8* [[Z6_2]]) -; CHECK-NEXT: store i32* null, i32** @g, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test6_2 +; IS__TUNIT____-SAME: (i8* [[X6_2:%.*]], i8* nocapture [[Y6_2:%.*]], i8* [[Z6_2:%.*]]) +; IS__TUNIT____-NEXT: call void (i8*, i8*, ...) @test6_1(i8* [[X6_2]], i8* nocapture [[Y6_2]], i8* [[Z6_2]]) +; IS__TUNIT____-NEXT: store i32* null, i32** @g +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test6_2 +; IS__CGSCC____-SAME: (i8* [[X6_2:%.*]], i8* nocapture [[Y6_2:%.*]], i8* [[Z6_2:%.*]]) +; IS__CGSCC____-NEXT: call void (i8*, i8*, ...) @test6_1(i8* [[X6_2]], i8* nocapture [[Y6_2]], i8* [[Z6_2]]) +; IS__CGSCC____-NEXT: store i32* null, i32** @g, align 8 +; IS__CGSCC____-NEXT: ret void ; call void (i8*, i8*, ...) @test6_1(i8* %x6_2, i8* %y6_2, i8* %z6_2) store i32* null, i32** @g @@ -441,11 +518,17 @@ @g2 = global i8* null define void @captureLaunder(i8* %p) { -; CHECK-LABEL: define {{[^@]+}}@captureLaunder -; CHECK-SAME: (i8* [[P:%.*]]) -; CHECK-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[P]]) -; CHECK-NEXT: store i8* [[B]], i8** @g2, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@captureLaunder +; IS__TUNIT____-SAME: (i8* [[P:%.*]]) +; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[P]]) +; IS__TUNIT____-NEXT: store i8* [[B]], i8** @g2 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@captureLaunder +; IS__CGSCC____-SAME: (i8* [[P:%.*]]) +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[P]]) +; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g2, align 8 +; IS__CGSCC____-NEXT: ret void ; %b = call i8* @llvm.launder.invariant.group.p0i8(i8* %p) store i8* %b, i8** @g2 @@ -468,11 +551,17 @@ @g3 = global i8* null define void @captureStrip(i8* %p) { -; CHECK-LABEL: define {{[^@]+}}@captureStrip -; CHECK-SAME: (i8* writeonly [[P:%.*]]) -; CHECK-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias readnone [[P]]) -; CHECK-NEXT: store i8* [[B]], i8** @g3, align 8 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@captureStrip +; IS__TUNIT____-SAME: (i8* writeonly [[P:%.*]]) +; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias readnone [[P]]) +; IS__TUNIT____-NEXT: store i8* [[B]], i8** @g3 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@captureStrip +; IS__CGSCC____-SAME: (i8* writeonly [[P:%.*]]) +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias readnone [[P]]) +; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g3, align 8 +; IS__CGSCC____-NEXT: ret void ; %b = call i8* @llvm.strip.invariant.group.p0i8(i8* %p) store i8* %b, i8** @g3 diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll b/llvm/test/Transforms/Attributor/nocapture-2.ll --- a/llvm/test/Transforms/Attributor/nocapture-2.ll +++ b/llvm/test/Transforms/Attributor/nocapture-2.ll @@ -505,7 +505,7 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1b ; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 [[A:%.*]]) ; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[CALL:%.*]] = call align 8 i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) ; IS__TUNIT____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64 ; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[CALL]], align 8 ; IS__TUNIT____-NEXT: ret void diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -12,11 +12,17 @@ ; NOTE: readonly for %y1_2 would be OK here but not for the similar situation in test13. ; define void @test1_2(i8* %x1_2, i8* %y1_2, i8* %z1_2) { -; CHECK-LABEL: define {{[^@]+}}@test1_2 -; CHECK-SAME: (i8* [[X1_2:%.*]], i8* [[Y1_2:%.*]], i8* [[Z1_2:%.*]]) -; CHECK-NEXT: call void (i8*, i8*, ...) @test1_1(i8* [[X1_2]], i8* readonly [[Y1_2]], i8* [[Z1_2]]) -; CHECK-NEXT: store i32 0, i32* @x, align 4 -; CHECK-NEXT: ret void +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_2 +; IS__TUNIT____-SAME: (i8* [[X1_2:%.*]], i8* [[Y1_2:%.*]], i8* [[Z1_2:%.*]]) +; IS__TUNIT____-NEXT: call void (i8*, i8*, ...) @test1_1(i8* [[X1_2]], i8* readonly [[Y1_2]], i8* [[Z1_2]]) +; IS__TUNIT____-NEXT: store i32 0, i32* @x +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_2 +; IS__CGSCC____-SAME: (i8* [[X1_2:%.*]], i8* [[Y1_2:%.*]], i8* [[Z1_2:%.*]]) +; IS__CGSCC____-NEXT: call void (i8*, i8*, ...) @test1_1(i8* [[X1_2]], i8* readonly [[Y1_2]], i8* [[Z1_2]]) +; IS__CGSCC____-NEXT: store i32 0, i32* @x, align 4 +; IS__CGSCC____-NEXT: ret void ; call void (i8*, i8*, ...) @test1_1(i8* %x1_2, i8* %y1_2, i8* %z1_2) store i32 0, i32* @x @@ -24,10 +30,15 @@ } define i8* @test2(i8* %p) { -; CHECK-LABEL: define {{[^@]+}}@test2 -; CHECK-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]]) -; CHECK-NEXT: store i32 0, i32* @x, align 4 -; CHECK-NEXT: ret i8* [[P]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2 +; IS__TUNIT____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]]) +; IS__TUNIT____-NEXT: store i32 0, i32* @x +; IS__TUNIT____-NEXT: ret i8* [[P]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2 +; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]]) +; IS__CGSCC____-NEXT: store i32 0, i32* @x, align 4 +; IS__CGSCC____-NEXT: ret i8* [[P]] ; store i32 0, i32* @x ret i8* %p diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll --- a/llvm/test/Transforms/Attributor/returned.ll +++ b/llvm/test/Transforms/Attributor/returned.ll @@ -1167,20 +1167,35 @@ ; We can use the return information of the weak function non_exact_4. ; FIXME: %c2 and %c3 should be replaced but not %c0 or %c1! define i32 @exact(i32* align 8 %a, i32* align 8 %b) { -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@exact -; NOT_CGSCC_NPM-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) -; NOT_CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @non_exact_0() -; NOT_CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 1) -; NOT_CGSCC_NPM-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 2) -; NOT_CGSCC_NPM-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) -; NOT_CGSCC_NPM-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) -; NOT_CGSCC_NPM-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32 -; NOT_CGSCC_NPM-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 -; NOT_CGSCC_NPM-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] -; NOT_CGSCC_NPM-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[C2]] -; NOT_CGSCC_NPM-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] -; NOT_CGSCC_NPM-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] -; NOT_CGSCC_NPM-NEXT: ret i32 [[ADD4]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@exact +; IS__TUNIT____-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) +; IS__TUNIT____-NEXT: [[C0:%.*]] = call i32 @non_exact_0() +; IS__TUNIT____-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 1) +; IS__TUNIT____-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 2) +; IS__TUNIT____-NEXT: [[C3:%.*]] = call i32* @non_exact_3(i32* align 32 [[A]]) +; IS__TUNIT____-NEXT: [[C4:%.*]] = call i32* @non_exact_4(i32* align 32 [[B]]) +; IS__TUNIT____-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]] +; IS__TUNIT____-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]] +; IS__TUNIT____-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] +; IS__TUNIT____-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[C2]] +; IS__TUNIT____-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] +; IS__TUNIT____-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] +; IS__TUNIT____-NEXT: ret i32 [[ADD4]] +; +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@exact +; IS__CGSCC_OPM-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) +; IS__CGSCC_OPM-NEXT: [[C0:%.*]] = call i32 @non_exact_0() +; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 1) +; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 2) +; IS__CGSCC_OPM-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]]) +; IS__CGSCC_OPM-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]]) +; IS__CGSCC_OPM-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32 +; IS__CGSCC_OPM-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16 +; IS__CGSCC_OPM-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]] +; IS__CGSCC_OPM-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[C2]] +; IS__CGSCC_OPM-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]] +; IS__CGSCC_OPM-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]] +; IS__CGSCC_OPM-NEXT: ret i32 [[ADD4]] ; ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@exact ; IS__CGSCC_NPM-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll --- a/llvm/test/Transforms/Attributor/undefined_behavior.ll +++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -339,14 +339,23 @@ ; Branch on undef because of uninitialized value. ; FIXME: Currently it doesn't propagate the undef. define i32 @cond_br_on_undef_uninit() { -; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit() -; CHECK-NEXT: [[ALLOC:%.*]] = alloca i1 -; CHECK-NEXT: [[COND:%.*]] = load i1, i1* [[ALLOC]], align 1 -; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] -; CHECK: t: -; CHECK-NEXT: ret i32 1 -; CHECK: e: -; CHECK-NEXT: ret i32 2 +; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit() +; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i1 +; IS__TUNIT____-NEXT: [[COND:%.*]] = load i1, i1* [[ALLOC]] +; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] +; IS__TUNIT____: t: +; IS__TUNIT____-NEXT: ret i32 1 +; IS__TUNIT____: e: +; IS__TUNIT____-NEXT: ret i32 2 +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit() +; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i1 +; IS__CGSCC____-NEXT: [[COND:%.*]] = load i1, i1* [[ALLOC]], align 1 +; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] +; IS__CGSCC____: t: +; IS__CGSCC____-NEXT: ret i32 1 +; IS__CGSCC____: e: +; IS__CGSCC____-NEXT: ret i32 2 ; %alloc = alloca i1 %cond = load i1, i1* %alloc diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -366,10 +366,15 @@ } define internal i8*@test_byval2(%struct.X* byval %a) { -; CHECK-LABEL: define {{[^@]+}}@test_byval2() -; CHECK-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0 -; CHECK-NEXT: [[L:%.*]] = load i8*, i8** [[G0]], align 8 -; CHECK-NEXT: ret i8* [[L]] +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_byval2() +; IS__TUNIT____-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0 +; IS__TUNIT____-NEXT: [[L:%.*]] = load i8*, i8** [[G0]] +; IS__TUNIT____-NEXT: ret i8* [[L]] +; +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_byval2() +; IS__CGSCC____-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0 +; IS__CGSCC____-NEXT: [[L:%.*]] = load i8*, i8** [[G0]], align 8 +; IS__CGSCC____-NEXT: ret i8* [[L]] ; %g0 = getelementptr %struct.X, %struct.X* %a, i32 0, i32 0 %l = load i8*, i8** %g0