[SLP] Add cost model for `llvm.powi.*` intrinsics
[llvm-project.git] / llvm / test / Transforms / InstCombine / strnlen-3.ll
blob877eae813c683d33a5aaa3542c241884b2075cff
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; Verify that strnlen calls with conditional expressions involving constant
3 ; string arguments with nonconstant offsets and constant bounds or constant
4 ; offsets and nonconstant bounds are folded correctly.
6 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
8 declare i64 @strnlen(i8*, i64)
10 @sx = external global [0 x i8]
11 @a3 = constant [3 x i8] c"123"
12 @s3 = constant [4 x i8] c"123\00"
13 @s5 = constant [6 x i8] c"12345\00"
14 @s5_3 = constant [10 x i8] c"12345\00abc\00"
17 ; Fold strnlen(sx + i, 0) to 0.
19 define i64 @fold_strnlen_sx_pi_0(i64 %i) {
20 ; CHECK-LABEL: @fold_strnlen_sx_pi_0(
21 ; CHECK-NEXT:    ret i64 0
24   %ptr = getelementptr [0 x i8], [0 x i8]* @sx, i64 0, i64 %i
25   %len = call i64 @strnlen(i8* %ptr, i64 0)
26   ret i64 %len
30 ; Do not fold strnlen(sx + i, n).
32 define i64 @call_strnlen_sx_pi_n(i64 %i, i64 %n) {
33 ; CHECK-LABEL: @call_strnlen_sx_pi_n(
34 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [0 x i8], [0 x i8]* @sx, i64 0, i64 [[I:%.*]]
35 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[N:%.*]])
36 ; CHECK-NEXT:    ret i64 [[LEN]]
39   %ptr = getelementptr inbounds [0 x i8], [0 x i8]* @sx, i64 0, i64 %i
40   %len = call i64 @strnlen(i8* %ptr, i64 %n)
41   ret i64 %len
45 ; Fold strnlen(a3 + i, 2) to min(3 - i, 2).
47 define i64 @call_strnlen_a3_pi_2(i64 %i) {
48 ; CHECK-LABEL: @call_strnlen_a3_pi_2(
49 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* @a3, i64 0, i64 [[I:%.*]]
50 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 2)
51 ; CHECK-NEXT:    ret i64 [[LEN]]
54   %ptr = getelementptr inbounds [3 x i8], [3 x i8]* @a3, i64 0, i64 %i
55   %len = call i64 @strnlen(i8* %ptr, i64 2)
56   ret i64 %len
60 ; Fold strnlen(a3 + i, 3) to min(3 - i, 3).
62 define i64 @call_strnlen_a3_pi_3(i64 %i) {
63 ; CHECK-LABEL: @call_strnlen_a3_pi_3(
64 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* @a3, i64 0, i64 [[I:%.*]]
65 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 3)
66 ; CHECK-NEXT:    ret i64 [[LEN]]
69   %ptr = getelementptr inbounds [3 x i8], [3 x i8]* @a3, i64 0, i64 %i
70   %len = call i64 @strnlen(i8* %ptr, i64 3)
71   ret i64 %len
75 ; Fold strnlen(s3 + i, 0) to 0.
77 define i64 @fold_strnlen_s3_pi_0(i64 %i) {
78 ; CHECK-LABEL: @fold_strnlen_s3_pi_0(
79 ; CHECK-NEXT:    ret i64 0
81   %ptr = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 %i
82   %len = call i64 @strnlen(i8* %ptr, i64 0)
83   ret i64 %len
87 ; Fold strnlen(s5 + i, 0) to 0.
89 define i64 @call_strnlen_s5_pi_0(i64 zeroext %i) {
90 ; CHECK-LABEL: @call_strnlen_s5_pi_0(
91 ; CHECK-NEXT:    ret i64 0
93   %ptr = getelementptr [6 x i8], [6 x i8]* @s5, i32 0, i32 0
94   %len = call i64 @strnlen(i8* %ptr, i64 0)
95   ret i64 %len
99 ; Fold strnlen(s5_3 + i, 0) to 0.
101 define i64 @fold_strnlen_s5_3_pi_0(i64 zeroext %i) {
102 ; CHECK-LABEL: @fold_strnlen_s5_3_pi_0(
103 ; CHECK-NEXT:    ret i64 0
105   %ptr = getelementptr [10 x i8], [10 x i8]* @s5_3, i32 0, i64 %i
106   %len = call i64 @strnlen(i8* %ptr, i64 0)
107   ret i64 %len
111 ; Do not fold strnlen(s5_3 + i, n).
113 define i64 @call_strnlen_s5_3_pi_n(i64 zeroext %i, i64 %n) {
114 ; CHECK-LABEL: @call_strnlen_s5_3_pi_n(
115 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i64 0, i64 [[I:%.*]]
116 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[N:%.*]])
117 ; CHECK-NEXT:    ret i64 [[LEN]]
119   %ptr = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i32 0, i64 %i
120   %len = call i64 @strnlen(i8* %ptr, i64 %n)
121   ret i64 %len
125 ; Fold strnlen(a3, n) to min(sizeof(a3), n)
127 define i64 @fold_strnlen_a3_n(i64 %n) {
128 ; CHECK-LABEL: @fold_strnlen_a3_n(
129 ; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.umin.i64(i64 [[N:%.*]], i64 3)
130 ; CHECK-NEXT:    ret i64 [[TMP1]]
133   %ptr = getelementptr [3 x i8], [3 x i8]* @a3, i64 0, i64 0
134   %len = call i64 @strnlen(i8* %ptr, i64 %n)
135   ret i64 %len
139 ; Fold strnlen(s3, n) to min(strlen(s3), n)
141 define i64 @fold_strnlen_s3_n(i64 %n) {
142 ; CHECK-LABEL: @fold_strnlen_s3_n(
143 ; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.umin.i64(i64 [[N:%.*]], i64 3)
144 ; CHECK-NEXT:    ret i64 [[TMP1]]
147   %ptr = getelementptr [4 x i8], [4 x i8]* @s3, i64 0, i64 0
148   %len = call i64 @strnlen(i8* %ptr, i64 %n)
149   ret i64 %len
153 ; Fold strnlen(a3 + i, 2) to min(sizeof(a3) - i, 2)
155 define i64 @fold_strnlen_a3_pi_2(i64 %i) {
156 ; CHECK-LABEL: @fold_strnlen_a3_pi_2(
157 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* @a3, i64 0, i64 [[I:%.*]]
158 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 2)
159 ; CHECK-NEXT:    ret i64 [[LEN]]
162   %ptr = getelementptr inbounds [3 x i8], [3 x i8]* @a3, i64 0, i64 %i
163   %len = call i64 @strnlen(i8* %ptr, i64 2)
164   ret i64 %len
168 ; Fold strnlen(s3 + i, 2) to min(strlen(s3) - i, 2)
170 define i64 @fold_strnlen_s3_pi_2(i64 %i) {
171 ; CHECK-LABEL: @fold_strnlen_s3_pi_2(
172 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]]
173 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 2)
174 ; CHECK-NEXT:    ret i64 [[LEN]]
177   %ptr = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 %i
178   %len = call i64 @strnlen(i8* %ptr, i64 2)
179   ret i64 %len
183 ; Fold strnlen(s3 + i, 3) to min(strlen(s3) - i, 3)
185 define i64 @fold_strnlen_s3_pi_3(i64 %i) {
186 ; CHECK-LABEL: @fold_strnlen_s3_pi_3(
187 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]]
188 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 3)
189 ; CHECK-NEXT:    ret i64 [[LEN]]
192   %ptr = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 %i
193   %len = call i64 @strnlen(i8* %ptr, i64 3)
194   ret i64 %len
198 ; Fold strnlen(s3 + i, n) to min(strlen(s3) - i, n)
200 define i64 @fold_strnlen_s3_pi_n(i64 %i, i64 %n) {
201 ; CHECK-LABEL: @fold_strnlen_s3_pi_n(
202 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]]
203 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[N:%.*]])
204 ; CHECK-NEXT:    ret i64 [[LEN]]
207   %ptr = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 %i
208   %len = call i64 @strnlen(i8* %ptr, i64 %n)
209   ret i64 %len
213 ; Do not fold strnlen(s5_3 + i, 2).  The result is in [0, 2] but there's
214 ; no simple way to derive its lower bound from the offset.
216 define i64 @call_strnlen_s5_3_pi_2(i64 %i) {
217 ; CHECK-LABEL: @call_strnlen_s5_3_pi_2(
218 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i64 0, i64 [[I:%.*]]
219 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 2)
220 ; CHECK-NEXT:    ret i64 [[LEN]]
223   %ptr = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i64 0, i64 %i
224   %len = call i64 @strnlen(i8* %ptr, i64 2)
225   ret i64 %len