Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SCCP / ip-add-range-to-call.ll
blob91efbcc4ee3825ebc52f8cc8d7635b88d4166da0
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt -passes=ipsccp -S %s | FileCheck %s
4 ; Test 1.
5 ; Both arguments and return value of @callee can be tracked. The inferred range
6 ; can be added to call sites.
7 define internal i32 @callee(i32 %x) {
8 ; CHECK-LABEL: define internal range(i32 0, 21) i32 @callee(
9 ; CHECK-SAME: i32 [[X:%.*]]) {
10 ; CHECK-NEXT:    ret i32 [[X]]
12   ret i32 %x
15 define i32 @caller1() {
16 ; CHECK-LABEL: define range(i32 0, 41) i32 @caller1() {
17 ; CHECK-NEXT:    [[C1:%.*]] = call i32 @callee(i32 10)
18 ; CHECK-NEXT:    [[C2:%.*]] = call i32 @callee(i32 20)
19 ; CHECK-NEXT:    [[A:%.*]] = add nuw nsw i32 [[C1]], [[C2]]
20 ; CHECK-NEXT:    ret i32 [[A]]
22   %c1 = call i32 @callee(i32 10)
23   %c2 = call i32 @callee(i32 20)
24   %a = add i32 %c1, %c2
25   ret i32 %a
28 define i32 @caller2(i32 %x) {
29 ; CHECK-LABEL: define range(i32 0, 21) i32 @caller2(
30 ; CHECK-SAME: i32 [[X:%.*]]) {
31 ; CHECK-NEXT:    [[X_15:%.*]] = and i32 [[X]], 15
32 ; CHECK-NEXT:    [[C:%.*]] = call i32 @callee(i32 [[X_15]])
33 ; CHECK-NEXT:    ret i32 [[C]]
35   %x.15 = and i32 %x, 15
36   %c = call i32 @callee(i32 %x.15)
37   ret i32 %c
40 ; Test 2.
41 ; The return value of @callee2 can be tracked, but arguments cannot, because
42 ; it is passed to @use_cb1. We cannot infer a range for the return value, no
43 ; metadata should be added.
45 declare void @use_cb1(ptr)
47 define internal i32 @callee2(i32 %x) {
48 ; CHECK-LABEL: define internal i32 @callee2(
49 ; CHECK-SAME: i32 [[X:%.*]]) {
50 ; CHECK-NEXT:    ret i32 [[X]]
52   ret i32 %x
55 define void @caller_cb1() {
56 ; CHECK-LABEL: define void @caller_cb1() {
57 ; CHECK-NEXT:    [[C1:%.*]] = call i32 @callee2(i32 9)
58 ; CHECK-NEXT:    [[C2:%.*]] = call i32 @callee2(i32 10)
59 ; CHECK-NEXT:    call void @use_cb1(ptr @callee2)
60 ; CHECK-NEXT:    ret void
62   %c1 = call i32 @callee2(i32 9)
63   %c2 = call i32 @callee2(i32 10)
64   call void @use_cb1(ptr @callee2)
65   ret void
68 ; Test 3.
69 ; The return value can be tracked and it the result range ([500, 601) does not
70 ; depend on the arguments, which cannot be tracked because @callee3 is passed
71 ; to @use_cb2. The result range can be added to the call sites of @callee.
73 declare void @use_cb2(ptr)
75 define internal i32 @callee3(i32 %x) {
76 ; CHECK-LABEL: define internal range(i32 500, 601) i32 @callee3(
77 ; CHECK-SAME: i32 [[X:%.*]]) {
78 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X]], 10
79 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 500, i32 600
80 ; CHECK-NEXT:    ret i32 [[S]]
82   %c = icmp eq i32 %x, 10
83   %s = select i1 %c, i32 500, i32 600
84   ret i32 %s
87 define void @caller_cb2() {
88 ; CHECK-LABEL: define void @caller_cb2() {
89 ; CHECK-NEXT:    [[C1:%.*]] = call i32 @callee3(i32 9)
90 ; CHECK-NEXT:    [[C2:%.*]] = call i32 @callee3(i32 10)
91 ; CHECK-NEXT:    call void @use_cb2(ptr @callee3)
92 ; CHECK-NEXT:    ret void
94   %c1 = call i32 @callee3(i32 9)
95   %c2 = call i32 @callee3(i32 10)
96   call void @use_cb2(ptr @callee3)
97   ret void
100 ; Test 4.
101 ; The return value of @callee4 can be tracked, but depends on an argument which
102 ; cannot be tracked. No result range can be inferred.
104 declare void @use_cb3(ptr)
106 define internal i32 @callee4(i32 %x, i32 %y) {
107 ; CHECK-LABEL: define internal i32 @callee4(
108 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
109 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X]], 10
110 ; CHECK-NEXT:    [[S:%.*]] = select i1 [[C]], i32 500, i32 [[Y]]
111 ; CHECK-NEXT:    ret i32 [[S]]
113   %c = icmp eq i32 %x, 10
114   %s = select i1 %c, i32 500, i32 %y
115   ret i32 %s
118 define void @caller_cb3() {
119 ; CHECK-LABEL: define void @caller_cb3() {
120 ; CHECK-NEXT:    [[C1:%.*]] = call i32 @callee4(i32 11, i32 30)
121 ; CHECK-NEXT:    [[C2:%.*]] = call i32 @callee4(i32 12, i32 40)
122 ; CHECK-NEXT:    call void @use_cb3(ptr @callee4)
123 ; CHECK-NEXT:    ret void
125   %c1 = call i32 @callee4(i32 11, i32 30)
126   %c2 = call i32 @callee4(i32 12, i32 40)
127   call void @use_cb3(ptr @callee4)
128   ret void
131 ; Test 5.
132 ; Range for the return value of callee5 includes undef. No range metadata
133 ; should be added at call sites.
134 define internal i32 @callee5(i32 %x, i32 %y) {
135 ; CHECK-LABEL: define internal i32 @callee5(
136 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
137 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[X]], 15
138 ; CHECK-NEXT:    br i1 [[C]], label [[BB1:%.*]], label [[BB2:%.*]]
139 ; CHECK:       bb1:
140 ; CHECK-NEXT:    br label [[EXIT:%.*]]
141 ; CHECK:       bb2:
142 ; CHECK-NEXT:    br label [[EXIT]]
143 ; CHECK:       exit:
144 ; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[Y]], [[BB1]] ], [ undef, [[BB2]] ]
145 ; CHECK-NEXT:    ret i32 [[RES]]
147   %c = icmp slt i32 %x, 15
148   br i1 %c, label %bb1, label %bb2
150 bb1:
151   br label %exit
153 bb2:
154   br label %exit
156 exit:
157   %res = phi i32 [ %y, %bb1 ], [ undef, %bb2]
158   ret i32 %res
161 define i32 @caller5() {
162 ; CHECK-LABEL: define i32 @caller5() {
163 ; CHECK-NEXT:    [[C1:%.*]] = call i32 @callee5(i32 10, i32 100)
164 ; CHECK-NEXT:    [[C2:%.*]] = call i32 @callee5(i32 20, i32 200)
165 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[C1]], [[C2]]
166 ; CHECK-NEXT:    ret i32 [[A]]
168   %c1 = call i32 @callee5(i32 10, i32 100)
169   %c2 = call i32 @callee5(i32 20, i32 200)
170   %a = add i32 %c1, %c2
171   ret i32 %a
174 define internal <2 x i64> @ctlz(<2 x i64> %arg) {
175 ; CHECK-LABEL: define internal range(i64 0, 65) <2 x i64> @ctlz(
176 ; CHECK-SAME: <2 x i64> [[ARG:%.*]]) {
177 ; CHECK-NEXT:    [[RES:%.*]] = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> [[ARG]], i1 false)
178 ; CHECK-NEXT:    ret <2 x i64> [[RES]]
180   %res = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %arg, i1 false)
181   ret <2 x i64> %res
184 define <2 x i64> @ctlz_caller(<2 x i64> %arg) {
185 ; CHECK-LABEL: define range(i64 0, 65) <2 x i64> @ctlz_caller(
186 ; CHECK-SAME: <2 x i64> [[ARG:%.*]]) {
187 ; CHECK-NEXT:    [[RES:%.*]] = call <2 x i64> @ctlz(<2 x i64> [[ARG]])
188 ; CHECK-NEXT:    ret <2 x i64> [[RES]]
190   %res = call <2 x i64> @ctlz(<2 x i64> %arg)
191   ret <2 x i64> %res
194 declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1)