xref: /llvm-project/llvm/test/Transforms/FunctionSpecialization/track-ptr-return.ll (revision 06664fdc7680f7f9fa9b0a414a8fb8df2f913d48)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 5
2; RUN: opt -passes="ipsccp<func-spec>" -force-specialization \
3; RUN:     -funcspec-max-iters=3 -S < %s | FileCheck %s
4
5; RUN: opt -passes="ipsccp<func-spec>" -force-specialization          \
6; RUN:     -funcspec-for-literal-constant=false -funcspec-max-iters=3 \
7; RUN:     -S < %s | FileCheck %s --check-prefix=NOLIT
8
9@global_true = constant i1 true
10@global_false = constant i1 false
11
12define i64 @main() {
13entry:
14  %op1 = call ptr @select_op(ptr @global_true)
15  %op2 = call ptr @select_op(ptr @global_false)
16
17  %c1 = call i64 @compute(ptr %op1)
18  %c2 = call i64 @compute(ptr %op2)
19  %add = add i64 %c1, %c2
20  ret i64 %add
21}
22
23define ptr @select_op(ptr %flag) {
24  %flag.val = load i1, ptr %flag
25  %op = select i1 %flag.val, ptr @plus, ptr @minus
26  ret ptr %op
27}
28
29define internal i64 @compute(ptr %op) {
30entry:
31  %res = call i64 %op(i64 1)
32  ret i64 %res
33}
34
35define internal i64 @plus(i64 %x) {
36entry:
37  %sum = add i64 %x, 1
38  ret i64 %sum
39}
40
41define internal i64 @minus(i64 %x) {
42entry:
43  %diff = sub i64 %x, 1
44  ret i64 %diff
45}
46; CHECK-LABEL: define i64 @main() {
47; CHECK-NEXT:  [[ENTRY:.*:]]
48; CHECK-NEXT:    [[OP1:%.*]] = call ptr @select_op.specialized.1(ptr @global_true)
49; CHECK-NEXT:    [[OP2:%.*]] = call ptr @select_op.specialized.2(ptr @global_false)
50; CHECK-NEXT:    [[C1:%.*]] = call i64 @compute.specialized.3(ptr @plus)
51; CHECK-NEXT:    [[C2:%.*]] = call i64 @compute.specialized.4(ptr @minus)
52; CHECK-NEXT:    [[ADD:%.*]] = add i64 [[C1]], [[C2]]
53; CHECK-NEXT:    ret i64 [[ADD]]
54;
55;
56; CHECK-LABEL: define ptr @select_op(
57; CHECK-SAME: ptr [[FLAG:%.*]]) {
58; CHECK-NEXT:    [[FLAG_VAL:%.*]] = load i1, ptr [[FLAG]], align 1
59; CHECK-NEXT:    [[OP:%.*]] = select i1 [[FLAG_VAL]], ptr @plus, ptr @minus
60; CHECK-NEXT:    ret ptr [[OP]]
61;
62;
63; CHECK-LABEL: define internal i64 @plus(
64; CHECK-SAME: i64 [[X:%.*]]) {
65; CHECK-NEXT:  [[ENTRY:.*:]]
66; CHECK-NEXT:    [[SUM:%.*]] = add i64 [[X]], 1
67; CHECK-NEXT:    ret i64 [[SUM]]
68;
69;
70; CHECK-LABEL: define internal i64 @minus(
71; CHECK-SAME: i64 [[X:%.*]]) {
72; CHECK-NEXT:  [[ENTRY:.*:]]
73; CHECK-NEXT:    [[DIFF:%.*]] = sub i64 [[X]], 1
74; CHECK-NEXT:    ret i64 [[DIFF]]
75;
76;
77; CHECK-LABEL: define internal ptr @select_op.specialized.1(
78; CHECK-SAME: ptr [[FLAG:%.*]]) {
79; CHECK-NEXT:    ret ptr poison
80;
81;
82; CHECK-LABEL: define internal ptr @select_op.specialized.2(
83; CHECK-SAME: ptr [[FLAG:%.*]]) {
84; CHECK-NEXT:    ret ptr poison
85;
86;
87; CHECK-LABEL: define internal i64 @compute.specialized.3(
88; CHECK-SAME: ptr [[OP:%.*]]) {
89; CHECK-NEXT:  [[ENTRY:.*:]]
90; CHECK-NEXT:    [[RES:%.*]] = call i64 @plus(i64 1)
91; CHECK-NEXT:    ret i64 [[RES]]
92;
93;
94; CHECK-LABEL: define internal i64 @compute.specialized.4(
95; CHECK-SAME: ptr [[OP:%.*]]) {
96; CHECK-NEXT:  [[ENTRY:.*:]]
97; CHECK-NEXT:    [[RES:%.*]] = call i64 @minus(i64 1)
98; CHECK-NEXT:    ret i64 [[RES]]
99;
100;
101; NOLIT-LABEL: define i64 @main() {
102; NOLIT-NEXT:  [[ENTRY:.*:]]
103; NOLIT-NEXT:    [[OP1:%.*]] = call ptr @select_op.specialized.1(ptr @global_true)
104; NOLIT-NEXT:    [[OP2:%.*]] = call ptr @select_op.specialized.2(ptr @global_false)
105; NOLIT-NEXT:    [[C1:%.*]] = call i64 @compute(ptr @plus)
106; NOLIT-NEXT:    [[C2:%.*]] = call i64 @compute(ptr @minus)
107; NOLIT-NEXT:    [[ADD:%.*]] = add i64 [[C1]], [[C2]]
108; NOLIT-NEXT:    ret i64 [[ADD]]
109;
110;
111; NOLIT-LABEL: define ptr @select_op(
112; NOLIT-SAME: ptr [[FLAG:%.*]]) {
113; NOLIT-NEXT:    [[FLAG_VAL:%.*]] = load i1, ptr [[FLAG]], align 1
114; NOLIT-NEXT:    [[OP:%.*]] = select i1 [[FLAG_VAL]], ptr @plus, ptr @minus
115; NOLIT-NEXT:    ret ptr [[OP]]
116;
117;
118; NOLIT-LABEL: define internal i64 @compute(
119; NOLIT-SAME: ptr [[OP:%.*]]) {
120; NOLIT-NEXT:  [[ENTRY:.*:]]
121; NOLIT-NEXT:    [[RES:%.*]] = call i64 [[OP]](i64 1)
122; NOLIT-NEXT:    ret i64 [[RES]]
123;
124;
125; NOLIT-LABEL: define internal i64 @plus(
126; NOLIT-SAME: i64 [[X:%.*]]) {
127; NOLIT-NEXT:  [[ENTRY:.*:]]
128; NOLIT-NEXT:    [[SUM:%.*]] = add i64 [[X]], 1
129; NOLIT-NEXT:    ret i64 [[SUM]]
130;
131;
132; NOLIT-LABEL: define internal i64 @minus(
133; NOLIT-SAME: i64 [[X:%.*]]) {
134; NOLIT-NEXT:  [[ENTRY:.*:]]
135; NOLIT-NEXT:    [[DIFF:%.*]] = sub i64 [[X]], 1
136; NOLIT-NEXT:    ret i64 [[DIFF]]
137;
138;
139; NOLIT-LABEL: define internal ptr @select_op.specialized.1(
140; NOLIT-SAME: ptr [[FLAG:%.*]]) {
141; NOLIT-NEXT:    ret ptr poison
142;
143;
144; NOLIT-LABEL: define internal ptr @select_op.specialized.2(
145; NOLIT-SAME: ptr [[FLAG:%.*]]) {
146; NOLIT-NEXT:    ret ptr poison
147;
148