[Transforms][IPO] Add func suffix in ArgumentPromotion and DeadArgume… (#105742)
…ntElimination ArgumentPromotion and DeadArgumentElimination passes could change function signatures but the function name remains the same as before the transformation. This makes it hard for tracing with bpf programs where user tends to use function signature in the source. See discussion [1] for details. This patch added suffix to functions whose signatures are changed. The suffix lets users know that function signature has changed and they need to impact the IR or binary to find modified signature before tracing those functions. The suffix for ArgumentPromotion is ".argprom" and the suffixes for DeadArgumentElimination are ".argelim" and ".retelim". The suffix also gives user hints about what kind of transformation has been done. With this patch, I built a recent linux kernel with full LTO enabled. I got 4 functions with only argpromotion like ``` set_track_update.argelim.argprom pmd_trans_huge_lock.argprom ... ``` I got 1058 functions with only deadargelim like ``` process_bit0.argelim pci_io_ecs_init.argelim ... ``` I got 3 functions with both argpromotion and deadargelim ``` set_track_update.argelim.argprom zero_pud_populate.argelim.argprom zero_pmd_populate.argelim.argprom ``` [1] https://github.com/llvm/llvm-project/issues/104678
This commit is contained in:
parent
30cdf1e959
commit
959448fbd6
@ -215,6 +215,7 @@ doPromotion(Function *F, FunctionAnalysisManager &FAM,
|
||||
|
||||
F->getParent()->getFunctionList().insert(F->getIterator(), NF);
|
||||
NF->takeName(F);
|
||||
NF->setName(NF->getName() + ".argprom");
|
||||
|
||||
// Loop over all the callers of the function, transforming the call sites to
|
||||
// pass in the loaded pointers.
|
||||
|
@ -889,6 +889,10 @@ bool DeadArgumentEliminationPass::removeDeadStuffFromFunction(Function *F) {
|
||||
// it again.
|
||||
F->getParent()->getFunctionList().insert(F->getIterator(), NF);
|
||||
NF->takeName(F);
|
||||
if (NumArgumentsEliminated)
|
||||
NF->setName(NF->getName() + ".argelim");
|
||||
else
|
||||
NF->setName(NF->getName() + ".retelim");
|
||||
NF->IsNewDbgInfoFormat = F->IsNewDbgInfoFormat;
|
||||
|
||||
// Loop over all the callers of the function, transforming the call sites to
|
||||
|
@ -9,7 +9,7 @@ define internal void @a() alwaysinline {
|
||||
}
|
||||
|
||||
define internal void @b(ptr) noinline {
|
||||
; CHECK-LABEL: @b(
|
||||
; CHECK-LABEL: @b.argprom(
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
ret void
|
||||
@ -17,7 +17,7 @@ define internal void @b(ptr) noinline {
|
||||
|
||||
define internal void @c() noinline {
|
||||
; CHECK-LABEL: @c(
|
||||
; CHECK-NEXT: call void @b()
|
||||
; CHECK-NEXT: call void @b.argprom()
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call void @b(ptr @a)
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
declare i32 @test2()
|
||||
|
||||
; CHECK: define void @test() {
|
||||
; CHECK: define void @test.argelim() {
|
||||
define i32 @test(i32 %A, ptr %B, float %C) {
|
||||
call i32 @test2()
|
||||
ret i32 %1
|
||||
|
@ -38,16 +38,16 @@ define dso_local void @caller_4xi32(ptr noalias %src, ptr noalias %dst) #1 {
|
||||
; CHECK-LABEL: define dso_local void @caller_4xi32(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[SRC_VAL:%.*]] = load <4 x i32>, ptr [[SRC:%.*]], align 16
|
||||
; CHECK-NEXT: call fastcc void @callee_4xi32(<4 x i32> [[SRC_VAL]], ptr noalias [[DST:%.*]])
|
||||
; CHECK-NEXT: call fastcc void @callee_4xi32.argprom.argprom(<4 x i32> [[SRC_VAL]], ptr noalias [[DST:%.*]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
call fastcc void @callee_4xi32(ptr noalias %src, ptr noalias %dst)
|
||||
call fastcc void @callee_4xi32.argprom(ptr noalias %src, ptr noalias %dst)
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal fastcc void @callee_4xi32(ptr noalias %src, ptr noalias %dst) #1 {
|
||||
; CHECK-LABEL: define internal fastcc void @callee_4xi32(
|
||||
define internal fastcc void @callee_4xi32.argprom(ptr noalias %src, ptr noalias %dst) #1 {
|
||||
; CHECK-LABEL: define internal fastcc void @callee_4xi32.argprom.argprom(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: store <4 x i32> [[SRC_0_VAL:%.*]], ptr [[DST:%.*]], align 16
|
||||
; CHECK-NEXT: ret void
|
||||
@ -65,7 +65,7 @@ define dso_local void @caller_i256(ptr noalias %src, ptr noalias %dst) #0 {
|
||||
; CHECK-LABEL: define dso_local void @caller_i256(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[SRC_VAL:%.*]] = load i256, ptr [[SRC:%.*]], align 16
|
||||
; CHECK-NEXT: call fastcc void @callee_i256(i256 [[SRC_VAL]], ptr noalias [[DST:%.*]])
|
||||
; CHECK-NEXT: call fastcc void @callee_i256.argprom(i256 [[SRC_VAL]], ptr noalias [[DST:%.*]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -74,7 +74,7 @@ entry:
|
||||
}
|
||||
|
||||
define internal fastcc void @callee_i256(ptr noalias %src, ptr noalias %dst) #0 {
|
||||
; CHECK-LABEL: define internal fastcc void @callee_i256(
|
||||
; CHECK-LABEL: define internal fastcc void @callee_i256.argprom(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: store i256 [[SRC_0_VAL:%.*]], ptr [[DST:%.*]], align 16
|
||||
; CHECK-NEXT: ret void
|
||||
@ -159,7 +159,7 @@ define dso_local void @caller_struct4xi32(ptr noalias %src, ptr noalias %dst) #1
|
||||
; CHECK-NEXT: [[SRC_VAL:%.*]] = load <4 x i32>, ptr [[SRC:%.*]], align 16
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[SRC]], i64 16
|
||||
; CHECK-NEXT: [[SRC_VAL1:%.*]] = load <4 x i32>, ptr [[TMP0]], align 16
|
||||
; CHECK-NEXT: call fastcc void @callee_struct4xi32(<4 x i32> [[SRC_VAL]], <4 x i32> [[SRC_VAL1]], ptr noalias [[DST:%.*]])
|
||||
; CHECK-NEXT: call fastcc void @callee_struct4xi32.argprom(<4 x i32> [[SRC_VAL]], <4 x i32> [[SRC_VAL1]], ptr noalias [[DST:%.*]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -168,7 +168,7 @@ entry:
|
||||
}
|
||||
|
||||
define internal fastcc void @callee_struct4xi32(ptr noalias %src, ptr noalias %dst) #1 {
|
||||
; CHECK-LABEL: define internal fastcc void @callee_struct4xi32(
|
||||
; CHECK-LABEL: define internal fastcc void @callee_struct4xi32.argprom(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: store <4 x i32> [[SRC_0_VAL:%.*]], ptr [[DST:%.*]], align 16
|
||||
; CHECK-NEXT: [[DST2:%.*]] = getelementptr inbounds [[STRUCT_4XI32:%.*]], ptr [[DST]], i64 0, i32 1
|
||||
|
@ -10,7 +10,7 @@
|
||||
; ALL: gvar_used
|
||||
@gvar_used = addrspace(1) global i32 undef, align 4
|
||||
|
||||
; OPT: define internal fastcc void @func_used_noinline(
|
||||
; OPT: define internal fastcc void @func_used_noinline.argelim(
|
||||
; OPT-NONE: define fastcc void @func_used_noinline(
|
||||
define fastcc void @func_used_noinline(ptr addrspace(1) %out, i32 %tid) #1 {
|
||||
entry:
|
||||
|
@ -84,22 +84,22 @@ attributes #0 = { noinline optnone }
|
||||
;; The first call to foo does not allocate cold memory. It should call the
|
||||
;; original functions, which ultimately call the original allocation decorated
|
||||
;; with a "notcold" attribute.
|
||||
; IR: call {{.*}} @_Z3foov()
|
||||
; IR: call {{.*}} @_Z3foov.retelim()
|
||||
;; The second call to foo allocates cold memory. It should call cloned functions
|
||||
;; which ultimately call a cloned allocation decorated with a "cold" attribute.
|
||||
; IR: call {{.*}} @_Z3foov.memprof.1()
|
||||
; IR: define internal {{.*}} @_Z3barv()
|
||||
; IR: call {{.*}} @_Z3foov.memprof.1.retelim()
|
||||
; IR: define internal {{.*}} @_Z3barv.retelim()
|
||||
; IR: call {{.*}} @_Znam(i64 0) #[[NOTCOLD:[0-9]+]]
|
||||
; IR: define internal {{.*}} @_Z3bazv()
|
||||
; IR: call {{.*}} @_Z3barv()
|
||||
; IR: define internal {{.*}} @_Z3foov()
|
||||
; IR: call {{.*}} @_Z3bazv()
|
||||
; IR: define internal {{.*}} @_Z3barv.memprof.1()
|
||||
; IR: define internal {{.*}} @_Z3bazv.retelim()
|
||||
; IR: call {{.*}} @_Z3barv.retelim()
|
||||
; IR: define internal {{.*}} @_Z3foov.retelim()
|
||||
; IR: call {{.*}} @_Z3bazv.retelim()
|
||||
; IR: define internal {{.*}} @_Z3barv.memprof.1.retelim()
|
||||
; IR: call {{.*}} @_Znam(i64 0) #[[COLD:[0-9]+]]
|
||||
; IR: define internal {{.*}} @_Z3bazv.memprof.1()
|
||||
; IR: call {{.*}} @_Z3barv.memprof.1()
|
||||
; IR: define internal {{.*}} @_Z3foov.memprof.1()
|
||||
; IR: call {{.*}} @_Z3bazv.memprof.1()
|
||||
; IR: define internal {{.*}} @_Z3bazv.memprof.1.retelim()
|
||||
; IR: call {{.*}} @_Z3barv.memprof.1.retelim()
|
||||
; IR: define internal {{.*}} @_Z3foov.memprof.1.retelim()
|
||||
; IR: call {{.*}} @_Z3bazv.memprof.1.retelim()
|
||||
; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IR: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
|
@ -84,22 +84,22 @@ attributes #0 = { noinline optnone }
|
||||
;; The first call to foo does not allocate cold memory. It should call the
|
||||
;; original functions, which ultimately call the original allocation decorated
|
||||
;; with a "notcold" attribute.
|
||||
; IR: call {{.*}} @_Z3foov()
|
||||
; IR: call {{.*}} @_Z3foov.retelim()
|
||||
;; The second call to foo allocates cold memory. It should call cloned functions
|
||||
;; which ultimately call a cloned allocation decorated with a "cold" attribute.
|
||||
; IR: call {{.*}} @_Z3foov.memprof.1()
|
||||
; IR: define internal {{.*}} @_Z3barv()
|
||||
; IR: call {{.*}} @_Z3foov.memprof.1.retelim()
|
||||
; IR: define internal {{.*}} @_Z3barv.retelim()
|
||||
; IR: call {{.*}} @_Znam(i64 0) #[[NOTCOLD:[0-9]+]]
|
||||
; IR: define internal {{.*}} @_Z3bazv()
|
||||
; IR: call {{.*}} @_Z3barv()
|
||||
; IR: define internal {{.*}} @_Z3foov()
|
||||
; IR: call {{.*}} @_Z3bazv()
|
||||
; IR: define internal {{.*}} @_Z3barv.memprof.1()
|
||||
; IR: define internal {{.*}} @_Z3bazv.retelim()
|
||||
; IR: call {{.*}} @_Z3barv.retelim()
|
||||
; IR: define internal {{.*}} @_Z3foov.retelim()
|
||||
; IR: call {{.*}} @_Z3bazv.retelim()
|
||||
; IR: define internal {{.*}} @_Z3barv.memprof.1.retelim()
|
||||
; IR: call {{.*}} @_Znam(i64 0) #[[COLD:[0-9]+]]
|
||||
; IR: define internal {{.*}} @_Z3bazv.memprof.1()
|
||||
; IR: call {{.*}} @_Z3barv.memprof.1()
|
||||
; IR: define internal {{.*}} @_Z3foov.memprof.1()
|
||||
; IR: call {{.*}} @_Z3bazv.memprof.1()
|
||||
; IR: define internal {{.*}} @_Z3bazv.memprof.1.retelim()
|
||||
; IR: call {{.*}} @_Z3barv.memprof.1.retelim()
|
||||
; IR: define internal {{.*}} @_Z3foov.memprof.1.retelim()
|
||||
; IR: call {{.*}} @_Z3bazv.memprof.1.retelim()
|
||||
; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IR: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
;; We should have cloned bar, baz, and foo, for the cold memory allocation.
|
||||
; RUN: cat %t.ccg.cloned.dot | FileCheck %s --check-prefix=DOTCLONED
|
||||
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IR
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IRNODIST
|
||||
|
||||
|
||||
;; Try again but with distributed ThinLTO
|
||||
@ -303,6 +303,23 @@ attributes #0 = { noinline optnone }
|
||||
; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IR: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; IRNODIST: define {{.*}} @main
|
||||
; IRNODIST: call {{.*}} @_Z3foov.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z3foov.memprof.1.retelim()
|
||||
; IRNODIST: define internal {{.*}} @_Z3barv.retelim()
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 0) #[[NOTCOLD:[0-9]+]]
|
||||
; IRNODIST: define internal {{.*}} @_Z3bazv.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z3barv.retelim()
|
||||
; IRNODIST: define internal {{.*}} @_Z3foov.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z3bazv.retelim()
|
||||
; IRNODIST: define internal {{.*}} @_Z3barv.memprof.1.retelim()
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 0) #[[COLD:[0-9]+]]
|
||||
; IRNODIST: define internal {{.*}} @_Z3bazv.memprof.1.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z3barv.memprof.1.retelim()
|
||||
; IRNODIST: define internal {{.*}} @_Z3foov.memprof.1.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z3bazv.memprof.1.retelim()
|
||||
; IRNODIST: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IRNODIST: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; STATS: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)
|
||||
; STATS-BE: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during ThinLTO backend
|
||||
|
@ -68,7 +68,7 @@
|
||||
; RUN: -o %t.out 2>&1 | FileCheck %s --check-prefix=DUMP \
|
||||
; RUN: --check-prefix=STATS --check-prefix=STATS-BE --check-prefix=REMARKS
|
||||
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IR
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IRNODIST
|
||||
|
||||
|
||||
;; Try again but with distributed ThinLTO
|
||||
@ -247,6 +247,18 @@ attributes #0 = { noinline optnone}
|
||||
; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IR: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; IRNODIST: define internal {{.*}} @_Z1Dv.retelim()
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 0) #[[NOTCOLD:[0-9]+]]
|
||||
; IRNODIST: define internal {{.*}} @_Z1Fv.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z1Dv.retelim()
|
||||
; IRNODIST: define internal {{.*}} @_Z1Bv.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z1Dv.memprof.1.retelim()
|
||||
; IRNODIST: define internal {{.*}} @_Z1Ev.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z1Dv.memprof.1.retelim()
|
||||
; IRNODIST: define internal {{.*}} @_Z1Dv.memprof.1.retelim()
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 0) #[[COLD:[0-9]+]]
|
||||
; IRNODIST: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IRNODIST: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; STATS: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)
|
||||
; STATS-BE: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during ThinLTO backend
|
||||
|
@ -61,7 +61,7 @@
|
||||
; RUN: -o %t.out 2>&1 | FileCheck %s --check-prefix=DUMP \
|
||||
; RUN: --check-prefix=STATS --check-prefix=STATS-BE --check-prefix=REMARKS
|
||||
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IR
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IRNODIST
|
||||
|
||||
|
||||
;; Try again but with distributed ThinLTO
|
||||
@ -283,6 +283,23 @@ attributes #0 = { noinline optnone }
|
||||
; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IR: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; IRNODIST: define internal {{.*}} @_Z1EPPcS0_.argelim(
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 noundef 10) #[[NOTCOLD:[0-9]+]]
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 noundef 10) #[[NOTCOLD]]
|
||||
; IRNODIST: define internal {{.*}} @_Z1BPPcS0_(
|
||||
; IRNODIST: call {{.*}} @_Z1EPPcS0_.argelim(
|
||||
; IRNODIST: define internal {{.*}} @_Z1CPPcS0_(
|
||||
; IRNODIST: call {{.*}} @_Z1EPPcS0_.memprof.3.argelim(
|
||||
; IRNODIST: define internal {{.*}} @_Z1DPPcS0_(
|
||||
; IRNODIST: call {{.*}} @_Z1EPPcS0_.memprof.2.argelim(
|
||||
; IRNODIST: define internal {{.*}} @_Z1EPPcS0_.memprof.2.argelim(
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 noundef 10) #[[COLD:[0-9]+]]
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 noundef 10) #[[NOTCOLD]]
|
||||
; IRNODIST: define internal {{.*}} @_Z1EPPcS0_.memprof.3.argelim(
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 noundef 10) #[[NOTCOLD]]
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 noundef 10) #[[COLD]]
|
||||
; IRNODIST: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IRNODIST: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; STATS: 2 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)
|
||||
; STATS-BE: 2 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during ThinLTO backend
|
||||
|
@ -74,7 +74,7 @@
|
||||
;; from main allocating cold memory.
|
||||
; RUN: cat %t.ccg.cloned.dot | FileCheck %s --check-prefix=DOTCLONED
|
||||
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IR
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IRNODIST
|
||||
|
||||
|
||||
;; Try again but with distributed ThinLTO
|
||||
@ -419,6 +419,19 @@ attributes #0 = { noinline optnone }
|
||||
; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IR: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; IRNODIST: define {{.*}} @main(
|
||||
; IRNODIST: call {{.*}} @_Z3foov.argelim()
|
||||
; IRNODIST: call {{.*}} @_Z3foov.memprof.1.argelim()
|
||||
; IRNODIST: call {{.*}} @_Z3barP1A.argelim(
|
||||
; IRNODIST: call {{.*}} @_Z3barP1A.argelim(
|
||||
; IRNODIST: call {{.*}} @_Z3barP1A.argelim(
|
||||
; IRNODIST: call {{.*}} @_Z3barP1A.argelim(
|
||||
; IRNODIST: define internal {{.*}} @_Z3foov.argelim()
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 0) #[[NOTCOLD:[0-9]+]]
|
||||
; IRNODIST: define internal {{.*}} @_Z3foov.memprof.1.argelim()
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 0) #[[COLD:[0-9]+]]
|
||||
; IRNODIST: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IRNODIST: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; STATS: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)
|
||||
; STATS-BE: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during ThinLTO backend
|
||||
|
@ -63,7 +63,7 @@
|
||||
;; cold memory.
|
||||
; RUN: cat %t.ccg.cloned.dot | FileCheck %s --check-prefix=DOTCLONED
|
||||
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IR
|
||||
; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s --check-prefix=IRNODIST
|
||||
|
||||
|
||||
;; Try again but with distributed ThinLTO
|
||||
@ -323,6 +323,19 @@ attributes #0 = { noinline optnone }
|
||||
; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IR: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; IRNODIST: define internal {{.*}} @_Z3barv.retelim()
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 0) #[[NOTCOLD:[0-9]+]]
|
||||
; IRNODIST: define internal {{.*}} @_Z3foov.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z3barv.retelim()
|
||||
; IRNODIST: define {{.*}} @main()
|
||||
; IRNODIST: call {{.*}} @_Z3foov.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z3foov.memprof.1.retelim()
|
||||
; IRNODIST: define internal {{.*}} @_Z3barv.memprof.1.retelim()
|
||||
; IRNODIST: call {{.*}} @_Znam(i64 0) #[[COLD:[0-9]+]]
|
||||
; IRNODIST: define internal {{.*}} @_Z3foov.memprof.1.retelim()
|
||||
; IRNODIST: call {{.*}} @_Z3barv.memprof.1.retelim()
|
||||
; IRNODIST: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
|
||||
; IRNODIST: attributes #[[COLD]] = { "memprof"="cold" }
|
||||
|
||||
; STATS: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)
|
||||
; STATS-BE: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during ThinLTO backend
|
||||
|
@ -3,7 +3,7 @@
|
||||
; RUN: cat %t | FileCheck -check-prefix=REMARK %s
|
||||
|
||||
define internal i32 @deref(ptr %x) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@deref
|
||||
; CHECK-LABEL: define {{[^@]+}}@deref.argprom
|
||||
; CHECK-SAME: (i32 [[X_0_VAL:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret i32 [[X_0_VAL]]
|
||||
@ -29,7 +29,7 @@ define i32 @f(i32 %x) {
|
||||
; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4
|
||||
; CHECK-NEXT: [[X_ADDR_VAL:%.*]] = load i32, ptr [[X_ADDR]], align 4
|
||||
; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @deref(i32 [[X_ADDR_VAL]])
|
||||
; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @deref.argprom(i32 [[X_ADDR_VAL]])
|
||||
; CHECK-NEXT: ret i32 [[TEMP1]]
|
||||
;
|
||||
entry:
|
||||
|
@ -85,4 +85,4 @@ entry:
|
||||
; Without number-of-argument constraint, argpromotion will create a function signature with 5 arguments, which equals
|
||||
; the maximum number of argument permitted by bpf backend, so argpromotion result code does work.
|
||||
;
|
||||
; CHECK: i32 @foo2(i32 %p1.0.val, i32 %p1.4.val, i32 %p2.8.val, i32 %p2.16.val, i32 %p3.20.val)
|
||||
; CHECK: i32 @foo2.argprom(i32 %p1.0.val, i32 %p1.4.val, i32 %p2.8.val, i32 %p2.16.val, i32 %p3.20.val)
|
||||
|
@ -42,7 +42,7 @@ bb:
|
||||
}
|
||||
|
||||
define internal fastcc void @promote_avx2(ptr %arg, ptr readonly %arg1) #0 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@promote_avx2
|
||||
; CHECK-LABEL: define {{[^@]+}}@promote_avx2.argprom
|
||||
; CHECK-SAME: (ptr [[ARG:%.*]], <4 x i64> [[ARG1_VAL:%.*]])
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: store <4 x i64> [[ARG1_VAL]], ptr [[ARG]]
|
||||
@ -62,7 +62,7 @@ define void @promote(ptr %arg) #0 {
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
|
||||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: [[TMP_VAL:%.*]] = load <4 x i64>, ptr [[TMP]]
|
||||
; CHECK-NEXT: call fastcc void @promote_avx2(ptr [[TMP2]], <4 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: call fastcc void @promote_avx2.argprom(ptr [[TMP2]], <4 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -7,7 +7,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; This should promote
|
||||
define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr %arg, ptr readonly %arg1) #0 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512.argprom
|
||||
; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
|
||||
@ -27,7 +27,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr %arg)
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512.argprom(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
@ -44,7 +44,7 @@ bb:
|
||||
|
||||
; This should promote
|
||||
define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr %arg, ptr readonly %arg1) #1 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256.argprom
|
||||
; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
|
||||
@ -64,7 +64,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr %arg)
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256.argprom(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
@ -81,7 +81,7 @@ bb:
|
||||
|
||||
; This should promote
|
||||
define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr %arg, ptr readonly %arg1) #1 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256.argprom
|
||||
; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
|
||||
@ -101,7 +101,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr %arg)
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256.argprom(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
@ -118,7 +118,7 @@ bb:
|
||||
|
||||
; This should promote
|
||||
define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr %arg, ptr readonly %arg1) #0 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512.argprom
|
||||
; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
|
||||
@ -138,7 +138,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr %arg)
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512.argprom(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
@ -229,7 +229,7 @@ bb:
|
||||
|
||||
; This should promote
|
||||
define internal fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr %arg, ptr readonly %arg1) #3 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256.argprom
|
||||
; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
|
||||
@ -249,7 +249,7 @@ define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr %arg) #4 {
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
|
||||
; CHECK-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256.argprom(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
@ -266,7 +266,7 @@ bb:
|
||||
|
||||
; This should promote
|
||||
define internal fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr %arg, ptr readonly %arg1) #4 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256.argprom
|
||||
; CHECK-SAME: (ptr [[ARG:%.*]], <8 x i64> [[ARG1_VAL:%.*]])
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: store <8 x i64> [[ARG1_VAL]], ptr [[ARG]]
|
||||
@ -286,7 +286,7 @@ define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr %arg) #3 {
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
|
||||
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 32 [[TMP]], i8 0, i64 32, i1 false)
|
||||
; CHECK-NEXT: [[TMP_VAL:%.*]] = load <8 x i64>, ptr [[TMP]]
|
||||
; CHECK-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: call fastcc void @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256.argprom(ptr [[TMP2]], <8 x i64> [[TMP_VAL]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, ptr [[TMP2]], align 32
|
||||
; CHECK-NEXT: store <8 x i64> [[TMP4]], ptr [[ARG]], align 2
|
||||
; CHECK-NEXT: ret void
|
||||
@ -303,7 +303,7 @@ bb:
|
||||
|
||||
; If the arguments are scalar, its ok to promote.
|
||||
define internal i32 @scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr %X, ptr %Y) #2 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256
|
||||
; CHECK-LABEL: define {{[^@]+}}@scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256.argprom
|
||||
; CHECK-SAME: (i32 [[X_VAL:%.*]], i32 [[Y_VAL:%.*]])
|
||||
; CHECK-NEXT: [[C:%.*]] = add i32 [[X_VAL]], [[Y_VAL]]
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
@ -321,7 +321,7 @@ define i32 @scalar_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr
|
||||
; CHECK-NEXT: store i32 1, ptr [[A]]
|
||||
; CHECK-NEXT: [[A_VAL:%.*]] = load i32, ptr [[A]]
|
||||
; CHECK-NEXT: [[B_VAL:%.*]] = load i32, ptr [[B]]
|
||||
; CHECK-NEXT: [[C:%.*]] = call i32 @scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(i32 [[A_VAL]], i32 [[B_VAL]])
|
||||
; CHECK-NEXT: [[C:%.*]] = call i32 @scalar_callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256.argprom(i32 [[A_VAL]], i32 [[B_VAL]])
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
;
|
||||
%A = alloca i32
|
||||
@ -332,7 +332,7 @@ define i32 @scalar_avx512_legal256_prefer256_call_avx512_legal512_prefer256(ptr
|
||||
|
||||
; If the arguments are scalar, its ok to promote.
|
||||
define internal i32 @scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr %X, ptr %Y) #2 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256
|
||||
; CHECK-LABEL: define {{[^@]+}}@scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256.argprom
|
||||
; CHECK-SAME: (i32 [[X_VAL:%.*]], i32 [[Y_VAL:%.*]])
|
||||
; CHECK-NEXT: [[C:%.*]] = add i32 [[X_VAL]], [[Y_VAL]]
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
@ -350,7 +350,7 @@ define i32 @scalar_avx512_legal512_prefer256_call_avx512_legal256_prefer256(ptr
|
||||
; CHECK-NEXT: store i32 1, ptr [[A]]
|
||||
; CHECK-NEXT: [[A_VAL:%.*]] = load i32, ptr [[A]]
|
||||
; CHECK-NEXT: [[B_VAL:%.*]] = load i32, ptr [[B]]
|
||||
; CHECK-NEXT: [[C:%.*]] = call i32 @scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(i32 [[A_VAL]], i32 [[B_VAL]])
|
||||
; CHECK-NEXT: [[C:%.*]] = call i32 @scalar_callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256.argprom(i32 [[A_VAL]], i32 [[B_VAL]])
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
;
|
||||
%A = alloca i32
|
||||
|
@ -23,7 +23,7 @@ define internal x86_thiscallcc void @internalfun(ptr %this, ptr inalloca(<{ %str
|
||||
; ARGPROMOTION-NEXT: call void @ext(ptr inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]])
|
||||
; ARGPROMOTION-NEXT: ret void
|
||||
;
|
||||
; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun
|
||||
; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun.argprom
|
||||
; GLOBALOPT_ARGPROMOTION-SAME: (ptr [[TMP0:%.*]]) unnamed_addr {
|
||||
; GLOBALOPT_ARGPROMOTION-NEXT: entry:
|
||||
; GLOBALOPT_ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A:%.*]] }>, ptr [[TMP0]], i32 0, i32 0
|
||||
@ -56,7 +56,7 @@ define void @exportedfun(ptr %a) {
|
||||
; GLOBALOPT_ARGPROMOTION-SAME: (ptr [[A:%.*]]) local_unnamed_addr {
|
||||
; GLOBALOPT_ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call ptr @llvm.stacksave.p0()
|
||||
; GLOBALOPT_ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4
|
||||
; GLOBALOPT_ARGPROMOTION-NEXT: call fastcc void @internalfun(ptr [[ARGMEM]])
|
||||
; GLOBALOPT_ARGPROMOTION-NEXT: call fastcc void @internalfun.argprom(ptr [[ARGMEM]])
|
||||
; GLOBALOPT_ARGPROMOTION-NEXT: call void @llvm.stackrestore.p0(ptr [[INALLOCA_SAVE]])
|
||||
; GLOBALOPT_ARGPROMOTION-NEXT: ret void
|
||||
;
|
||||
|
@ -12,7 +12,7 @@ define internal i32 @test_cannot_promote_1(ptr %p, ptr nocapture readonly %test_
|
||||
; CHECK-LABEL: define {{[^@]+}}@test_cannot_promote_1
|
||||
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
|
||||
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee.argprom(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
|
||||
; CHECK-NEXT: ret i32 [[SUM]]
|
||||
@ -33,7 +33,7 @@ define internal i32 @test_cannot_promote_2(ptr %p, ptr nocapture readonly %test_
|
||||
; CHECK-LABEL: define {{[^@]+}}@test_cannot_promote_2
|
||||
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
|
||||
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee.argprom(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
|
||||
; CHECK-NEXT: ret i32 [[SUM]]
|
||||
@ -54,7 +54,7 @@ define internal i32 @test_cannot_promote_3(ptr %p, ptr nocapture readonly %test_
|
||||
; CHECK-LABEL: define {{[^@]+}}@test_cannot_promote_3
|
||||
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
|
||||
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee.argprom(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
|
||||
; CHECK-NEXT: ret i32 [[SUM]]
|
||||
@ -77,7 +77,7 @@ define internal i32 @test_can_promote_1(ptr %p, ptr nocapture readonly %test_c)
|
||||
; CHECK-LABEL: define {{[^@]+}}@test_can_promote_1
|
||||
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
|
||||
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee.argprom(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
|
||||
; CHECK-NEXT: ret i32 [[SUM]]
|
||||
@ -101,7 +101,7 @@ define internal i32 @test_can_promote_2(ptr %p, ptr nocapture readonly %test_c)
|
||||
; CHECK-LABEL: define {{[^@]+}}@test_can_promote_2
|
||||
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
|
||||
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee.argprom(ptr [[P]], i32 [[TEST_C_VAL]])
|
||||
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
|
||||
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
|
||||
; CHECK-NEXT: ret i32 [[SUM]]
|
||||
|
@ -5,7 +5,7 @@
|
||||
@G = constant %T { i32 0, i32 0, i32 17, i32 25 }
|
||||
|
||||
define internal i32 @test(ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test
|
||||
; CHECK-LABEL: define {{[^@]+}}@test.argprom
|
||||
; CHECK-SAME: (i32 [[P_12_VAL:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[V:%.*]] = add i32 [[P_12_VAL]], 10
|
||||
@ -24,7 +24,7 @@ define i32 @caller() {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr @G, i64 12
|
||||
; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr [[TMP0]], align 4
|
||||
; CHECK-NEXT: [[V:%.*]] = call i32 @test(i32 [[G_VAL]])
|
||||
; CHECK-NEXT: [[V:%.*]] = call i32 @test.argprom(i32 [[G_VAL]])
|
||||
; CHECK-NEXT: ret i32 [[V]]
|
||||
;
|
||||
entry:
|
||||
|
@ -5,7 +5,7 @@
|
||||
@G = constant %T { i32 0, i32 0, i32 17, i32 25 }
|
||||
|
||||
define internal i32 @test(ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test
|
||||
; CHECK-LABEL: define {{[^@]+}}@test.argprom
|
||||
; CHECK-SAME: (i32 [[P_8_VAL:%.*]], i32 [[P_12_VAL:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[V:%.*]] = add i32 [[P_12_VAL]], [[P_8_VAL]]
|
||||
@ -27,7 +27,7 @@ define i32 @caller() {
|
||||
; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr [[TMP0]], align 4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr @G, i64 12
|
||||
; CHECK-NEXT: [[G_VAL1:%.*]] = load i32, ptr [[TMP1]], align 4
|
||||
; CHECK-NEXT: [[V:%.*]] = call i32 @test(i32 [[G_VAL]], i32 [[G_VAL1]])
|
||||
; CHECK-NEXT: [[V:%.*]] = call i32 @test.argprom(i32 [[G_VAL]], i32 [[G_VAL1]])
|
||||
; CHECK-NEXT: ret i32 [[V]]
|
||||
;
|
||||
entry:
|
||||
|
@ -2,7 +2,7 @@
|
||||
; RUN: opt -S -passes=argpromotion < %s | FileCheck %s
|
||||
|
||||
define internal i32 @callee_must_exec(ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_must_exec
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_must_exec.argprom
|
||||
; CHECK-SAME: (i32 [[P_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: ret i32 [[P_0_VAL]]
|
||||
;
|
||||
@ -14,7 +14,7 @@ define void @caller_must_exec(ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@caller_must_exec
|
||||
; CHECK-SAME: (ptr [[P:%.*]]) {
|
||||
; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 16
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_must_exec(i32 [[P_VAL]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_must_exec.argprom(i32 [[P_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call i32 @callee_must_exec(ptr %p)
|
||||
@ -22,7 +22,7 @@ define void @caller_must_exec(ptr %p) {
|
||||
}
|
||||
|
||||
define internal i32 @callee_guaranteed_aligned_1(i1 %c, ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_aligned_1
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_aligned_1.argprom
|
||||
; CHECK-SAME: (i1 [[C:%.*]], i32 [[P_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
|
||||
; CHECK: if:
|
||||
@ -44,7 +44,7 @@ define void @caller_guaranteed_aligned_1(i1 %c, ptr align 16 dereferenceable(4)
|
||||
; CHECK-LABEL: define {{[^@]+}}@caller_guaranteed_aligned_1
|
||||
; CHECK-SAME: (i1 [[C:%.*]], ptr align 16 dereferenceable(4) [[P:%.*]]) {
|
||||
; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 16
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_aligned_1(i1 [[C]], i32 [[P_VAL]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_aligned_1.argprom(i1 [[C]], i32 [[P_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call i32 @callee_guaranteed_aligned_1(i1 %c, ptr %p)
|
||||
@ -52,7 +52,7 @@ define void @caller_guaranteed_aligned_1(i1 %c, ptr align 16 dereferenceable(4)
|
||||
}
|
||||
|
||||
define internal i32 @callee_guaranteed_aligned_2(i1 %c, ptr align 16 dereferenceable(4) %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_aligned_2
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_aligned_2.argprom
|
||||
; CHECK-SAME: (i1 [[C:%.*]], i32 [[P_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
|
||||
; CHECK: if:
|
||||
@ -74,7 +74,7 @@ define void @caller_guaranteed_aligned_2(i1 %c, ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@caller_guaranteed_aligned_2
|
||||
; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
|
||||
; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 16
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_aligned_2(i1 [[C]], i32 [[P_VAL]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_aligned_2.argprom(i1 [[C]], i32 [[P_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call i32 @callee_guaranteed_aligned_2(i1 %c, ptr %p)
|
||||
@ -83,7 +83,7 @@ define void @caller_guaranteed_aligned_2(i1 %c, ptr %p) {
|
||||
|
||||
; We have seen the offset before but with a lower alignment
|
||||
define internal i32 @callee_guaranteed_aligned_3(i1 %c, ptr align 16 dereferenceable(4) %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_aligned_3
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_guaranteed_aligned_3.argprom
|
||||
; CHECK-SAME: (i1 [[C:%.*]], i32 [[P_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
|
||||
; CHECK: if:
|
||||
@ -106,7 +106,7 @@ define void @caller_guaranteed_aligned_3(i1 %c, ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@caller_guaranteed_aligned_3
|
||||
; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
|
||||
; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 16
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_aligned_3(i1 [[C]], i32 [[P_VAL]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_guaranteed_aligned_3.argprom(i1 [[C]], i32 [[P_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call i32 @callee_guaranteed_aligned_3(i1 %c, ptr %p)
|
||||
|
@ -6,7 +6,7 @@ declare ptr @calloc(i64, i64)
|
||||
|
||||
define internal ptr @my_alloc1(i64 %unchanged, ptr %unused, i64 %size, ptr %unused2) allocsize(2) {
|
||||
; CHECK: Function Attrs: allocsize(1)
|
||||
; CHECK-LABEL: define internal ptr @my_alloc1(
|
||||
; CHECK-LABEL: define internal ptr @my_alloc1.argprom(
|
||||
; CHECK-SAME: i64 [[UNCHANGED:%.*]], i64 [[SIZE:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; CHECK-NEXT: [[PTR:%.*]] = call ptr @malloc(i64 [[SIZE]])
|
||||
; CHECK-NEXT: ret ptr [[PTR]]
|
||||
@ -17,7 +17,7 @@ define internal ptr @my_alloc1(i64 %unchanged, ptr %unused, i64 %size, ptr %unus
|
||||
|
||||
define internal ptr @my_alloc2(i64 %unchanged, ptr %unused, i64 %size, i64 %size2, ptr %unused2) allocsize(2,3) {
|
||||
; CHECK: Function Attrs: allocsize(1,2)
|
||||
; CHECK-LABEL: define internal ptr @my_alloc2(
|
||||
; CHECK-LABEL: define internal ptr @my_alloc2.argprom(
|
||||
; CHECK-SAME: i64 [[UNCHANGED:%.*]], i64 [[SIZE:%.*]], i64 [[SIZE2:%.*]]) #[[ATTR1:[0-9]+]] {
|
||||
; CHECK-NEXT: [[PTR:%.*]] = call ptr @calloc(i64 [[SIZE]], i64 [[SIZE2]])
|
||||
; CHECK-NEXT: ret ptr [[PTR]]
|
||||
@ -28,7 +28,7 @@ define internal ptr @my_alloc2(i64 %unchanged, ptr %unused, i64 %size, i64 %size
|
||||
|
||||
define internal ptr @my_alloc3(i64 %unchanged, ptr %promoted, ptr %promoted2, i64 %size) allocsize(3) {
|
||||
; CHECK: Function Attrs: allocsize(5)
|
||||
; CHECK-LABEL: define internal ptr @my_alloc3(
|
||||
; CHECK-LABEL: define internal ptr @my_alloc3.argprom(
|
||||
; CHECK-SAME: i64 [[UNCHANGED:%.*]], i32 [[PROMOTED_0_VAL:%.*]], i32 [[PROMOTED_4_VAL:%.*]], i32 [[PROMOTED2_0_VAL:%.*]], i32 [[PROMOTED2_4_VAL:%.*]], i64 [[SIZE:%.*]]) #[[ATTR2:[0-9]+]] {
|
||||
; CHECK-NEXT: [[PTR:%.*]] = call ptr @malloc(i64 [[SIZE]])
|
||||
; CHECK-NEXT: ret ptr [[PTR]]
|
||||
@ -47,7 +47,7 @@ define internal ptr @my_alloc3(i64 %unchanged, ptr %promoted, ptr %promoted2, i6
|
||||
|
||||
define internal ptr @my_alloc4(i64 %unchanged, ptr %promoted, ptr %promoted2, i64 %size, i64 %size2) allocsize(3,4) {
|
||||
; CHECK: Function Attrs: allocsize(5,6)
|
||||
; CHECK-LABEL: define internal ptr @my_alloc4(
|
||||
; CHECK-LABEL: define internal ptr @my_alloc4.argprom(
|
||||
; CHECK-SAME: i64 [[UNCHANGED:%.*]], i32 [[PROMOTED_0_VAL:%.*]], i32 [[PROMOTED_4_VAL:%.*]], i32 [[PROMOTED2_0_VAL:%.*]], i32 [[PROMOTED2_4_VAL:%.*]], i64 [[SIZE:%.*]], i64 [[SIZE2:%.*]]) #[[ATTR3:[0-9]+]] {
|
||||
; CHECK-NEXT: [[PTR:%.*]] = call ptr @calloc(i64 [[SIZE]], i64 [[SIZE2]])
|
||||
; CHECK-NEXT: ret ptr [[PTR]]
|
||||
@ -67,22 +67,22 @@ define internal ptr @my_alloc4(i64 %unchanged, ptr %promoted, ptr %promoted2, i6
|
||||
define void @call_my_alloc(ptr %arg, ptr %arg2) {
|
||||
; CHECK-LABEL: define void @call_my_alloc(
|
||||
; CHECK-SAME: ptr [[ARG:%.*]], ptr [[ARG2:%.*]]) {
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @my_alloc1(i64 0, i64 2)
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = call ptr @my_alloc2(i64 0, i64 2, i64 2)
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @my_alloc1.argprom(i64 0, i64 2)
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = call ptr @my_alloc2.argprom(i64 0, i64 2, i64 2)
|
||||
; CHECK-NEXT: [[ARG_VAL:%.*]] = load i32, ptr [[ARG]], align 4
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[ARG]], i64 4
|
||||
; CHECK-NEXT: [[ARG_VAL1:%.*]] = load i32, ptr [[TMP3]], align 4
|
||||
; CHECK-NEXT: [[ARG2_VAL:%.*]] = load i32, ptr [[ARG2]], align 4
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[ARG2]], i64 4
|
||||
; CHECK-NEXT: [[ARG2_VAL2:%.*]] = load i32, ptr [[TMP4]], align 4
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = call ptr @my_alloc3(i64 0, i32 [[ARG_VAL]], i32 [[ARG_VAL1]], i32 [[ARG2_VAL]], i32 [[ARG2_VAL2]], i64 2)
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = call ptr @my_alloc3.argprom(i64 0, i32 [[ARG_VAL]], i32 [[ARG_VAL1]], i32 [[ARG2_VAL]], i32 [[ARG2_VAL2]], i64 2)
|
||||
; CHECK-NEXT: [[ARG_VAL3:%.*]] = load i32, ptr [[ARG]], align 4
|
||||
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[ARG]], i64 4
|
||||
; CHECK-NEXT: [[ARG_VAL4:%.*]] = load i32, ptr [[TMP6]], align 4
|
||||
; CHECK-NEXT: [[ARG2_VAL5:%.*]] = load i32, ptr [[ARG2]], align 4
|
||||
; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[ARG2]], i64 4
|
||||
; CHECK-NEXT: [[ARG2_VAL6:%.*]] = load i32, ptr [[TMP7]], align 4
|
||||
; CHECK-NEXT: [[TMP8:%.*]] = call ptr @my_alloc4(i64 0, i32 [[ARG_VAL3]], i32 [[ARG_VAL4]], i32 [[ARG2_VAL5]], i32 [[ARG2_VAL6]], i64 2, i64 2)
|
||||
; CHECK-NEXT: [[TMP8:%.*]] = call ptr @my_alloc4.argprom(i64 0, i32 [[ARG_VAL3]], i32 [[ARG_VAL4]], i32 [[ARG2_VAL5]], i32 [[ARG2_VAL6]], i64 2, i64 2)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%ptr = call ptr @my_alloc1(i64 0, ptr null, i64 2, ptr null)
|
||||
|
@ -4,7 +4,7 @@
|
||||
%struct.ss = type { i32, i64 }
|
||||
|
||||
define internal void @f(ptr byval(%struct.ss) align 4 %b, ptr byval(i32) align 4 %X, i32 %i) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@f
|
||||
; CHECK-LABEL: define {{[^@]+}}@f.argprom
|
||||
; CHECK-SAME: (i32 [[B_0:%.*]], i32 [[X:%.*]], i32 [[I:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TEMP:%.*]] = add i32 [[B_0]], 1
|
||||
@ -30,7 +30,7 @@ define i32 @test(ptr %X) {
|
||||
; CHECK-NEXT: store i64 2, ptr [[TEMP4]], align 4
|
||||
; CHECK-NEXT: [[S_0_VAL:%.*]] = load i32, ptr [[S]], align 4
|
||||
; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4
|
||||
; CHECK-NEXT: call void @f(i32 [[S_0_VAL]], i32 [[X_VAL]], i32 zeroext 0)
|
||||
; CHECK-NEXT: call void @f.argprom(i32 [[S_0_VAL]], i32 [[X_VAL]], i32 zeroext 0)
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
@ -3,7 +3,7 @@
|
||||
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(ptr %X, ptr %Y) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test
|
||||
; CHECK-LABEL: define {{[^@]+}}@test.argprom
|
||||
; CHECK-SAME: (i32 [[X_0_VAL:%.*]], i32 [[Y_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: [[C:%.*]] = add i32 [[X_0_VAL]], [[Y_0_VAL]]
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
@ -15,9 +15,9 @@ define internal i32 @test(ptr %X, ptr %Y) {
|
||||
}
|
||||
|
||||
define internal i32 @caller(ptr %B) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@caller
|
||||
; CHECK-LABEL: define {{[^@]+}}@caller.argprom
|
||||
; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: [[C:%.*]] = call i32 @test(i32 1, i32 [[B_0_VAL]])
|
||||
; CHECK-NEXT: [[C:%.*]] = call i32 @test.argprom(i32 1, i32 [[B_0_VAL]])
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
;
|
||||
%A = alloca i32
|
||||
@ -28,7 +28,7 @@ define internal i32 @caller(ptr %B) {
|
||||
|
||||
define i32 @callercaller() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callercaller() {
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @caller(i32 2)
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @caller.argprom(i32 2)
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
;
|
||||
%B = alloca i32
|
||||
|
@ -6,7 +6,7 @@
|
||||
%opaque = type opaque
|
||||
|
||||
define internal i32 @callee_basic(ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_basic
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_basic.argprom
|
||||
; CHECK-SAME: (i32 [[P_0_VAL:%.*]], i32 [[P_4_VAL:%.*]]) {
|
||||
; CHECK-NEXT: [[Z:%.*]] = add i32 [[P_0_VAL]], [[P_4_VAL]]
|
||||
; CHECK-NEXT: ret i32 [[Z]]
|
||||
@ -24,7 +24,7 @@ define void @caller_basic(ptr %p) {
|
||||
; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 4
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[P]], i64 4
|
||||
; CHECK-NEXT: [[P_VAL1:%.*]] = load i32, ptr [[TMP2]], align 4
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = call i32 @callee_basic(i32 [[P_VAL]], i32 [[P_VAL1]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = call i32 @callee_basic.argprom(i32 [[P_VAL]], i32 [[P_VAL1]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call i32 @callee_basic(ptr %p)
|
||||
@ -32,7 +32,7 @@ define void @caller_basic(ptr %p) {
|
||||
}
|
||||
|
||||
define internal i32 @callee_opaque(ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_opaque
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_opaque.argprom
|
||||
; CHECK-SAME: (i32 [[P_0_VAL:%.*]], i32 [[P_4_VAL:%.*]]) {
|
||||
; CHECK-NEXT: [[Z:%.*]] = add i32 [[P_0_VAL]], [[P_4_VAL]]
|
||||
; CHECK-NEXT: ret i32 [[Z]]
|
||||
@ -50,7 +50,7 @@ define void @caller_opaque(ptr %p) {
|
||||
; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 4
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[P]], i64 4
|
||||
; CHECK-NEXT: [[P_VAL1:%.*]] = load i32, ptr [[TMP3]], align 4
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = call i32 @callee_opaque(i32 [[P_VAL]], i32 [[P_VAL1]])
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = call i32 @callee_opaque.argprom(i32 [[P_VAL]], i32 [[P_VAL1]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call i32 @callee_opaque(ptr %p)
|
||||
|
@ -6,7 +6,7 @@
|
||||
%struct.ss = type { i32, i64 }
|
||||
|
||||
define internal void @f(ptr byval(%struct.ss) align 8 %b, ptr byval(i32) align 4 %X) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@f
|
||||
; CHECK-LABEL: define {{[^@]+}}@f.argprom
|
||||
; CHECK-SAME: (i32 [[B_0:%.*]], i32 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TEMP:%.*]] = add i32 [[B_0]], 1
|
||||
@ -31,7 +31,7 @@ define i32 @test(ptr %X) {
|
||||
; CHECK-NEXT: store i64 2, ptr [[TEMP4]], align 4
|
||||
; CHECK-NEXT: [[S_0_VAL:%.*]] = load i32, ptr [[S]], align 4
|
||||
; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4
|
||||
; CHECK-NEXT: call void @f(i32 [[S_0_VAL]], i32 [[X_VAL]])
|
||||
; CHECK-NEXT: call void @f.argprom(i32 [[S_0_VAL]], i32 [[X_VAL]])
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
@ -4,7 +4,7 @@
|
||||
%struct.A = type { float, [12 x i8], i64, [8 x i8] }
|
||||
|
||||
define internal float @callee(ptr byval(%struct.A) align 32 %0) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee.argprom
|
||||
; CHECK-SAME: (float [[DOT0_VAL:%.*]], i64 [[DOT16_VAL:%.*]]) {
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = fadd float 0.000000e+00, [[DOT0_VAL]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = uitofp i64 [[DOT16_VAL]] to float
|
||||
@ -30,7 +30,7 @@ define float @caller(float %0) {
|
||||
; CHECK-NEXT: [[DOTVAL:%.*]] = load float, ptr [[TMP2]], align 32
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP2]], i64 16
|
||||
; CHECK-NEXT: [[DOTVAL1:%.*]] = load i64, ptr [[TMP4]], align 16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = call noundef float @callee(float [[DOTVAL]], i64 [[DOTVAL1]])
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = call noundef float @callee.argprom(float [[DOTVAL]], i64 [[DOTVAL1]])
|
||||
; CHECK-NEXT: ret float [[TMP5]]
|
||||
;
|
||||
%2 = alloca %struct.A, align 32
|
||||
|
@ -6,7 +6,7 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
|
||||
%struct.ss = type { i32, i64 }
|
||||
|
||||
define internal void @f(ptr byval(%struct.ss) align 4 %b) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@f
|
||||
; CHECK-LABEL: define {{[^@]+}}@f.argprom
|
||||
; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[B_0_VAL]], 1
|
||||
@ -20,7 +20,7 @@ entry:
|
||||
}
|
||||
|
||||
define internal void @g(ptr byval(%struct.ss) align 32 %b) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@g
|
||||
; CHECK-LABEL: define {{[^@]+}}@g.argprom
|
||||
; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) #[[ATTR0]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[B_0_VAL]], 1
|
||||
@ -56,7 +56,7 @@ entry:
|
||||
|
||||
; Transform even if an argument is written to and then is loaded from.
|
||||
define internal void @k(ptr byval(%struct.ss) align 4 %b) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@k
|
||||
; CHECK-LABEL: define {{[^@]+}}@k.argprom
|
||||
; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) #[[ATTR0]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[B_0_VAL]], 1
|
||||
@ -72,7 +72,7 @@ entry:
|
||||
|
||||
; Transform even if a store instruction is the single user.
|
||||
define internal void @l(ptr byval(%struct.ss) align 4 %b) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@l
|
||||
; CHECK-LABEL: define {{[^@]+}}@l.argprom
|
||||
; CHECK-SAME: (i32 [[B_0_VAL:%.*]]) #[[ATTR0]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret void
|
||||
@ -85,7 +85,7 @@ entry:
|
||||
; Transform all the arguments creating the required number of 'alloca's and
|
||||
; then optimize them out.
|
||||
define internal void @m(ptr byval(%struct.ss) align 4 %b, ptr byval(%struct.ss) align 4 %c) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@m
|
||||
; CHECK-LABEL: define {{[^@]+}}@m.argprom
|
||||
; CHECK-SAME: (i32 [[B_0_VAL:%.*]], i32 [[C_0_VAL:%.*]], i64 [[C_4_VAL:%.*]]) #[[ATTR0]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TEMP2:%.*]] = add i32 [[B_0_VAL]], 1
|
||||
@ -116,19 +116,19 @@ define i32 @main() nounwind {
|
||||
; CHECK-NEXT: [[TEMP4:%.*]] = getelementptr [[STRUCT_SS]], ptr [[S]], i32 0, i32 1
|
||||
; CHECK-NEXT: store i64 2, ptr [[TEMP4]], align 4
|
||||
; CHECK-NEXT: [[S_VAL:%.*]] = load i32, ptr [[S]], align 4
|
||||
; CHECK-NEXT: call void @f(i32 [[S_VAL]])
|
||||
; CHECK-NEXT: call void @f.argprom(i32 [[S_VAL]])
|
||||
; CHECK-NEXT: [[S_VAL1:%.*]] = load i32, ptr [[S]], align 4
|
||||
; CHECK-NEXT: call void @g(i32 [[S_VAL1]])
|
||||
; CHECK-NEXT: call void @g.argprom(i32 [[S_VAL1]])
|
||||
; CHECK-NEXT: call void @h(ptr byval([[STRUCT_SS]]) [[S]])
|
||||
; CHECK-NEXT: [[S_VAL2:%.*]] = load i32, ptr [[S]], align 4
|
||||
; CHECK-NEXT: call void @k(i32 [[S_VAL2]])
|
||||
; CHECK-NEXT: call void @k.argprom(i32 [[S_VAL2]])
|
||||
; CHECK-NEXT: [[S_VAL3:%.*]] = load i32, ptr [[S]], align 4
|
||||
; CHECK-NEXT: call void @l(i32 [[S_VAL3]])
|
||||
; CHECK-NEXT: call void @l.argprom(i32 [[S_VAL3]])
|
||||
; CHECK-NEXT: [[S_VAL4:%.*]] = load i32, ptr [[S]], align 4
|
||||
; CHECK-NEXT: [[S_VAL5:%.*]] = load i32, ptr [[S]], align 4
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i64 4
|
||||
; CHECK-NEXT: [[S_VAL6:%.*]] = load i64, ptr [[TMP0]], align 8
|
||||
; CHECK-NEXT: call void @m(i32 [[S_VAL4]], i32 [[S_VAL5]], i64 [[S_VAL6]])
|
||||
; CHECK-NEXT: call void @m.argprom(i32 [[S_VAL4]], i32 [[S_VAL5]], i64 [[S_VAL6]])
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
@ -5,7 +5,7 @@
|
||||
@G2 = constant ptr @G1
|
||||
|
||||
define internal i32 @test(ptr %x) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test
|
||||
; CHECK-LABEL: define {{[^@]+}}@test.argprom.argprom
|
||||
; CHECK-SAME: (i32 [[X_0_VAL_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret i32 [[X_0_VAL_0_VAL]]
|
||||
@ -21,7 +21,7 @@ define i32 @caller() {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[G2_VAL:%.*]] = load ptr, ptr @G2, align 8
|
||||
; CHECK-NEXT: [[G2_VAL_VAL:%.*]] = load i32, ptr [[G2_VAL]], align 4
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @test(i32 [[G2_VAL_VAL]])
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @test.argprom.argprom(i32 [[G2_VAL_VAL]])
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
;
|
||||
entry:
|
||||
|
@ -4,7 +4,7 @@
|
||||
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, ptr %P) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee.argprom
|
||||
; CHECK-SAME: (i1 [[C:%.*]], i32 [[P_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
||||
; CHECK: T:
|
||||
@ -27,7 +27,7 @@ define i32 @foo() {
|
||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: store i32 17, ptr [[A]], align 4
|
||||
; CHECK-NEXT: [[A_VAL:%.*]] = load i32, ptr [[A]], align 4
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32 [[A_VAL]])
|
||||
; CHECK-NEXT: [[X:%.*]] = call i32 @callee.argprom(i1 false, i32 [[A_VAL]])
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
;
|
||||
%A = alloca i32 ; <ptr> [#uses=2]
|
||||
|
@ -44,7 +44,7 @@ bb:
|
||||
}
|
||||
|
||||
define internal i1 @eggs(ptr %arg) {
|
||||
; ARGPROMOTION-LABEL: define {{[^@]+}}@eggs() {
|
||||
; ARGPROMOTION-LABEL: define {{[^@]+}}@eggs.argprom() {
|
||||
; ARGPROMOTION-NEXT: bb:
|
||||
; ARGPROMOTION-NEXT: unreachable
|
||||
;
|
||||
|
@ -4,7 +4,7 @@
|
||||
declare void @sink(i32)
|
||||
|
||||
define internal void @test(ptr %X) !dbg !2 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test
|
||||
; CHECK-LABEL: define {{[^@]+}}@test.argprom.argprom
|
||||
; CHECK-SAME: (i32 [[X_0_VAL_0_VAL:%.*]]) !dbg [[DBG3:![0-9]+]] {
|
||||
; CHECK-NEXT: call void @sink(i32 [[X_0_VAL_0_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
@ -37,7 +37,7 @@ define void @caller(ptr %Y, ptr %P) {
|
||||
; CHECK-SAME: (ptr [[Y:%.*]], ptr [[P:%.*]]) {
|
||||
; CHECK-NEXT: [[Y_VAL:%.*]] = load ptr, ptr [[Y]], align 8, !dbg [[DBG4:![0-9]+]]
|
||||
; CHECK-NEXT: [[Y_VAL_VAL:%.*]] = load i32, ptr [[Y_VAL]], align 8, !dbg [[DBG4]]
|
||||
; CHECK-NEXT: call void @test(i32 [[Y_VAL_VAL]]), !dbg [[DBG4]]
|
||||
; CHECK-NEXT: call void @test.argprom.argprom(i32 [[Y_VAL_VAL]]), !dbg [[DBG4]]
|
||||
; CHECK-NEXT: call void @test_byval(ptr byval([[STRUCT_PAIR:%.*]]) align 4 [[P]]), !dbg [[DBG5:![0-9]+]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
|
@ -16,12 +16,12 @@ define void @run() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@run() {
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr @b, i64 10
|
||||
; CHECK-NEXT: [[B_VAL:%.*]] = load i8, ptr [[TMP1]], align 1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = tail call i8 @UseLongDoubleUnsafely(i8 [[B_VAL]])
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = tail call i8 @UseLongDoubleUnsafely.argprom(i8 [[B_VAL]])
|
||||
; CHECK-NEXT: [[B_VAL1:%.*]] = load x86_fp80, ptr @b, align 16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = tail call x86_fp80 @UseLongDoubleSafely(x86_fp80 [[B_VAL1]])
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = tail call x86_fp80 @UseLongDoubleSafely.argprom(x86_fp80 [[B_VAL1]])
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = tail call x86_fp80 @UseLongDoubleSafelyNoPromotion(ptr byval([[UNION_U:%.*]]) align 16 @b)
|
||||
; CHECK-NEXT: [[A_VAL:%.*]] = load i64, ptr @a, align 8
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = call i64 @AccessPaddingOfStruct(i64 [[A_VAL]])
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = call i64 @AccessPaddingOfStruct.argprom(i64 [[A_VAL]])
|
||||
; CHECK-NEXT: [[TMP6:%.*]] = call i64 @CaptureAStruct(ptr byval([[STRUCT_FOO:%.*]]) @a)
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
@ -34,7 +34,7 @@ define void @run() {
|
||||
}
|
||||
|
||||
define internal i8 @UseLongDoubleUnsafely(ptr byval(%union.u) align 16 %arg) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@UseLongDoubleUnsafely
|
||||
; CHECK-LABEL: define {{[^@]+}}@UseLongDoubleUnsafely.argprom
|
||||
; CHECK-SAME: (i8 [[ARG_10_VAL:%.*]]) {
|
||||
; CHECK-NEXT: ret i8 [[ARG_10_VAL]]
|
||||
;
|
||||
@ -44,7 +44,7 @@ define internal i8 @UseLongDoubleUnsafely(ptr byval(%union.u) align 16 %arg) {
|
||||
}
|
||||
|
||||
define internal x86_fp80 @UseLongDoubleSafely(ptr byval(%union.u) align 16 %arg) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@UseLongDoubleSafely
|
||||
; CHECK-LABEL: define {{[^@]+}}@UseLongDoubleSafely.argprom
|
||||
; CHECK-SAME: (x86_fp80 [[ARG_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: ret x86_fp80 [[ARG_0_VAL]]
|
||||
;
|
||||
@ -71,7 +71,7 @@ define internal x86_fp80 @UseLongDoubleSafelyNoPromotion(ptr byval(%union.u) ali
|
||||
}
|
||||
|
||||
define internal i64 @AccessPaddingOfStruct(ptr byval(%struct.Foo) %a) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@AccessPaddingOfStruct
|
||||
; CHECK-LABEL: define {{[^@]+}}@AccessPaddingOfStruct.argprom
|
||||
; CHECK-SAME: (i64 [[A_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: ret i64 [[A_0_VAL]]
|
||||
;
|
||||
|
@ -7,7 +7,7 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
|
||||
|
||||
; Argpromote + sroa should change this to passing the two integers by value.
|
||||
define internal i32 @f(ptr inalloca(%struct.ss) %s) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@f
|
||||
; CHECK-LABEL: define {{[^@]+}}@f.argprom
|
||||
; CHECK-SAME: (i32 [[S_0_VAL:%.*]], i32 [[S_4_VAL:%.*]]) unnamed_addr {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[R:%.*]] = add i32 [[S_0_VAL]], [[S_4_VAL]]
|
||||
@ -24,7 +24,7 @@ entry:
|
||||
define i32 @main() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@main() local_unnamed_addr {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[R:%.*]] = call fastcc i32 @f(i32 1, i32 2)
|
||||
; CHECK-NEXT: [[R:%.*]] = call fastcc i32 @f.argprom(i32 1, i32 2)
|
||||
; CHECK-NEXT: ret i32 [[R]]
|
||||
;
|
||||
entry:
|
||||
|
@ -12,7 +12,7 @@
|
||||
@G = constant i32 0
|
||||
|
||||
define internal i32 @a(ptr %x) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@a
|
||||
; CHECK-LABEL: define {{[^@]+}}@a.argprom
|
||||
; CHECK-SAME: (i32 [[X_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret i32 [[X_0_VAL]]
|
||||
@ -26,7 +26,7 @@ define i32 @b() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@b() {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr @G, align 4
|
||||
; CHECK-NEXT: [[V:%.*]] = call i32 @a(i32 [[G_VAL]])
|
||||
; CHECK-NEXT: [[V:%.*]] = call i32 @a.argprom(i32 [[G_VAL]])
|
||||
; CHECK-NEXT: ret i32 [[V]]
|
||||
;
|
||||
entry:
|
||||
@ -38,7 +38,7 @@ define i32 @c() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@c() {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr @G, align 4
|
||||
; CHECK-NEXT: [[V1:%.*]] = call i32 @a(i32 [[G_VAL]])
|
||||
; CHECK-NEXT: [[V1:%.*]] = call i32 @a.argprom(i32 [[G_VAL]])
|
||||
; CHECK-NEXT: [[V2:%.*]] = call i32 @b()
|
||||
; CHECK-NEXT: [[RESULT:%.*]] = add i32 [[V1]], [[V2]]
|
||||
; CHECK-NEXT: ret i32 [[RESULT]]
|
||||
|
@ -66,7 +66,7 @@ define internal void @call_load_maxalign_alloca_maxalign() {
|
||||
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [13 x i16], align 4294967296, addrspace(5)
|
||||
; CHECK-NEXT: [[ADDRSPACECAST:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
|
||||
; CHECK-NEXT: [[ADDRSPACECAST_VAL:%.*]] = load i32, ptr [[ADDRSPACECAST]], align 4294967296
|
||||
; CHECK-NEXT: call void @load_maxalign1(i32 [[ADDRSPACECAST_VAL]])
|
||||
; CHECK-NEXT: call void @load_maxalign1.argprom(i32 [[ADDRSPACECAST_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
bb:
|
||||
@ -77,7 +77,7 @@ bb:
|
||||
}
|
||||
|
||||
define internal void @load_maxalign1(ptr %arg) {
|
||||
; CHECK-LABEL: define internal void @load_maxalign1
|
||||
; CHECK-LABEL: define internal void @load_maxalign1.argprom
|
||||
; CHECK-SAME: (i32 [[ARG_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: br label [[BB1:%.*]]
|
||||
@ -110,7 +110,7 @@ define internal void @call_load_maxalign_alloca_ptr128() {
|
||||
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [13 x i16], align 4294967296, addrspace(6)
|
||||
; CHECK-NEXT: [[ADDRSPACECAST:%.*]] = addrspacecast ptr addrspace(6) [[ALLOCA]] to ptr
|
||||
; CHECK-NEXT: [[ADDRSPACECAST_VAL:%.*]] = load i32, ptr [[ADDRSPACECAST]], align 4294967296
|
||||
; CHECK-NEXT: call void @load_maxalign2(i32 [[ADDRSPACECAST_VAL]])
|
||||
; CHECK-NEXT: call void @load_maxalign2.argprom(i32 [[ADDRSPACECAST_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
bb:
|
||||
@ -121,7 +121,7 @@ bb:
|
||||
}
|
||||
|
||||
define internal void @load_maxalign2(ptr %arg) {
|
||||
; CHECK-LABEL: define internal void @load_maxalign2
|
||||
; CHECK-LABEL: define internal void @load_maxalign2.argprom
|
||||
; CHECK-SAME: (i32 [[ARG_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: bb:
|
||||
; CHECK-NEXT: br label [[BB1:%.*]]
|
||||
|
@ -2,7 +2,7 @@
|
||||
; RUN: opt -passes=argpromotion -S %s | FileCheck %s
|
||||
|
||||
define internal i32 @callee2(ptr noundef %0) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee2
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee2.argprom
|
||||
; CHECK-SAME: (i32 [[DOT0_VAL:%.*]], i32 [[DOT4_VAL:%.*]]) {
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[DOT0_VAL]], [[DOT4_VAL]]
|
||||
; CHECK-NEXT: ret i32 [[TMP1]]
|
||||
@ -24,7 +24,7 @@ define i32 @caller2(i32 %0, i32 %1) {
|
||||
; CHECK-NEXT: [[DOTVAL:%.*]] = load i32, ptr [[TMP3]], align 4
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP3]], i64 4
|
||||
; CHECK-NEXT: [[DOTVAL1:%.*]] = load i32, ptr [[TMP5]], align 4
|
||||
; CHECK-NEXT: [[TMP6:%.*]] = call i32 @callee2(i32 [[DOTVAL]], i32 [[DOTVAL1]])
|
||||
; CHECK-NEXT: [[TMP6:%.*]] = call i32 @callee2.argprom(i32 [[DOTVAL]], i32 [[DOTVAL1]])
|
||||
; CHECK-NEXT: ret i32 [[TMP6]]
|
||||
;
|
||||
%3 = alloca [2 x i32], align 4
|
||||
|
@ -5,7 +5,7 @@ declare void @use.i32(i32)
|
||||
declare void @use.p32(ptr)
|
||||
|
||||
define internal void @callee(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p7, ptr %p8, ptr %p9, ptr %p10) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee.argprom
|
||||
; CHECK-SAME: (i32 [[P1_0_VAL:%.*]], i32 [[P2_0_VAL:%.*]], ptr [[P3_0_VAL:%.*]], ptr [[P4_0_VAL:%.*]], ptr [[P5_0_VAL:%.*]], ptr [[P6_0_VAL:%.*]], ptr [[P7_0_VAL:%.*]], ptr [[P8_0_VAL:%.*]], ptr [[P9_0_VAL:%.*]], ptr [[P10_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[P4_0_VAL]], null
|
||||
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
|
||||
@ -57,7 +57,7 @@ define void @caller(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p
|
||||
; CHECK-NEXT: [[P8_VAL:%.*]] = load ptr, ptr [[P8]], align 8, !align !3, !noundef !1
|
||||
; CHECK-NEXT: [[P9_VAL:%.*]] = load ptr, ptr [[P9]], align 8, !noundef !1
|
||||
; CHECK-NEXT: [[P10_VAL:%.*]] = load ptr, ptr [[P10]], align 8, !nontemporal !4
|
||||
; CHECK-NEXT: call void @callee(i32 [[P1_VAL]], i32 [[P2_VAL]], ptr [[P3_VAL]], ptr [[P4_VAL]], ptr [[P5_VAL]], ptr [[P6_VAL]], ptr [[P7_VAL]], ptr [[P8_VAL]], ptr [[P9_VAL]], ptr [[P10_VAL]])
|
||||
; CHECK-NEXT: call void @callee.argprom(i32 [[P1_VAL]], i32 [[P2_VAL]], ptr [[P3_VAL]], ptr [[P4_VAL]], ptr [[P5_VAL]], ptr [[P6_VAL]], ptr [[P7_VAL]], ptr [[P8_VAL]], ptr [[P9_VAL]], ptr [[P10_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call void @callee(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p7, ptr %p8, ptr %p9, ptr %p10)
|
||||
@ -65,7 +65,7 @@ define void @caller(ptr %p1, ptr %p2, ptr %p3, ptr %p4, ptr %p5, ptr %p6, ptr %p
|
||||
}
|
||||
|
||||
define internal ptr @callee_conditional(i1 %c, ptr dereferenceable(8) align 8 %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_conditional
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_conditional.argprom
|
||||
; CHECK-SAME: (i1 [[C:%.*]], ptr [[P_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
|
||||
; CHECK: if:
|
||||
@ -89,7 +89,7 @@ define void @caller_conditional(i1 %c, ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@caller_conditional
|
||||
; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
|
||||
; CHECK-NEXT: [[P_VAL:%.*]] = load ptr, ptr [[P]], align 8
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @callee_conditional(i1 [[C]], ptr [[P_VAL]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @callee_conditional.argprom(i1 [[C]], ptr [[P_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call ptr @callee_conditional(i1 %c, ptr %p)
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
; CHECK-LABEL: define i32 @foo() #0 {
|
||||
; CHECK-NEXT: %.val = load <32 x half>, ptr undef, align 4
|
||||
; CHECK-NEXT: call void @bar(<32 x half> %.val)
|
||||
; CHECK-NEXT: call void @bar.argprom(<32 x half> %.val)
|
||||
; CHECK-NEXT: ret i32 0
|
||||
; CHECK-NEXT: }
|
||||
|
||||
; CHECK-LABEL: define internal void @bar(<32 x half> %.0.val) #0 {
|
||||
; CHECK-LABEL: define internal void @bar.argprom(<32 x half> %.0.val) #0 {
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK-NEXT: }
|
||||
|
||||
|
@ -11,7 +11,7 @@ target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
|
||||
define i32 @bar() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@bar() addrspace(1) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call addrspace(1) i32 @foo()
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call addrspace(1) i32 @foo.argprom()
|
||||
; CHECK-NEXT: ret i32 [[CALL]]
|
||||
;
|
||||
|
||||
@ -21,7 +21,7 @@ entry:
|
||||
}
|
||||
|
||||
define internal i32 @foo(ptr) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@foo() addrspace(1) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@foo.argprom() addrspace(1) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: call addrspace(0) void asm sideeffect "ldr r0, [r0] \0Abx lr \0A", ""()
|
||||
|
@ -2,7 +2,7 @@
|
||||
; RUN: opt -S -passes=argpromotion < %s | FileCheck %s
|
||||
|
||||
define internal i32 @callee_basic(ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_basic
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_basic.argprom
|
||||
; CHECK-SAME: (i32 [[P_0_VAL:%.*]], i32 [[P_4_VAL:%.*]]) {
|
||||
; CHECK-NEXT: [[Z:%.*]] = add i32 [[P_0_VAL]], [[P_4_VAL]]
|
||||
; CHECK-NEXT: ret i32 [[Z]]
|
||||
@ -20,7 +20,7 @@ define void @caller_basic(ptr %p) {
|
||||
; CHECK-NEXT: [[P_VAL:%.*]] = load i32, ptr [[P]], align 4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[P]], i64 4
|
||||
; CHECK-NEXT: [[P_VAL1:%.*]] = load i32, ptr [[TMP1]], align 4
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @callee_basic(i32 [[P_VAL]], i32 [[P_VAL1]])
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @callee_basic.argprom(i32 [[P_VAL]], i32 [[P_VAL1]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call i32 @callee_basic(ptr %p)
|
||||
|
@ -5,7 +5,7 @@
|
||||
target triple = "x86_64-pc-windows-msvc"
|
||||
|
||||
define internal void @callee(ptr) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee.argprom() {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @thunk()
|
||||
; CHECK-NEXT: ret void
|
||||
@ -24,7 +24,7 @@ define void @test1() personality ptr @__CxxFrameHandler3 {
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: cpad:
|
||||
; CHECK-NEXT: [[PAD:%.*]] = cleanuppad within none []
|
||||
; CHECK-NEXT: call void @callee() [ "funclet"(token [[PAD]]) ]
|
||||
; CHECK-NEXT: call void @callee.argprom() [ "funclet"(token [[PAD]]) ]
|
||||
; CHECK-NEXT: cleanupret from [[PAD]] unwind to caller
|
||||
;
|
||||
entry:
|
||||
|
@ -12,7 +12,7 @@ define i32 @fn2() local_unnamed_addr {
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP3]], i64 -4
|
||||
; CHECK-NEXT: [[DOTVAL:%.*]] = load i32, ptr [[TMP4]], align 4
|
||||
; CHECK-NEXT: call fastcc void @fn1(i32 [[DOTVAL]])
|
||||
; CHECK-NEXT: call fastcc void @fn1.argprom(i32 [[DOTVAL]])
|
||||
; CHECK-NEXT: ret i32 undef
|
||||
;
|
||||
%1 = load i32, ptr @b, align 4
|
||||
@ -23,7 +23,7 @@ define i32 @fn2() local_unnamed_addr {
|
||||
}
|
||||
|
||||
define internal fastcc void @fn1(ptr nocapture readonly) unnamed_addr {
|
||||
; CHECK-LABEL: define {{[^@]+}}@fn1
|
||||
; CHECK-LABEL: define {{[^@]+}}@fn1.argprom
|
||||
; CHECK-SAME: (i32 [[DOT_4_VAL:%.*]]) unnamed_addr {
|
||||
; CHECK-NEXT: store i32 [[DOT_4_VAL]], ptr @a, align 4
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -14,7 +14,7 @@ define void @foo() {
|
||||
}
|
||||
|
||||
define internal void @bar(ptr %p) {
|
||||
; CHECK-LABEL: define {{.*}}void @bar()
|
||||
; CHECK-LABEL: define {{.*}}void @bar.argprom()
|
||||
; CHECK-NEXT: #dbg_value(ptr undef, !3, !DIExpression(), !5
|
||||
call void @llvm.dbg.value(metadata ptr %p, metadata !3, metadata !DIExpression()), !dbg !5
|
||||
ret void
|
||||
|
@ -6,7 +6,7 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
|
||||
|
||||
define void @caller() #0 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@caller() {
|
||||
; CHECK-NEXT: call void @promote_i32_ptr(i32 42), !prof [[PROF0:![0-9]+]]
|
||||
; CHECK-NEXT: call void @promote_i32_ptr.argprom(i32 42), !prof [[PROF0:![0-9]+]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%x = alloca i32
|
||||
@ -16,7 +16,7 @@ define void @caller() #0 {
|
||||
}
|
||||
|
||||
define internal void @promote_i32_ptr(ptr %xp) !prof !1 {
|
||||
; CHECK-LABEL: define {{[^@]+}}@promote_i32_ptr
|
||||
; CHECK-LABEL: define {{[^@]+}}@promote_i32_ptr.argprom
|
||||
; CHECK-SAME: (i32 [[XP_0_VAL:%.*]]) !prof [[PROF1:![0-9]+]] {
|
||||
; CHECK-NEXT: call void @use_i32(i32 [[XP_0_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
|
@ -4,7 +4,7 @@
|
||||
%ptr.struct = type { ptr, ptr, ptr }
|
||||
|
||||
define internal void @child(ptr %this, ptr %y, ptr %x) {
|
||||
; CHECK-LABEL: define internal void @child
|
||||
; CHECK-LABEL: define internal void @child.argprom
|
||||
; CHECK-SAME: (ptr [[Y:%.*]], half [[X_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: store half [[X_0_VAL]], ptr [[Y]], align 2
|
||||
@ -17,15 +17,15 @@ entry:
|
||||
}
|
||||
|
||||
define internal void @parent(ptr %this, ptr %p1, ptr %p2) {
|
||||
; CHECK-LABEL: define internal void @parent
|
||||
; CHECK-LABEL: define internal void @parent.argprom
|
||||
; CHECK-SAME: (ptr [[P1:%.*]], ptr [[P2:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[P2_VAL2:%.*]] = load half, ptr [[P2]], align 2
|
||||
; CHECK-NEXT: call void @child(ptr [[P1]], half [[P2_VAL2]])
|
||||
; CHECK-NEXT: call void @child.argprom(ptr [[P1]], half [[P2_VAL2]])
|
||||
; CHECK-NEXT: [[P2_VAL1:%.*]] = load half, ptr [[P2]], align 2
|
||||
; CHECK-NEXT: call void @child(ptr [[P1]], half [[P2_VAL1]])
|
||||
; CHECK-NEXT: call void @child.argprom(ptr [[P1]], half [[P2_VAL1]])
|
||||
; CHECK-NEXT: [[P2_VAL:%.*]] = load half, ptr [[P2]], align 2
|
||||
; CHECK-NEXT: call void @child(ptr [[P1]], half [[P2_VAL]])
|
||||
; CHECK-NEXT: call void @child.argprom(ptr [[P1]], half [[P2_VAL]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -46,7 +46,7 @@ define void @grandparent() {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[XPTR:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: [[YPTR:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: call void @parent(ptr [[XPTR]], ptr [[YPTR]])
|
||||
; CHECK-NEXT: call void @parent.argprom(ptr [[XPTR]], ptr [[YPTR]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -58,7 +58,7 @@ entry:
|
||||
}
|
||||
|
||||
define internal ptr @callee(ptr %dead) {
|
||||
; CHECK-LABEL: define internal ptr @callee() {
|
||||
; CHECK-LABEL: define internal ptr @callee.argprom() {
|
||||
; CHECK-NEXT: ret ptr null
|
||||
;
|
||||
ret ptr null
|
||||
@ -66,8 +66,8 @@ define internal ptr @callee(ptr %dead) {
|
||||
|
||||
define void @caller() {
|
||||
; CHECK-LABEL: define void @caller() {
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @callee()
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = call ptr @callee()
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call ptr @callee.argprom()
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = call ptr @callee.argprom()
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%ret = call ptr @callee(ptr null)
|
||||
|
@ -5,11 +5,11 @@
|
||||
@G = constant %T { i32 0, i32 0, i32 17, i32 25 }
|
||||
|
||||
define internal i32 @test(ptr %p) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test
|
||||
; CHECK-LABEL: define {{[^@]+}}@test.argprom
|
||||
; CHECK-SAME: (i32 [[P_8_VAL:%.*]], i32 [[P_12_VAL:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[V:%.*]] = add i32 [[P_12_VAL]], [[P_8_VAL]]
|
||||
; CHECK-NEXT: [[RET:%.*]] = call i32 @test(i32 [[P_8_VAL]], i32 [[P_12_VAL]])
|
||||
; CHECK-NEXT: [[RET:%.*]] = call i32 @test.argprom(i32 [[P_8_VAL]], i32 [[P_12_VAL]])
|
||||
; CHECK-NEXT: [[ARET:%.*]] = add i32 [[V]], [[RET]]
|
||||
; CHECK-NEXT: ret i32 [[ARET]]
|
||||
;
|
||||
@ -31,7 +31,7 @@ define i32 @caller() {
|
||||
; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr [[TMP0]], align 4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr @G, i64 12
|
||||
; CHECK-NEXT: [[G_VAL1:%.*]] = load i32, ptr [[TMP1]], align 4
|
||||
; CHECK-NEXT: [[V:%.*]] = call i32 @test(i32 [[G_VAL]], i32 [[G_VAL1]])
|
||||
; CHECK-NEXT: [[V:%.*]] = call i32 @test.argprom(i32 [[G_VAL]], i32 [[G_VAL1]])
|
||||
; CHECK-NEXT: ret i32 [[V]]
|
||||
;
|
||||
entry:
|
||||
|
@ -1,7 +1,7 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
||||
; RUN: opt -S -passes=argpromotion < %s | FileCheck %s
|
||||
define internal i32 @foo(ptr %x, i32 %n, i32 %m) {
|
||||
; CHECK-LABEL: define internal i32 @foo(
|
||||
; CHECK-LABEL: define internal i32 @foo.argprom(
|
||||
; CHECK-SAME: i32 [[X_0_VAL:%.*]], i32 [[N:%.*]], i32 [[M:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[N]], 0
|
||||
@ -10,9 +10,9 @@ define internal i32 @foo(ptr %x, i32 %n, i32 %m) {
|
||||
; CHECK-NEXT: br label %[[RETURN:.*]]
|
||||
; CHECK: [[COND_FALSE]]:
|
||||
; CHECK-NEXT: [[SUBVAL:%.*]] = sub i32 [[N]], 1
|
||||
; CHECK-NEXT: [[CALLRET:%.*]] = call i32 @foo(i32 [[X_0_VAL]], i32 [[SUBVAL]], i32 [[X_0_VAL]])
|
||||
; CHECK-NEXT: [[CALLRET:%.*]] = call i32 @foo.argprom(i32 [[X_0_VAL]], i32 [[SUBVAL]], i32 [[X_0_VAL]])
|
||||
; CHECK-NEXT: [[SUBVAL2:%.*]] = sub i32 [[N]], 2
|
||||
; CHECK-NEXT: [[CALLRET2:%.*]] = call i32 @foo(i32 [[X_0_VAL]], i32 [[SUBVAL2]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CALLRET2:%.*]] = call i32 @foo.argprom(i32 [[X_0_VAL]], i32 [[SUBVAL2]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = add i32 [[CALLRET]], [[CALLRET2]]
|
||||
; CHECK-NEXT: br label %[[RETURN]]
|
||||
; CHECK: [[COND_NEXT:.*]]:
|
||||
@ -51,7 +51,7 @@ define i32 @bar(ptr align(4) dereferenceable(4) %x, i32 %n, i32 %m) {
|
||||
; CHECK-SAME: ptr align 4 dereferenceable(4) [[X:%.*]], i32 [[N:%.*]], i32 [[M:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4
|
||||
; CHECK-NEXT: [[CALLRET3:%.*]] = call i32 @foo(i32 [[X_VAL]], i32 [[N]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CALLRET3:%.*]] = call i32 @foo.argprom(i32 [[X_VAL]], i32 [[N]], i32 [[M]])
|
||||
; CHECK-NEXT: br label %[[RETURN:.*]]
|
||||
; CHECK: [[RETURN]]:
|
||||
; CHECK-NEXT: ret i32 [[CALLRET3]]
|
||||
|
@ -1,7 +1,7 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
||||
; RUN: opt -S -passes=argpromotion < %s | FileCheck %s
|
||||
define internal i32 @zoo(ptr %x, i32 %m) {
|
||||
; CHECK-LABEL: define internal i32 @zoo(
|
||||
; CHECK-LABEL: define internal i32 @zoo.argprom(
|
||||
; CHECK-SAME: i32 [[X_0_VAL:%.*]], i32 [[M:%.*]]) {
|
||||
; CHECK-NEXT: [[RESZOO:%.*]] = add i32 [[X_0_VAL]], [[M]]
|
||||
; CHECK-NEXT: ret i32 [[X_0_VAL]]
|
||||
@ -12,7 +12,7 @@ define internal i32 @zoo(ptr %x, i32 %m) {
|
||||
}
|
||||
|
||||
define internal i32 @foo(ptr %x, ptr %y, i32 %n, i32 %m) {
|
||||
; CHECK-LABEL: define internal i32 @foo(
|
||||
; CHECK-LABEL: define internal i32 @foo.argprom(
|
||||
; CHECK-SAME: ptr [[X:%.*]], i32 [[Y_0_VAL:%.*]], i32 [[N:%.*]], i32 [[M:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[N]], 0
|
||||
@ -23,12 +23,12 @@ define internal i32 @foo(ptr %x, ptr %y, i32 %n, i32 %m) {
|
||||
; CHECK: [[COND_FALSE]]:
|
||||
; CHECK-NEXT: [[VAL2:%.*]] = load i32, ptr [[X]], align 4
|
||||
; CHECK-NEXT: [[SUBVAL:%.*]] = sub i32 [[N]], [[Y_0_VAL]]
|
||||
; CHECK-NEXT: [[CALLRET:%.*]] = call i32 @foo(ptr [[X]], i32 [[Y_0_VAL]], i32 [[SUBVAL]], i32 [[VAL2]])
|
||||
; CHECK-NEXT: [[CALLRET:%.*]] = call i32 @foo.argprom(ptr [[X]], i32 [[Y_0_VAL]], i32 [[SUBVAL]], i32 [[VAL2]])
|
||||
; CHECK-NEXT: [[SUBVAL2:%.*]] = sub i32 [[N]], 2
|
||||
; CHECK-NEXT: [[CALLRET2:%.*]] = call i32 @foo(ptr [[X]], i32 [[Y_0_VAL]], i32 [[SUBVAL2]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CALLRET2:%.*]] = call i32 @foo.argprom(ptr [[X]], i32 [[Y_0_VAL]], i32 [[SUBVAL2]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CMP1:%.*]] = add i32 [[CALLRET]], [[CALLRET2]]
|
||||
; CHECK-NEXT: [[X_VAL:%.*]] = load i32, ptr [[X]], align 4
|
||||
; CHECK-NEXT: [[CALLRETFINAL:%.*]] = call i32 @zoo(i32 [[X_VAL]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CALLRETFINAL:%.*]] = call i32 @zoo.argprom(i32 [[X_VAL]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = add i32 [[CMP1]], [[CALLRETFINAL]]
|
||||
; CHECK-NEXT: br label %[[RETURN]]
|
||||
; CHECK: [[COND_NEXT:.*]]:
|
||||
@ -70,7 +70,7 @@ define i32 @bar(ptr align(4) dereferenceable(4) %x, ptr align(4) dereferenceable
|
||||
; CHECK-SAME: ptr align 4 dereferenceable(4) [[X:%.*]], ptr align 4 dereferenceable(4) [[Y:%.*]], i32 [[N:%.*]], i32 [[M:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[Y_VAL:%.*]] = load i32, ptr [[Y]], align 4
|
||||
; CHECK-NEXT: [[CALLRET3:%.*]] = call i32 @foo(ptr [[X]], i32 [[Y_VAL]], i32 [[N]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CALLRET3:%.*]] = call i32 @foo.argprom(ptr [[X]], i32 [[Y_VAL]], i32 [[N]], i32 [[M]])
|
||||
; CHECK-NEXT: br label %[[RETURN:.*]]
|
||||
; CHECK: [[RETURN]]:
|
||||
; CHECK-NEXT: ret i32 [[CALLRET3]]
|
||||
|
@ -1,7 +1,7 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
||||
; RUN: opt -S -passes=argpromotion < %s | FileCheck %s
|
||||
define internal i32 @foo(ptr %x, i32 %n, i32 %m) {
|
||||
; CHECK-LABEL: define internal i32 @foo(
|
||||
; CHECK-LABEL: define internal i32 @foo.argprom(
|
||||
; CHECK-SAME: i32 [[X_0_VAL:%.*]], i32 [[N:%.*]], i32 [[M:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[N]], 0
|
||||
@ -10,9 +10,9 @@ define internal i32 @foo(ptr %x, i32 %n, i32 %m) {
|
||||
; CHECK-NEXT: br label %[[RETURN:.*]]
|
||||
; CHECK: [[COND_FALSE]]:
|
||||
; CHECK-NEXT: [[SUBVAL:%.*]] = sub i32 [[N]], 1
|
||||
; CHECK-NEXT: [[CALLRET:%.*]] = call i32 @foo(i32 [[X_0_VAL]], i32 [[SUBVAL]], i32 [[X_0_VAL]])
|
||||
; CHECK-NEXT: [[CALLRET:%.*]] = call i32 @foo.argprom(i32 [[X_0_VAL]], i32 [[SUBVAL]], i32 [[X_0_VAL]])
|
||||
; CHECK-NEXT: [[SUBVAL2:%.*]] = sub i32 [[N]], 2
|
||||
; CHECK-NEXT: [[CALLRET2:%.*]] = call i32 @foo(i32 [[X_0_VAL]], i32 [[SUBVAL2]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CALLRET2:%.*]] = call i32 @foo.argprom(i32 [[X_0_VAL]], i32 [[SUBVAL2]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CMP2:%.*]] = add i32 [[CALLRET]], [[CALLRET2]]
|
||||
; CHECK-NEXT: br label %[[RETURN]]
|
||||
; CHECK: [[COND_NEXT:.*]]:
|
||||
@ -52,7 +52,7 @@ define i32 @bar(ptr align(4) dereferenceable(4) %x, i32 %n, i32 %m) {
|
||||
; CHECK-NEXT: [[ENTRY:.*:]]
|
||||
; CHECK-NEXT: [[GEPVAL:%.*]] = getelementptr ptr, ptr [[X]], i32 0
|
||||
; CHECK-NEXT: [[GEPVAL_VAL:%.*]] = load i32, ptr [[GEPVAL]], align 4
|
||||
; CHECK-NEXT: [[CALLRET3:%.*]] = call i32 @foo(i32 [[GEPVAL_VAL]], i32 [[N]], i32 [[M]])
|
||||
; CHECK-NEXT: [[CALLRET3:%.*]] = call i32 @foo.argprom(i32 [[GEPVAL_VAL]], i32 [[N]], i32 [[M]])
|
||||
; CHECK-NEXT: br label %[[RETURN:.*]]
|
||||
; CHECK: [[RETURN]]:
|
||||
; CHECK-NEXT: ret i32 [[CALLRET3]]
|
||||
|
@ -14,7 +14,7 @@
|
||||
@d = global i8 0, align 1
|
||||
|
||||
define internal fastcc void @fn(ptr nocapture readonly %p1, ptr nocapture readonly %p2) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@fn
|
||||
; CHECK-LABEL: define {{[^@]+}}@fn.argprom
|
||||
; CHECK-SAME: (i32 [[P1_0_VAL:%.*]], i64 [[P2_0_VAL:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[P2_0_VAL]] to i32
|
||||
@ -40,7 +40,7 @@ define i32 @main() {
|
||||
; CHECK-NEXT: store i32 1, ptr [[TMP1]], align 4, !tbaa [[TBAA5:![0-9]+]]
|
||||
; CHECK-NEXT: [[G_VAL:%.*]] = load i32, ptr @g, align 4, !tbaa [[TBAA5]]
|
||||
; CHECK-NEXT: [[C_VAL:%.*]] = load i64, ptr @c, align 8, !tbaa [[TBAA7:![0-9]+]]
|
||||
; CHECK-NEXT: call fastcc void @fn(i32 [[G_VAL]], i64 [[C_VAL]])
|
||||
; CHECK-NEXT: call fastcc void @fn.argprom(i32 [[G_VAL]], i64 [[C_VAL]])
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
@ -5,7 +5,7 @@ target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-windows-msvc"
|
||||
|
||||
define internal void @add(ptr %this, ptr sret(i32) %r) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@add
|
||||
; CHECK-LABEL: define {{[^@]+}}@add.argprom
|
||||
; CHECK-SAME: (i32 [[THIS_0_VAL:%.*]], i32 [[THIS_4_VAL:%.*]], ptr noalias [[R:%.*]]) {
|
||||
; CHECK-NEXT: [[AB:%.*]] = add i32 [[THIS_0_VAL]], [[THIS_4_VAL]]
|
||||
; CHECK-NEXT: store i32 [[AB]], ptr [[R]], align 4
|
||||
@ -27,7 +27,7 @@ define void @f() {
|
||||
; CHECK-NEXT: [[PAIR_VAL:%.*]] = load i32, ptr [[PAIR]], align 4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PAIR]], i64 4
|
||||
; CHECK-NEXT: [[PAIR_VAL1:%.*]] = load i32, ptr [[TMP1]], align 4
|
||||
; CHECK-NEXT: call void @add(i32 [[PAIR_VAL]], i32 [[PAIR_VAL1]], ptr noalias [[R]])
|
||||
; CHECK-NEXT: call void @add.argprom(i32 [[PAIR_VAL]], i32 [[PAIR_VAL1]], ptr noalias [[R]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%r = alloca i32
|
||||
|
@ -59,7 +59,7 @@ entry:
|
||||
}
|
||||
|
||||
define internal void @l(ptr byval(ptr) align 4 %p) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@l
|
||||
; CHECK-LABEL: define {{[^@]+}}@l.argprom.argprom
|
||||
; CHECK-SAME: () #[[ATTR0]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret void
|
||||
@ -83,7 +83,7 @@ define i32 @main() nounwind {
|
||||
; CHECK-NEXT: call void @g(ptr byval(ptr) align 4 [[S]]) #[[ATTR0]]
|
||||
; CHECK-NEXT: call void @h(ptr byval(ptr) align 4 [[S]]) #[[ATTR0]]
|
||||
; CHECK-NEXT: call void @k(ptr byval(ptr) align 4 [[S]]) #[[ATTR0]]
|
||||
; CHECK-NEXT: call void @l() #[[ATTR0]]
|
||||
; CHECK-NEXT: call void @l.argprom.argprom() #[[ATTR0]]
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
@ -4,7 +4,7 @@
|
||||
; while the used arguments should be promoted if they are pointers.
|
||||
; The pass should not touch any unused non-pointer arguments.
|
||||
define internal i32 @callee(i1 %c, i1 %d, ptr %used, ptr %unused) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee.argprom
|
||||
; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]], i32 [[USED_VAL:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 [[C]], label %if, label %else
|
||||
@ -28,7 +28,7 @@ else:
|
||||
; while the used arguments should be promoted if they are pointers.
|
||||
; The pass should not touch any unused non-pointer arguments.
|
||||
define internal i32 @callee_byval(i1 %c, i1 %d, ptr byval(i32) align 4 %used, ptr byval(i32) align 4 %unused) nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_byval
|
||||
; CHECK-LABEL: define {{[^@]+}}@callee_byval.argprom
|
||||
; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]], i32 [[USED_VAL:%.*]]) #[[ATTR0]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 [[C]], label %if, label %else
|
||||
@ -53,9 +53,9 @@ define i32 @caller(i1 %c, i1 %d, ptr %arg) nounwind {
|
||||
; CHECK-SAME: (i1 [[C:%.*]], i1 [[D:%.*]], ptr [[ARG:%.*]]) #[[ATTR0]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[ARG_VAL_0:%.*]] = load i32, ptr [[ARG]], align 4
|
||||
; CHECK-NEXT: [[RES_0:%.*]] = call i32 @callee_byval(i1 [[C]], i1 [[D]], i32 [[ARG_VAL_0]]) #[[ATTR0]]
|
||||
; CHECK-NEXT: [[RES_0:%.*]] = call i32 @callee_byval.argprom(i1 [[C]], i1 [[D]], i32 [[ARG_VAL_0]]) #[[ATTR0]]
|
||||
; CHECK-NEXT: [[ARG_VAL_1:%.*]] = load i32, ptr [[ARG]], align 4
|
||||
; CHECK-NEXT: [[RES_1:%.*]] = call i32 @callee(i1 [[C]], i1 [[D]], i32 [[ARG_VAL_1]]) #[[ATTR0]]
|
||||
; CHECK-NEXT: [[RES_1:%.*]] = call i32 @callee.argprom(i1 [[C]], i1 [[D]], i32 [[ARG_VAL_1]]) #[[ATTR0]]
|
||||
; CHECK-NEXT: ret i32 1
|
||||
;
|
||||
entry:
|
||||
|
@ -19,7 +19,7 @@ define i32 @clause_LiteralComputeWeight(ptr %call23) {
|
||||
; CGSCC-NEXT: [[TERM_0:%.*]] = phi ptr [ null, [[ENTRY:%.*]] ], [ [[CALL24:%.*]], [[DO_BODY]] ]
|
||||
; CGSCC-NEXT: [[CALL2:%.*]] = load volatile i32, ptr [[TERM_0]], align 4
|
||||
; CGSCC-NEXT: [[CALL23_VAL:%.*]] = load ptr, ptr [[CALL23]], align 8
|
||||
; CGSCC-NEXT: [[CALL24]] = call ptr @list_Car(ptr nofree readonly [[CALL23_VAL]]) #[[ATTR3:[0-9]+]]
|
||||
; CGSCC-NEXT: [[CALL24]] = call ptr @list_Car.argprom(ptr nofree readonly [[CALL23_VAL]]) #[[ATTR3:[0-9]+]]
|
||||
; CGSCC-NEXT: br label [[DO_BODY]]
|
||||
;
|
||||
entry:
|
||||
@ -46,7 +46,7 @@ entry:
|
||||
|
||||
define internal ptr @list_Car(ptr %L) #0 {
|
||||
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
|
||||
; CGSCC-LABEL: define {{[^@]+}}@list_Car
|
||||
; CGSCC-LABEL: define {{[^@]+}}@list_Car.argprom
|
||||
; CGSCC-SAME: (ptr nofree [[L_0_VAL:%.*]]) #[[ATTR2:[0-9]+]] {
|
||||
; CGSCC-NEXT: entry:
|
||||
; CGSCC-NEXT: ret ptr [[L_0_VAL]]
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt < %s -passes=deadargelim -S | grep "@test("
|
||||
; RUN: opt < %s -passes=deadargelim -S | grep "@test.argelim("
|
||||
; RUN: opt < %s -passes=deadargelim -S | not grep dead
|
||||
|
||||
define internal i32 @test(i32 %X, i32 %dead) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
@g = global i8 0
|
||||
|
||||
; CHECK: define internal void @foo(i8 signext %y) [[NUW:#[0-9]+]]
|
||||
; CHECK: define internal void @foo.argelim(i8 signext %y) [[NUW:#[0-9]+]]
|
||||
;
|
||||
; REMARK-LABEL: Function: foo
|
||||
; REMARK: Args:
|
||||
@ -21,7 +21,7 @@ define internal zeroext i8 @foo(ptr inreg %p, i8 signext %y, ... ) nounwind {
|
||||
}
|
||||
|
||||
define i32 @bar() {
|
||||
; CHECK: call void @foo(i8 signext 1) [[NUW]]
|
||||
; CHECK: call void @foo.argelim(i8 signext 1) [[NUW]]
|
||||
%A = call zeroext i8(ptr, i8, ...) @foo(ptr inreg null, i8 signext 1, ptr byval(%struct) null ) nounwind
|
||||
ret i32 0
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ define ptr @vfs_addname(ptr %name, i32 %len, i32 %hash, i32 %flags) nounwind ssp
|
||||
; CHECK-NEXT: #dbg_value(i32 [[LEN]], [[META13:![0-9]+]], !DIExpression(), [[META12]])
|
||||
; CHECK-NEXT: #dbg_value(i32 [[HASH]], [[META14:![0-9]+]], !DIExpression(), [[META12]])
|
||||
; CHECK-NEXT: #dbg_value(i32 [[FLAGS]], [[META15:![0-9]+]], !DIExpression(), [[META12]])
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = call fastcc ptr @add_name_internal(ptr [[NAME]], i32 [[HASH]]) #[[ATTR2:[0-9]+]], !dbg [[DBG16:![0-9]+]]
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = call fastcc ptr @add_name_internal.argelim(ptr [[NAME]], i32 [[HASH]]) #[[ATTR2:[0-9]+]], !dbg [[DBG16:![0-9]+]]
|
||||
; CHECK-NEXT: ret ptr [[TMP0]], !dbg [[DBG16]]
|
||||
;
|
||||
entry:
|
||||
@ -31,7 +31,7 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
|
||||
|
||||
define internal fastcc ptr @add_name_internal(ptr %name, i32 %len, i32 %hash, i8 zeroext %extra, i32 %flags) noinline nounwind ssp !dbg !16 {
|
||||
;
|
||||
; CHECK-LABEL: define {{[^@]+}}@add_name_internal
|
||||
; CHECK-LABEL: define {{[^@]+}}@add_name_internal.argelim
|
||||
; CHECK-SAME: (ptr [[NAME:%.*]], i32 [[HASH:%.*]]) #[[ATTR1:[0-9]+]] !dbg [[DBG18:![0-9]+]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: #dbg_value(ptr [[NAME]], [[META22:![0-9]+]], !DIExpression(), [[META23:![0-9]+]])
|
||||
|
@ -4,7 +4,7 @@
|
||||
; actually only used in ways we can eliminate. We gain benefit from analysing
|
||||
; the "use" and applying its results to all sub-values.
|
||||
|
||||
; CHECK-LABEL: define internal void @agguse_dead()
|
||||
; CHECK-LABEL: define internal void @agguse_dead.retelim()
|
||||
|
||||
define internal { i32, i32 } @agguse_dead() {
|
||||
ret { i32, i32 } { i32 0, i32 1 }
|
||||
@ -20,7 +20,7 @@ define internal { i32, i32 } @test_agguse_dead() {
|
||||
; Case 1: an opaque use of the aggregate exists (in this case dead). Otherwise
|
||||
; only one value is used, so function can be simplified.
|
||||
|
||||
; CHECK-LABEL: define internal i32 @rets_independent_if_agguse_dead()
|
||||
; CHECK-LABEL: define internal i32 @rets_independent_if_agguse_dead.retelim()
|
||||
; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } { i32 0, i32 1 }, 1
|
||||
; CHECK: ret i32 [[RET]]
|
||||
|
||||
@ -89,7 +89,7 @@ define [2 x i32] @test_array_rets_have_multiple_slots() {
|
||||
; Case 4: we can remove some retvals from the array. It's nice to produce an
|
||||
; array again having done so (rather than converting it to a struct).
|
||||
|
||||
; CHECK-LABEL: define internal [2 x i32] @can_shrink_arrays()
|
||||
; CHECK-LABEL: define internal [2 x i32] @can_shrink_arrays.retelim()
|
||||
; CHECK: [[VAL0:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 0
|
||||
; CHECK: [[RESTMP:%.*]] = insertvalue [2 x i32] poison, i32 [[VAL0]], 0
|
||||
; CHECK: [[VAL2:%.*]] = extractvalue [3 x i32] [i32 42, i32 43, i32 44], 2
|
||||
@ -117,7 +117,7 @@ define void @test_can_shrink_arrays() {
|
||||
; Case 5: %in gets passed directly to the return. It should mark be marked as
|
||||
; used if *any* of the return values are, not just if value 0 is.
|
||||
|
||||
; CHECK-LABEL: define internal i32 @ret_applies_to_all({ i32, i32 } %in)
|
||||
; CHECK-LABEL: define internal i32 @ret_applies_to_all.retelim({ i32, i32 } %in)
|
||||
; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } %in, 1
|
||||
; CHECK: ret i32 [[RET]]
|
||||
|
||||
@ -167,7 +167,7 @@ entry:
|
||||
}
|
||||
|
||||
; CHECK-LABEL: define void @PR24906
|
||||
; CHECK: %[[invoke:.*]] = invoke i32 @agg_ret()
|
||||
; CHECK: %[[invoke:.*]] = invoke i32 @agg_ret.retelim()
|
||||
; CHECK: %[[oldret:.*]] = insertvalue { i32 } poison, i32 %[[invoke]], 0
|
||||
; CHECK: phi { i32 } [ %[[oldret]],
|
||||
define void @PR24906() personality ptr poison {
|
||||
|
@ -3,8 +3,8 @@
|
||||
; Checks if !prof metadata is corret in deadargelim.
|
||||
|
||||
define void @caller() #0 {
|
||||
; CHECK: call void @test_vararg(), !prof ![[PROF:[0-9]]]
|
||||
; CHECK: call void @test(), !prof ![[PROF]]
|
||||
; CHECK: call void @test_vararg.argelim(), !prof ![[PROF:[0-9]]]
|
||||
; CHECK: call void @test.argelim(), !prof ![[PROF]]
|
||||
call void (i32, ...) @test_vararg(i32 1), !prof !0
|
||||
call void @test(i32 1), !prof !0
|
||||
ret void
|
||||
|
@ -11,4 +11,4 @@ define internal void @g(i32 %dead) comdat($f) {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define internal void @g() comdat($f) {
|
||||
; CHECK: define internal void @g.argelim() comdat($f) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
; Reproducer for PR23260.
|
||||
|
||||
; CHECK-LABEL: define internal void @bar()
|
||||
; CHECK-LABEL: define internal void @bar.argelim()
|
||||
; CHECK: #dbg_value(i32 poison, ![[LOCAL1:[0-9]+]]
|
||||
; CHECK: call void @sink()
|
||||
|
||||
@ -18,9 +18,9 @@ entry:
|
||||
}
|
||||
|
||||
; CHECK-LABEL: define void @foo()
|
||||
; CHECK: call void @bar()
|
||||
; CHECK: call void @bar.argelim()
|
||||
; CHECK: #dbg_value(i32 poison, ![[LOCAL2:[0-9]+]]
|
||||
; CHECK: call void @bar()
|
||||
; CHECK: call void @bar.argelim()
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define void @foo() #0 !dbg !6 {
|
||||
|
@ -14,7 +14,7 @@
|
||||
; the function->debug info mapping on update to ensure it's accurate when used
|
||||
; again for the next removal.
|
||||
|
||||
; CHECK: define internal void @_ZL2f1iz({{.*}} !dbg [[SP:![0-9]+]]
|
||||
; CHECK: define internal void @_ZL2f1iz.argelim({{.*}} !dbg [[SP:![0-9]+]]
|
||||
; CHECK: [[SP]] = distinct !DISubprogram(name: "f1"
|
||||
|
||||
; Check that debug info metadata for subprograms stores pointers to
|
||||
|
@ -23,7 +23,7 @@ define i32 @test3() {
|
||||
; The callee function's return type shouldn't be changed if the call result is
|
||||
; used.
|
||||
|
||||
; CHECK-LABEL: define internal ptr @callee4()
|
||||
; CHECK-LABEL: define internal ptr @callee4.argelim()
|
||||
|
||||
define internal ptr @callee4(ptr %a0) {
|
||||
ret ptr @g0;
|
||||
@ -32,7 +32,7 @@ define internal ptr @callee4(ptr %a0) {
|
||||
declare void @llvm.objc.clang.arc.noop.use(...)
|
||||
|
||||
; CHECK-LABEL: define ptr @test4(
|
||||
; CHECK: tail call ptr @callee4() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
; CHECK: tail call ptr @callee4.argelim() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
|
||||
define ptr @test4() {
|
||||
%call = tail call ptr @callee4(ptr @g0) [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ]
|
||||
|
@ -22,7 +22,7 @@ define i32 @call_indirect(ptr readnone %fct_ptr, i32 %arg1, i32 %arg2, i32 %arg3
|
||||
; CHECK-NEXT: [[RES2:%.*]] = tail call i32 @internal_fct(i32 poison, i32 [[ARG2]], i32 poison)
|
||||
; CHECK-NEXT: br label [[END]]
|
||||
; CHECK: call_other:
|
||||
; CHECK-NEXT: [[RES3:%.*]] = tail call i32 @other_fct(i32 [[ARG2]])
|
||||
; CHECK-NEXT: [[RES3:%.*]] = tail call i32 @other_fct.argelim(i32 [[ARG2]])
|
||||
; CHECK-NEXT: br label [[END]]
|
||||
; CHECK: end:
|
||||
; CHECK-NEXT: [[FINAL_RES:%.*]] = phi i32 [ [[RES1]], [[CALL_EXT]] ], [ [[RES2]], [[CALL_INT]] ], [ [[RES3]], [[CALL_OTHER]] ]
|
||||
|
@ -8,7 +8,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
@s = common dso_local local_unnamed_addr global i32 0, align 4
|
||||
|
||||
define internal i32 @va_func(i32 %num, ...) !prof !28 !PGOFuncName !29{
|
||||
; CHECK: define internal void @va_func(i32 %num) !prof ![[ENTRYCOUNT:[0-9]+]] !PGOFuncName ![[PGOFUNCNAME1:[0-9]+]] {
|
||||
; CHECK: define internal void @va_func.retelim(i32 %num) !prof ![[ENTRYCOUNT:[0-9]+]] !PGOFuncName ![[PGOFUNCNAME1:[0-9]+]] {
|
||||
entry:
|
||||
%0 = load i32, ptr @s, align 4, !tbaa !31
|
||||
%add = add nsw i32 %0, %num
|
||||
@ -17,7 +17,7 @@ entry:
|
||||
}
|
||||
|
||||
define internal fastcc i32 @foo() unnamed_addr !prof !28 !PGOFuncName !30 {
|
||||
; CHECK: define internal fastcc void @foo() unnamed_addr !prof ![[ENTRYCOUNT:[0-9]+]] !PGOFuncName ![[PGOFUNCNAME2:[0-9]+]] {
|
||||
; CHECK: define internal fastcc void @foo.retelim() unnamed_addr !prof ![[ENTRYCOUNT:[0-9]+]] !PGOFuncName ![[PGOFUNCNAME2:[0-9]+]] {
|
||||
entry:
|
||||
%0 = load i32, ptr @s, align 4, !tbaa !31
|
||||
%add = add nsw i32 %0, 8
|
||||
|
@ -22,7 +22,7 @@ bad1: ; preds = %entry-block
|
||||
}
|
||||
; CHECK-LABEL: define void @test1(
|
||||
; CHECK: %[[pad:.*]] = cleanuppad within none []
|
||||
; CHECK-NEXT: call void @callee() [ "funclet"(token %[[pad]]) ]
|
||||
; CHECK-NEXT: call void @callee.argelim() [ "funclet"(token %[[pad]]) ]
|
||||
|
||||
declare void @thunk()
|
||||
|
||||
|
@ -10,7 +10,7 @@ declare ptr @llvm.call.preallocated.arg(token, i32)
|
||||
; the function and then changing too much.
|
||||
|
||||
; This checks if the return value attributes are not removed
|
||||
; CHECK: define internal zeroext i32 @test1() #1
|
||||
; CHECK: define internal zeroext i32 @test1.argelim() #1
|
||||
define internal zeroext i32 @test1(i32 %DEADARG1) nounwind {
|
||||
;
|
||||
;
|
||||
@ -18,7 +18,7 @@ define internal zeroext i32 @test1(i32 %DEADARG1) nounwind {
|
||||
}
|
||||
|
||||
; This checks if the struct doesn't get non-packed
|
||||
; CHECK-LABEL: define internal <{ i32, i32 }> @test2(
|
||||
; CHECK-LABEL: define internal <{ i32, i32 }> @test2.argelim(
|
||||
define internal <{ i32, i32 }> @test2(i32 %DEADARG1) {
|
||||
;
|
||||
;
|
||||
|
@ -5,14 +5,14 @@
|
||||
|
||||
target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
|
||||
|
||||
; CHECK: define internal i32 @foo() addrspace(1)
|
||||
; CHECK: define internal i32 @foo.argelim() addrspace(1)
|
||||
define internal i32 @foo(i32 %x) #0 {
|
||||
tail call void asm sideeffect inteldialect "mov eax, [esp + $$4]\0A\09ret", "~{eax},~{dirflag},~{fpsr},~{flags}"()
|
||||
unreachable
|
||||
}
|
||||
|
||||
define i32 @f(i32 %x, i32 %y) {
|
||||
; CHECK: %r = call addrspace(1) i32 @foo()
|
||||
; CHECK: %r = call addrspace(1) i32 @foo.argelim()
|
||||
%r = call i32 @foo(i32 %x)
|
||||
|
||||
ret i32 %r
|
||||
|
@ -3,14 +3,14 @@
|
||||
%Ty = type { i32, i32 }
|
||||
|
||||
; Validate that the argument and return value are both dead
|
||||
; CHECK-LABEL: define internal void @test1()
|
||||
; CHECK-LABEL: define internal void @test1.argelim()
|
||||
|
||||
define internal ptr @test1(ptr %this) {
|
||||
ret ptr %this
|
||||
}
|
||||
|
||||
; do not keep alive the return value of a function with a dead 'returned' argument
|
||||
; CHECK-LABEL: define internal void @test2()
|
||||
; CHECK-LABEL: define internal void @test2.argelim()
|
||||
|
||||
define internal ptr @test2(ptr returned %this) {
|
||||
ret ptr %this
|
||||
@ -20,7 +20,7 @@ define internal ptr @test2(ptr returned %this) {
|
||||
@dummy = global ptr null
|
||||
|
||||
; Validate that return value is dead
|
||||
; CHECK-LABEL: define internal void @test3(ptr %this)
|
||||
; CHECK-LABEL: define internal void @test3.argelim(ptr %this)
|
||||
|
||||
define internal ptr @test3(ptr %this) {
|
||||
store volatile ptr %this, ptr @dummy
|
||||
@ -36,7 +36,7 @@ define internal ptr @test4(ptr returned %this) {
|
||||
}
|
||||
|
||||
; don't do this if 'returned' is on the call site...
|
||||
; CHECK-LABEL: define internal void @test5(ptr %this)
|
||||
; CHECK-LABEL: define internal void @test5.argelim(ptr %this)
|
||||
|
||||
define internal ptr @test5(ptr %this) {
|
||||
store volatile ptr %this, ptr @dummy
|
||||
@ -55,7 +55,7 @@ define ptr @caller(ptr %this) {
|
||||
%3 = call ptr @test3(ptr %this)
|
||||
%4 = call ptr @test4(ptr %this)
|
||||
; ...instead, drop 'returned' form the call site
|
||||
; CHECK: call void @test5(ptr %this)
|
||||
; CHECK: call void @test5.argelim(ptr %this)
|
||||
%5 = call ptr @test5(ptr returned %this)
|
||||
%6 = call ptr @test6()
|
||||
ret ptr %this
|
||||
|
@ -34,5 +34,5 @@ define void @call_deadret(i32 %in) {
|
||||
store i32 42, ptr %stacked
|
||||
call i32 (i32, i32, ...) @va_deadret_func(i32 poison, i32 %in, [6 x i32] poison, ptr byval(i32) %stacked)
|
||||
ret void
|
||||
; CHECK: call void (i32, i32, ...) @va_deadret_func(i32 poison, i32 poison, [6 x i32] poison, ptr byval(i32) %stacked)
|
||||
; CHECK: call void (i32, i32, ...) @va_deadret_func.retelim(i32 poison, i32 poison, [6 x i32] poison, ptr byval(i32) %stacked)
|
||||
}
|
||||
|
@ -42,15 +42,15 @@ define internal void @decrement(ptr nocapture %0) {
|
||||
}
|
||||
|
||||
define i32 @main(ptr %0, i32 %1) {
|
||||
; CHECK: call void @func.specialized.2(ptr [[TMP0:%.*]], i32 [[TMP1:%.*]])
|
||||
; CHECK: call void @func.specialized.2.argelim(ptr [[TMP0:%.*]], i32 [[TMP1:%.*]])
|
||||
%3 = call i32 @func(ptr %0, i32 %1, ptr nonnull @increment)
|
||||
; CHECK: call void @func.specialized.1(ptr [[TMP0]], i32 0)
|
||||
; CHECK: call void @func.specialized.1.argelim(ptr [[TMP0]], i32 0)
|
||||
%4 = call i32 @func(ptr %0, i32 %3, ptr nonnull @decrement)
|
||||
; CHECK: ret i32 0
|
||||
ret i32 %4
|
||||
}
|
||||
|
||||
; CHECK: @func.specialized.1(
|
||||
; CHECK: @func.specialized.1.argelim(
|
||||
; CHECK: [[TMP3:%.*]] = alloca i32, align 4
|
||||
; CHECK: store i32 [[TMP1:%.*]], ptr [[TMP3]], align 4
|
||||
; CHECK: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
|
||||
@ -63,13 +63,13 @@ define i32 @main(ptr %0, i32 %1) {
|
||||
; CHECK: call void @decrement(ptr [[TMP9]])
|
||||
; CHECK: [[TMP10:%.*]] = load i32, ptr [[TMP3]], align 4
|
||||
; CHECK: [[TMP11:%.*]] = add nsw i32 [[TMP10]], -1
|
||||
; CHECK: call void @func.specialized.1(ptr [[TMP0]], i32 [[TMP11]])
|
||||
; CHECK: call void @func.specialized.1.argelim(ptr [[TMP0]], i32 [[TMP11]])
|
||||
; CHECK: br label [[TMP12:%.*]]
|
||||
; CHECK: 12:
|
||||
; CHECK: ret void
|
||||
;
|
||||
;
|
||||
; CHECK: @func.specialized.2(
|
||||
; CHECK: @func.specialized.2.argelim(
|
||||
; CHECK: [[TMP3:%.*]] = alloca i32, align 4
|
||||
; CHECK: store i32 [[TMP1:%.*]], ptr [[TMP3]], align 4
|
||||
; CHECK: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
|
||||
@ -82,7 +82,7 @@ define i32 @main(ptr %0, i32 %1) {
|
||||
; CHECK: call void @increment(ptr [[TMP9]])
|
||||
; CHECK: [[TMP10:%.*]] = load i32, ptr [[TMP3]], align 4
|
||||
; CHECK: [[TMP11:%.*]] = add nsw i32 [[TMP10]], -1
|
||||
; CHECK: call void @func.specialized.2(ptr [[TMP0]], i32 [[TMP11]])
|
||||
; CHECK: call void @func.specialized.2.argelim(ptr [[TMP0]], i32 [[TMP11]])
|
||||
; CHECK: br label [[TMP12:%.*]]
|
||||
; CHECK: 12:
|
||||
; CHECK: ret void
|
||||
|
@ -49,11 +49,11 @@ entry:
|
||||
; Check if specialisation on the address of a non-const global variable
|
||||
; is not allowed, then it is not performed.
|
||||
|
||||
; NO-GLOBALS-LABEL: define internal range(i32 -2147483646, -2147483648) i32 @g()
|
||||
; NO-GLOBALS-LABEL: define internal range(i32 -2147483646, -2147483648) i32 @g.argelim()
|
||||
; NO-GLOBALS: call i32 @f(ptr @G)
|
||||
|
||||
; NO-GLOBALS-LABEL: define range(i32 -2147483646, -2147483648) i32 @h0(ptr %p)
|
||||
; NO-GLOBALS:call i32 @g()
|
||||
; NO-GLOBALS:call i32 @g.argelim()
|
||||
|
||||
; NO-GLOBALS-LABEL: define i32 @h1()
|
||||
; NO-GLOBALS: call i32 @f(ptr @G)
|
||||
@ -64,15 +64,15 @@ entry:
|
||||
; Check if specialisation on the address of a non-const global variable
|
||||
; is allowed, then it is performed where possible.
|
||||
|
||||
; GLOBALS-LABEL: define internal range(i32 -2147483646, -2147483648) i32 @g()
|
||||
; GLOBALS: call i32 @f.specialized.2()
|
||||
; GLOBALS-LABEL: define internal range(i32 -2147483646, -2147483648) i32 @g.argelim()
|
||||
; GLOBALS: call i32 @f.specialized.2.argelim()
|
||||
|
||||
; GLOBALS-LABEL: define range(i32 -2147483646, -2147483648) i32 @h0(ptr %p)
|
||||
; GLOBALS: call i32 @g()
|
||||
; GLOBALS: call i32 @g.argelim()
|
||||
|
||||
; GLOBALS-LABEL: define i32 @h1()
|
||||
; GLOBALS: call i32 @f.specialized.2()
|
||||
; GLOBALS: call i32 @f.specialized.2.argelim()
|
||||
|
||||
; GLOBALS-LABEL: define i32 @h2()
|
||||
; GLOBALS: call i32 @f.specialized.1()
|
||||
; GLOBALS: call i32 @f.specialized.1.argelim()
|
||||
|
||||
|
@ -29,9 +29,9 @@ define internal i32 @f2(i32 %i) {
|
||||
;; All calls are to specilisation instances.
|
||||
|
||||
; CHECK-LABEL: define i32 @g0
|
||||
; CHECK: call void @f0.specialized.[[#A:]]()
|
||||
; CHECK-NEXT: call void @f1.specialized.[[#B:]]()
|
||||
; CHECK-NEXT: call void @f2.specialized.[[#C:]]()
|
||||
; CHECK: call void @f0.specialized.[[#A:]].argelim()
|
||||
; CHECK-NEXT: call void @f1.specialized.[[#B:]].argelim()
|
||||
; CHECK-NEXT: call void @f2.specialized.[[#C:]].argelim()
|
||||
; CHECK-NEXT: ret i32 9
|
||||
define i32 @g0(i32 %i) {
|
||||
%u0 = call i32 @f0(i32 1)
|
||||
@ -43,9 +43,9 @@ define i32 @g0(i32 %i) {
|
||||
}
|
||||
|
||||
; CHECK-LABEL: define i32 @g1
|
||||
; CHECK: call void @f0.specialized.[[#D:]]()
|
||||
; CHECK-NEXT: call void @f1.specialized.[[#E:]]()
|
||||
; CHECK-NEXT: call void @f2.specialized.[[#F:]]()
|
||||
; CHECK: call void @f0.specialized.[[#D:]].argelim()
|
||||
; CHECK-NEXT: call void @f1.specialized.[[#E:]].argelim()
|
||||
; CHECK-NEXT: call void @f2.specialized.[[#F:]].argelim()
|
||||
; CHECK-NEXT: ret i32 12
|
||||
define i32 @g1(i32 %i) {
|
||||
%u0 = call i32 @f0(i32 2)
|
||||
@ -58,9 +58,9 @@ define i32 @g1(i32 %i) {
|
||||
|
||||
; All of the function are specialized and all clones are with internal linkage.
|
||||
|
||||
; CHECK-DAG: define internal void @f0.specialized.[[#A]]() {
|
||||
; CHECK-DAG: define internal void @f1.specialized.[[#B]]() {
|
||||
; CHECK-DAG: define internal void @f2.specialized.[[#C]]() {
|
||||
; CHECK-DAG: define internal void @f0.specialized.[[#D]]() {
|
||||
; CHECK-DAG: define internal void @f1.specialized.[[#E]]() {
|
||||
; CHECK-DAG: define internal void @f2.specialized.[[#F]]() {
|
||||
; CHECK-DAG: define internal void @f0.specialized.[[#A]].argelim() {
|
||||
; CHECK-DAG: define internal void @f1.specialized.[[#B]].argelim() {
|
||||
; CHECK-DAG: define internal void @f2.specialized.[[#C]].argelim() {
|
||||
; CHECK-DAG: define internal void @f0.specialized.[[#D]].argelim() {
|
||||
; CHECK-DAG: define internal void @f1.specialized.[[#E]].argelim() {
|
||||
; CHECK-DAG: define internal void @f2.specialized.[[#F]].argelim() {
|
||||
|
@ -21,7 +21,7 @@ entry:
|
||||
|
||||
define dso_local i32 @g0(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @g0
|
||||
; CHECK: call i32 @f.specialized.3(i32 [[X:%.*]], i32 [[Y:%.*]])
|
||||
; CHECK: call i32 @f.specialized.3.argelim(i32 [[X:%.*]], i32 [[Y:%.*]])
|
||||
entry:
|
||||
%call = tail call i32 @f(i32 %x, i32 %y, ptr @add, ptr @add)
|
||||
ret i32 %call
|
||||
@ -30,7 +30,7 @@ entry:
|
||||
|
||||
define dso_local i32 @g1(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @g1(
|
||||
; CHECK: call i32 @f.specialized.2(i32 [[X:%.*]], i32 [[Y:%.*]])
|
||||
; CHECK: call i32 @f.specialized.2.argelim(i32 [[X:%.*]], i32 [[Y:%.*]])
|
||||
entry:
|
||||
%call = tail call i32 @f(i32 %x, i32 %y, ptr @sub, ptr @add)
|
||||
ret i32 %call
|
||||
@ -38,21 +38,21 @@ entry:
|
||||
|
||||
define dso_local i32 @g2(i32 %x, i32 %y, ptr %v) {
|
||||
; CHECK-LABEL: @g2
|
||||
; CHECK: call i32 @f.specialized.1(i32 [[X:%.*]], i32 [[Y:%.*]], ptr [[V:%.*]])
|
||||
; CHECK: call i32 @f.specialized.1.argelim(i32 [[X:%.*]], i32 [[Y:%.*]], ptr [[V:%.*]])
|
||||
entry:
|
||||
%call = tail call i32 @f(i32 %x, i32 %y, ptr @sub, ptr %v)
|
||||
ret i32 %call
|
||||
}
|
||||
|
||||
; CHECK-LABEL: define {{.*}} i32 @f.specialized.1
|
||||
; CHECK-LABEL: define {{.*}} i32 @f.specialized.1.argelim
|
||||
; CHECK: call i32 @sub(i32 %x, i32 %y)
|
||||
; CHECK-NEXT: call i32 %v(i32 %x, i32 %y)
|
||||
|
||||
; CHECK-LABEL: define {{.*}} i32 @f.specialized.2
|
||||
; CHECK-LABEL: define {{.*}} i32 @f.specialized.2.argelim
|
||||
; CHECK: call i32 @sub(i32 %x, i32 %y)
|
||||
; CHECK-NEXT: call i32 @add(i32 %x, i32 %y)
|
||||
|
||||
; CHECK-LABEL: define {{.*}} i32 @f.specialized.3
|
||||
; CHECK-LABEL: define {{.*}} i32 @f.specialized.3.argelim
|
||||
; CHECK: call i32 @add(i32 %x, i32 %y)
|
||||
; CHECK-NEXT: call i32 @add(i32 %x, i32 %y)
|
||||
|
||||
|
@ -14,7 +14,8 @@ define void @do_trap(ptr %ptr) {
|
||||
}
|
||||
|
||||
define internal void @capture_and_trap(ptr %ptr) noinline {
|
||||
; CHECK-LABEL: @capture_and_trap(
|
||||
; DEFAULT-LABEL: @capture_and_trap.argelim(
|
||||
; LTO-LABEL: @capture_and_trap.argprom(
|
||||
; CHECK-NEXT: tail call void @llvm.trap()
|
||||
; CHECK-NEXT: unreachable
|
||||
;
|
||||
@ -34,7 +35,8 @@ define internal void @dead_fn2() {
|
||||
|
||||
define void @test(i1 %c) {
|
||||
; CHECK-LABEL: @test(
|
||||
; CHECK-NEXT: tail call fastcc void @capture_and_trap()
|
||||
; DEFAULT-NEXT: tail call fastcc void @capture_and_trap.argelim()
|
||||
; LTO-NEXT: tail call fastcc void @capture_and_trap.argprom()
|
||||
; CHECK-NEXT: unreachable
|
||||
;
|
||||
br i1 %c, label %if, label %else
|
||||
|
@ -8,7 +8,7 @@
|
||||
; CHECK: [[DUMMY:@.*]] = local_unnamed_addr global i32 0
|
||||
|
||||
define internal void @f(ptr byval(%struct.ss) align 8 %b, ptr byval(i32) align 4 %X) noinline nounwind {
|
||||
; CHECK-LABEL: define {{[^@]+}}@f
|
||||
; CHECK-LABEL: define {{[^@]+}}@f.argprom.argelim
|
||||
; CHECK-SAME: (i32 [[B_0:%.*]]){{[^#]*}} #[[ATTR0:[0-9]+]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TEMP:%.*]] = add i32 [[B_0]], 1
|
||||
@ -27,7 +27,7 @@ define i32 @test(ptr %X) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@test
|
||||
; CHECK-SAME: (ptr {{[^%]*}} [[X:%.*]]){{[^#]*}} #[[ATTR1:[0-9]+]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: tail call {{.*}}void @f(i32 1)
|
||||
; CHECK-NEXT: tail call {{.*}}void @f.argprom.argelim(i32 1)
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
entry:
|
||||
|
@ -4,8 +4,8 @@
|
||||
; CHECK-NOT: %X
|
||||
|
||||
define internal i32 @foo(i32 %X) {
|
||||
; CHECK-LABEL: @foo(
|
||||
; CHECK-NEXT: [[Y:%.*]] = call i32 @foo()
|
||||
; CHECK-LABEL: @foo.argelim(
|
||||
; CHECK-NEXT: [[Y:%.*]] = call i32 @foo.argelim()
|
||||
; CHECK-NEXT: [[Z:%.*]] = add i32 [[Y]], 1
|
||||
; CHECK-NEXT: ret i32 [[Z]]
|
||||
;
|
||||
@ -16,7 +16,7 @@ define internal i32 @foo(i32 %X) {
|
||||
|
||||
define void @bar() {
|
||||
; CHECK-LABEL: @bar(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @foo()
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @foo.argelim()
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call i32 @foo( i32 17 ) ; <i32>:1 [#uses=0]
|
||||
|
Loading…
x
Reference in New Issue
Block a user