xref: /llvm-project/llvm/test/Transforms/FunctionSpecialization/track-return.ll (revision 16bb8c16aab32e2ee623a2b64d976548be247180)
1; RUN: opt -passes="ipsccp<func-spec>" -force-specialization -funcspec-for-literal-constant -funcspec-max-iters=3 -S < %s | FileCheck %s
2
3define i64 @main() {
4; CHECK:       define i64 @main
5; CHECK-NEXT:  entry:
6; CHECK-NEXT:    [[C1:%.*]] = call i64 @foo.specialized.1(i1 true, i64 3, i64 1)
7; CHECK-NEXT:    [[C2:%.*]] = call i64 @foo.specialized.2(i1 false, i64 4, i64 -1)
8; CHECK-NEXT:    ret i64 8
9;
10entry:
11  %c1 = call i64 @foo(i1 true, i64 3, i64 1)
12  %c2 = call i64 @foo(i1 false, i64 4, i64 -1)
13  %add = add i64 %c1, %c2
14  ret i64 %add
15}
16
17define internal i64 @foo(i1 %flag, i64 %m, i64 %n) {
18;
19; CHECK:       define internal i64 @foo.specialized.1
20; CHECK-NEXT:  entry:
21; CHECK-NEXT:    br label %plus
22; CHECK:       plus:
23; CHECK-NEXT:    [[N0:%.*]] = call i64 @binop.specialized.4(i64 3, i64 1)
24; CHECK-NEXT:    [[RES0:%.*]] = call i64 @bar.specialized.6(i64 4)
25; CHECK-NEXT:    br label %merge
26; CHECK:       merge:
27; CHECK-NEXT:    ret i64 poison
28;
29; CHECK:       define internal i64 @foo.specialized.2
30; CHECK-NEXT:  entry:
31; CHECK-NEXT:    br label %minus
32; CHECK:       minus:
33; CHECK-NEXT:    [[N1:%.*]] = call i64 @binop.specialized.3(i64 4, i64 -1)
34; CHECK-NEXT:    [[RES1:%.*]] = call i64 @bar.specialized.5(i64 3)
35; CHECK-NEXT:    br label %merge
36; CHECK:       merge:
37; CHECK-NEXT:    ret i64 poison
38;
39entry:
40  br i1 %flag, label %plus, label %minus
41
42plus:
43  %n0 = call i64 @binop(i64 %m, i64 %n)
44  %res0 = call i64 @bar(i64 %n0)
45  br label %merge
46
47minus:
48  %n1 = call i64 @binop(i64 %m, i64 %n)
49  %res1 = call i64 @bar(i64 %n1)
50  br label %merge
51
52merge:
53  %res = phi i64 [ %res0, %plus ], [ %res1, %minus]
54  ret i64 %res
55}
56
57define internal i64 @binop(i64 %x, i64 %y) {
58;
59; CHECK:       define internal i64 @binop.specialized.3
60; CHECK-NEXT:  entry:
61; CHECK-NEXT:    ret i64 poison
62;
63; CHECK:       define internal i64 @binop.specialized.4
64; CHECK-NEXT:  entry:
65; CHECK-NEXT:    ret i64 poison
66;
67entry:
68  %z = add i64 %x, %y
69  ret i64 %z
70}
71
72define internal i64 @bar(i64 %n) {
73;
74; CHECK:       define internal i64 @bar.specialized.5
75; CHECK-NEXT:  entry:
76; CHECK-NEXT:    br label %if.else
77; CHECK:       if.else:
78; CHECK-NEXT:    br label %if.end
79; CHECK:       if.end:
80; CHECK-NEXT:    ret i64 poison
81;
82; CHECK:       define internal i64 @bar.specialized.6
83; CHECK-NEXT:  entry:
84; CHECK-NEXT:    br label %if.then
85; CHECK:       if.then:
86; CHECK-NEXT:    br label %if.end
87; CHECK:       if.end:
88; CHECK-NEXT:    ret i64 poison
89;
90entry:
91  %cmp = icmp sgt i64 %n, 3
92  br i1 %cmp, label %if.then, label %if.else
93
94if.then:
95  %res0 = sdiv i64 %n, 2
96  br label %if.end
97
98if.else:
99  %res1 = mul i64 %n, 2
100  br label %if.end
101
102if.end:
103  %res = phi i64 [ %res0, %if.then ], [ %res1, %if.else]
104  ret i64 %res
105}
106
107