[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:
yonghong-song 2024-09-19 10:21:58 +02:00 committed by GitHub
parent 30cdf1e959
commit 959448fbd6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
79 changed files with 342 additions and 263 deletions

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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" }

View File

@ -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" }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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
;

View File

@ -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]]

View File

@ -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:

View File

@ -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:

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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]

View File

@ -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
;

View File

@ -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
;

View File

@ -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]]
;

View File

@ -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:

View File

@ -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]]

View File

@ -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:%.*]]

View File

@ -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

View File

@ -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)

View File

@ -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: }

View File

@ -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", ""()

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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]]

View File

@ -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]]

View File

@ -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]]

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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]]

View File

@ -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) {

View File

@ -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
}

View File

@ -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]+]])

View File

@ -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 {

View File

@ -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

View File

@ -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) {

View File

@ -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 {

View File

@ -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

View File

@ -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) ]

View File

@ -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]] ]

View File

@ -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

View File

@ -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()

View File

@ -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) {
;
;

View File

@ -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

View File

@ -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

View File

@ -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)
}

View File

@ -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

View File

@ -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()

View File

@ -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() {

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -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]