xref: /llvm-project/llvm/test/Transforms/FunctionSpecialization/non-argument-tracked.ll (revision e15d72adac66790a78a51a3087b56b2bde6b778a)
1; RUN: opt -S --passes=ipsccp,deadargelim -funcspec-for-literal-constant --force-specialization < %s | FileCheck %s
2
3; Test that all of `f0`, `f1`, and `f2` are specialised, even though `f0` has its address taken
4; and `f1` is with external linkage (`f2` was specialised anyway).
5
6@p = global ptr @f0
7
8; `f0` is kept even though all apparent calls are specialized
9; CHECK-LABEL: define internal i32 @f0(
10define internal i32 @f0(i32 %i) {
11  %v = add i32 %i, 1
12  ret i32 %v
13}
14
15; Likewise, `f1` is kept, because of the external linkage
16; CHECK-LABEL: define i32 @f1(
17define i32 @f1(i32 %i) {
18  %v = add i32 %i, 1
19  ret i32 %v
20}
21
22; `f2` is fully specialised.
23; CHECK-NOT: defined internal i32 @f2()
24define internal i32 @f2(i32 %i) {
25  %v = add i32 %i, 1
26  ret i32 %v
27}
28
29;; All calls are to specilisation instances.
30
31; CHECK-LABEL: define i32 @g0
32; CHECK:         call void @f0.specialized.[[#A:]]()
33; CHECK-NEXT:    call void @f1.specialized.[[#B:]]()
34; CHECK-NEXT:    call void @f2.specialized.[[#C:]]()
35; CHECK-NEXT:    ret i32 9
36define i32 @g0(i32 %i) {
37  %u0 = call i32 @f0(i32 1)
38  %u1 = call i32 @f1(i32 2)
39  %u2 = call i32 @f2(i32 3)
40  %v0 = add i32 %u0, %u1
41  %v = add i32 %v0, %u2
42  ret i32 %v
43}
44
45; CHECK-LABEL: define i32 @g1
46; CHECK:         call void @f0.specialized.[[#D:]]()
47; CHECK-NEXT:    call void @f1.specialized.[[#E:]]()
48; CHECK-NEXT:    call void @f2.specialized.[[#F:]]()
49; CHECK-NEXT:    ret i32 12
50define i32 @g1(i32 %i) {
51  %u0 = call i32 @f0(i32 2)
52  %u1 = call i32 @f1(i32 3)
53  %u2 = call i32 @f2(i32 4)
54  %v0 = add i32 %u0, %u1
55  %v = add i32 %v0, %u2
56  ret i32 %v
57}
58
59; All of the function are specialized and all clones are with internal linkage.
60
61; CHECK-DAG: define internal void @f0.specialized.[[#A]]() {
62; CHECK-DAG: define internal void @f1.specialized.[[#B]]() {
63; CHECK-DAG: define internal void @f2.specialized.[[#C]]() {
64; CHECK-DAG: define internal void @f0.specialized.[[#D]]() {
65; CHECK-DAG: define internal void @f1.specialized.[[#E]]() {
66; CHECK-DAG: define internal void @f2.specialized.[[#F]]() {
67