1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; Verify that memrchr calls with one or more constant arguments are folded
7 declare ptr @memrchr(ptr, i32, i64)
9 @ax = external global [0 x i8]
10 @a12345 = constant [5 x i8] c"\01\02\03\04\05"
11 @a123123 = constant [6 x i8] c"\01\02\03\01\02\03"
14 ; Fold memrchr(ax, C, 0) to null.
16 define ptr @fold_memrchr_ax_c_0(i32 %C) {
17 ; CHECK-LABEL: @fold_memrchr_ax_c_0(
18 ; CHECK-NEXT: ret ptr null
21 %ret = call ptr @memrchr(ptr @ax, i32 %C, i64 0)
26 ; Fold memrchr(a12345, 3, 0) to null.
28 define ptr @fold_memrchr_a12345_3_0() {
29 ; CHECK-LABEL: @fold_memrchr_a12345_3_0(
30 ; CHECK-NEXT: ret ptr null
33 %ret = call ptr @memrchr(ptr @a12345, i32 3, i64 0)
38 ; Fold memrchr(a12345, 1, 1) to a12345.
40 define ptr @fold_memrchr_a12345_1_1() {
41 ; CHECK-LABEL: @fold_memrchr_a12345_1_1(
42 ; CHECK-NEXT: ret ptr @a12345
44 %ret = call ptr @memrchr(ptr @a12345, i32 1, i64 1)
49 ; Fold memrchr(a12345, 5, 1) to null.
51 define ptr @fold_memrchr_a12345_5_1() {
52 ; CHECK-LABEL: @fold_memrchr_a12345_5_1(
53 ; CHECK-NEXT: ret ptr null
55 %ret = call ptr @memrchr(ptr @a12345, i32 5, i64 1)
60 ; Fold memrchr(a123123, 1, 1) to a123123.
62 define ptr @fold_memrchr_a123123_1_1() {
63 ; CHECK-LABEL: @fold_memrchr_a123123_1_1(
64 ; CHECK-NEXT: ret ptr @a123123
66 %ret = call ptr @memrchr(ptr @a123123, i32 1, i64 1)
71 ; Fold memrchr(a123123, 3, 1) to null.
73 define ptr @fold_memrchr_a123123_3_1() {
74 ; CHECK-LABEL: @fold_memrchr_a123123_3_1(
75 ; CHECK-NEXT: ret ptr null
77 %ret = call ptr @memrchr(ptr @a123123, i32 3, i64 1)
82 ; Fold memrchr(ax, C, 1) to *ax == C ? ax : null.
84 define ptr @fold_memrchr_ax_c_1(i32 %C) {
85 ; CHECK-LABEL: @fold_memrchr_ax_c_1(
86 ; CHECK-NEXT: [[MEMRCHR_CHAR0:%.*]] = load i8, ptr @ax, align 1
87 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8
88 ; CHECK-NEXT: [[MEMRCHR_CHAR0CMP:%.*]] = icmp eq i8 [[MEMRCHR_CHAR0]], [[TMP1]]
89 ; CHECK-NEXT: [[MEMRCHR_SEL:%.*]] = select i1 [[MEMRCHR_CHAR0CMP]], ptr @ax, ptr null
90 ; CHECK-NEXT: ret ptr [[MEMRCHR_SEL]]
92 %ret = call ptr @memrchr(ptr @ax, i32 %C, i64 1)
97 ; Fold memrchr(a12345, 5, 5) to a12345 + 4.
99 define ptr @fold_memrchr_a12345_5_5() {
100 ; CHECK-LABEL: @fold_memrchr_a12345_5_5(
101 ; CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @a12345, i64 4)
104 %ret = call ptr @memrchr(ptr @a12345, i32 5, i64 5)
109 ; Fold memrchr(a12345, 5, 4) to null.
111 define ptr @fold_memrchr_a12345_5_4() {
112 ; CHECK-LABEL: @fold_memrchr_a12345_5_4(
113 ; CHECK-NEXT: ret ptr null
116 %ret = call ptr @memrchr(ptr @a12345, i32 5, i64 4)
121 ; Fold memrchr(a12345, 4, 5) to a12345 + 3.
123 define ptr @fold_memrchr_a12345_4_5() {
124 ; CHECK-LABEL: @fold_memrchr_a12345_4_5(
125 ; CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @a12345, i64 3)
128 %ret = call ptr @memrchr(ptr @a12345, i32 4, i64 5)
133 ; Fold memrchr(a12345 + 1, 1, 4) to null.
135 define ptr @fold_memrchr_a12345p1_1_4() {
136 ; CHECK-LABEL: @fold_memrchr_a12345p1_1_4(
137 ; CHECK-NEXT: ret ptr null
140 %ptr = getelementptr [5 x i8], ptr @a12345, i32 0, i32 1
141 %ret = call ptr @memrchr(ptr %ptr, i32 1, i64 4)
146 ; Fold memrchr(a12345 + 1, 2, 4) to a12345 + 1.
148 define ptr @fold_memrchr_a12345p1_2_4() {
149 ; CHECK-LABEL: @fold_memrchr_a12345p1_2_4(
150 ; CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @a12345, i64 1)
153 %ptr = getelementptr [5 x i8], ptr @a12345, i32 0, i32 1
154 %ret = call ptr @memrchr(ptr %ptr, i32 2, i64 4)
159 ; Fold memrchr(a12345, 2, 5) to a12345 + 1.
161 define ptr @fold_memrchr_a12345_2_5() {
162 ; CHECK-LABEL: @fold_memrchr_a12345_2_5(
163 ; CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @a12345, i64 1)
166 %ret = call ptr @memrchr(ptr @a12345, i32 2, i64 5)
171 ; Fold memrchr(a12345, 0, %N) to null.
173 define ptr @fold_memrchr_a12345_0_n(i64 %N) {
174 ; CHECK-LABEL: @fold_memrchr_a12345_0_n(
175 ; CHECK-NEXT: ret ptr null
178 %ret = call ptr @memrchr(ptr @a12345, i32 0, i64 %N)
183 ; Fold memrchr(a12345, 3, n) to n < 3 ? null : s + 2.
185 define ptr @fold_memrchr_a12345_3_n(i64 %n) {
186 ; CHECK-LABEL: @fold_memrchr_a12345_3_n(
187 ; CHECK-NEXT: [[MEMRCHR_CMP:%.*]] = icmp ult i64 [[N:%.*]], 3
188 ; CHECK-NEXT: [[MEMRCHR_SEL:%.*]] = select i1 [[MEMRCHR_CMP]], ptr null, ptr getelementptr inbounds (i8, ptr @a12345, i64 2)
189 ; CHECK-NEXT: ret ptr [[MEMRCHR_SEL]]
192 %ret = call ptr @memrchr(ptr @a12345, i32 3, i64 %n)
197 ; Fold memrchr(a12345, 5, n) to n < 5 ? null : s + 4.
199 define ptr @fold_memrchr_a12345_5_n(i64 %n) {
200 ; CHECK-LABEL: @fold_memrchr_a12345_5_n(
201 ; CHECK-NEXT: [[MEMRCHR_CMP:%.*]] = icmp ult i64 [[N:%.*]], 5
202 ; CHECK-NEXT: [[MEMRCHR_SEL:%.*]] = select i1 [[MEMRCHR_CMP]], ptr null, ptr getelementptr inbounds (i8, ptr @a12345, i64 4)
203 ; CHECK-NEXT: ret ptr [[MEMRCHR_SEL]]
206 %ret = call ptr @memrchr(ptr @a12345, i32 5, i64 %n)
211 ; Fold memrchr(a123123, 3, 5) to a123123 + 2.
213 define ptr @fold_memrchr_a123123_3_5() {
214 ; CHECK-LABEL: @fold_memrchr_a123123_3_5(
215 ; CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @a123123, i64 2)
218 %ret = call ptr @memrchr(ptr @a123123, i32 3, i64 5)
223 ; Fold memrchr(a123123, 3, 6) to a123123 + 5.
225 define ptr @fold_memrchr_a123123_3_6() {
226 ; CHECK-LABEL: @fold_memrchr_a123123_3_6(
227 ; CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @a123123, i64 5)
230 %ret = call ptr @memrchr(ptr @a123123, i32 3, i64 6)
234 ; Fold memrchr(a123123, 2, 6) to a123123 + 4.
236 define ptr @fold_memrchr_a123123_2_6() {
237 ; CHECK-LABEL: @fold_memrchr_a123123_2_6(
238 ; CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @a123123, i64 4)
241 %ret = call ptr @memrchr(ptr @a123123, i32 2, i64 6)
245 ; Fold memrchr(a123123, 1, 6) to a123123 + 3.
247 define ptr @fold_memrchr_a123123_1_6() {
248 ; CHECK-LABEL: @fold_memrchr_a123123_1_6(
249 ; CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @a123123, i64 3)
252 %ret = call ptr @memrchr(ptr @a123123, i32 1, i64 6)
257 ; Fold memrchr(a123123, 0, 6) to null.
259 define ptr @fold_memrchr_a123123_0_6() {
260 ; CHECK-LABEL: @fold_memrchr_a123123_0_6(
261 ; CHECK-NEXT: ret ptr null
264 %ret = call ptr @memrchr(ptr @a123123, i32 0, i64 6)
269 ; Fold memrchr(a123123, 0, n) to null
271 define ptr @fold_memrchr_a123123_0_n(i64 %n) {
272 ; CHECK-LABEL: @fold_memrchr_a123123_0_n(
273 ; CHECK-NEXT: ret ptr null
276 %ret = call ptr @memrchr(ptr @a123123, i32 0, i64 %n)
281 ; Don't fold memrchr(a123123, 3, n) (although it's possible to fold the call
282 ; for a small number of occurrences of the character greater than one, it's
283 ; less and less profitable as the number grows).
285 define ptr @call_memrchr_a123123_3_n(i64 %n) {
286 ; CHECK-LABEL: @call_memrchr_a123123_3_n(
287 ; CHECK-NEXT: [[RET:%.*]] = call ptr @memrchr(ptr nonnull @a123123, i32 3, i64 [[N:%.*]])
288 ; CHECK-NEXT: ret ptr [[RET]]
291 %ret = call ptr @memrchr(ptr @a123123, i32 3, i64 %n)
296 ; Same as above but for 2.
298 define ptr @call_memrchr_a123123_2_n(i64 %n) {
299 ; CHECK-LABEL: @call_memrchr_a123123_2_n(
300 ; CHECK-NEXT: [[RET:%.*]] = call ptr @memrchr(ptr nonnull @a123123, i32 2, i64 [[N:%.*]])
301 ; CHECK-NEXT: ret ptr [[RET]]
304 %ret = call ptr @memrchr(ptr @a123123, i32 2, i64 %n)
309 ; And again for 1 to exercise the other edge case.
311 define ptr @call_memrchr_a123123_1_n(i64 %n) {
312 ; CHECK-LABEL: @call_memrchr_a123123_1_n(
313 ; CHECK-NEXT: [[RET:%.*]] = call ptr @memrchr(ptr nonnull @a123123, i32 1, i64 [[N:%.*]])
314 ; CHECK-NEXT: ret ptr [[RET]]
317 %ret = call ptr @memrchr(ptr @a123123, i32 1, i64 %n)