[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / InstCombine / strnlen-5.ll
blob3866b92ab8b4a4f2b96c97a91c35bb2f4015d584
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; Verify that equality tests of strnlen calls against zero are folded
3 ; correctly.
5 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
7 declare i64 @strnlen(ptr, i64)
9 @ax = external global [0 x i8]
10 @a5 = external global [5 x i8]
11 @s5 = constant [6 x i8] c"12345\00"
14 ; Fold strnlen(ax, 0) == 0 to true.
16 define i1 @fold_strnlen_ax_0_eqz() {
17 ; CHECK-LABEL: @fold_strnlen_ax_0_eqz(
18 ; CHECK-NEXT:    ret i1 true
21   %len = tail call i64 @strnlen(ptr @ax, i64 0)
22   %eqz = icmp eq i64 %len, 0
23   ret i1 %eqz
27 ; Fold strnlen(ax, 0) > 0 to false.
29 define i1 @fold_strnlen_ax_0_gtz() {
30 ; CHECK-LABEL: @fold_strnlen_ax_0_gtz(
31 ; CHECK-NEXT:    ret i1 false
34   %len = tail call i64 @strnlen(ptr @ax, i64 0)
35   %gtz = icmp ugt i64 %len, 0
36   ret i1 %gtz
40 ; Fold strnlen(ax, 1) == 0 to *ax == 0.
42 define i1 @fold_strnlen_ax_1_eqz() {
43 ; CHECK-LABEL: @fold_strnlen_ax_1_eqz(
44 ; CHECK-NEXT:    [[CHAR0:%.*]] = load i8, ptr @ax, align 1
45 ; CHECK-NEXT:    [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0
46 ; CHECK-NEXT:    ret i1 [[EQZ]]
49   %len = tail call i64 @strnlen(ptr @ax, i64 1)
50   %eqz = icmp eq i64 %len, 0
51   ret i1 %eqz
55 ; Likewise, fold strnlen(ax, 1) < 1 to *ax == 0.
57 define i1 @fold_strnlen_ax_1_lt1() {
58 ; CHECK-LABEL: @fold_strnlen_ax_1_lt1(
59 ; CHECK-NEXT:    [[STRNLEN_CHAR0:%.*]] = load i8, ptr @ax, align 1
60 ; CHECK-NEXT:    [[STRNLEN_CHAR0CMP_NOT:%.*]] = icmp eq i8 [[STRNLEN_CHAR0]], 0
61 ; CHECK-NEXT:    ret i1 [[STRNLEN_CHAR0CMP_NOT]]
64   %len = tail call i64 @strnlen(ptr @ax, i64 1)
65   %nez = icmp ult i64 %len, 1
66   ret i1 %nez
70 ; Fold strnlen(ax, 1) != 0 to *ax != 0.
72 define i1 @fold_strnlen_ax_1_neqz() {
73 ; CHECK-LABEL: @fold_strnlen_ax_1_neqz(
74 ; CHECK-NEXT:    [[CHAR0:%.*]] = load i8, ptr @ax, align 1
75 ; CHECK-NEXT:    [[NEZ:%.*]] = icmp ne i8 [[CHAR0]], 0
76 ; CHECK-NEXT:    ret i1 [[NEZ]]
79   %len = tail call i64 @strnlen(ptr @ax, i64 1)
80   %nez = icmp ne i64 %len, 0
81   ret i1 %nez
85 ; Likewise, fold strnlen(ax, 1) > 0 to *ax != 0.
87 define i1 @fold_strnlen_ax_1_gtz() {
88 ; CHECK-LABEL: @fold_strnlen_ax_1_gtz(
89 ; CHECK-NEXT:    [[STRNLEN_CHAR0:%.*]] = load i8, ptr @ax, align 1
90 ; CHECK-NEXT:    [[STRNLEN_CHAR0CMP:%.*]] = icmp ne i8 [[STRNLEN_CHAR0]], 0
91 ; CHECK-NEXT:    ret i1 [[STRNLEN_CHAR0CMP]]
94   %len = tail call i64 @strnlen(ptr @ax, i64 1)
95   %nez = icmp ugt i64 %len, 0
96   ret i1 %nez
100 ; Fold strnlen(ax, 9) == 0 to *ax == 0.
102 define i1 @fold_strnlen_ax_9_eqz() {
103 ; CHECK-LABEL: @fold_strnlen_ax_9_eqz(
104 ; CHECK-NEXT:    [[CHAR0:%.*]] = load i8, ptr @ax, align 1
105 ; CHECK-NEXT:    [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0
106 ; CHECK-NEXT:    ret i1 [[EQZ]]
109   %len = tail call i64 @strnlen(ptr @ax, i64 9)
110   %eqz = icmp eq i64 %len, 0
111   ret i1 %eqz
115 ; Do not fold strnlen(ax, n) == 0 for n that might be zero.
117 define i1 @call_strnlen_ax_n_eqz(i64 %n) {
118 ; CHECK-LABEL: @call_strnlen_ax_n_eqz(
119 ; CHECK-NEXT:    [[LEN:%.*]] = tail call i64 @strnlen(ptr nonnull @ax, i64 [[N:%.*]])
120 ; CHECK-NEXT:    [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0
121 ; CHECK-NEXT:    ret i1 [[EQZ]]
124   %len = tail call i64 @strnlen(ptr @ax, i64 %n)
125   %eqz = icmp eq i64 %len, 0
126   ret i1 %eqz
130 ; Fold strnlen(ax, n) == 0 to *ax == 0 for %0 that's not zero.
132 define i1 @fold_strnlen_ax_nz_eqz(i64 %n) {
133 ; CHECK-LABEL: @fold_strnlen_ax_nz_eqz(
134 ; CHECK-NEXT:    [[CHAR0:%.*]] = load i8, ptr @ax, align 1
135 ; CHECK-NEXT:    [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0
136 ; CHECK-NEXT:    ret i1 [[EQZ]]
139   %max = or i64 %n, 1
140   %len = tail call i64 @strnlen(ptr @ax, i64 %max)
141   %eqz = icmp eq i64 %len, 0
142   ret i1 %eqz
146 ; Fold strnlen(ax, n) > 0 to *ax != 0 for n that's not zero.
148 define i1 @fold_strnlen_ax_nz_gtz(i64 %n) {
149 ; CHECK-LABEL: @fold_strnlen_ax_nz_gtz(
150 ; CHECK-NEXT:    [[CHAR0:%.*]] = load i8, ptr @ax, align 1
151 ; CHECK-NEXT:    [[GTZ:%.*]] = icmp ne i8 [[CHAR0]], 0
152 ; CHECK-NEXT:    ret i1 [[GTZ]]
155   %max = or i64 %n, 1
156   %len = tail call i64 @strnlen(ptr @ax, i64 %max)
157   %gtz = icmp ugt i64 %len, 0
158   ret i1 %gtz
162 ; Fold strnlen(a5 + i, n) == 0 to a5[i] == 0 for a nonconstant a5
163 ; and a nonzero n.
165 define i1 @fold_strnlen_a5_pi_nz_eqz(i64 %i, i64 %n) {
166 ; CHECK-LABEL: @fold_strnlen_a5_pi_nz_eqz(
167 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [5 x i8], ptr @a5, i64 0, i64 [[I:%.*]]
168 ; CHECK-NEXT:    [[CHAR0:%.*]] = load i8, ptr [[PTR]], align 1
169 ; CHECK-NEXT:    [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0
170 ; CHECK-NEXT:    ret i1 [[EQZ]]
173   %nz = or i64 %n, 1
174   %ptr = getelementptr inbounds [5 x i8], ptr @a5, i64 0, i64 %i
175   %len = call i64 @strnlen(ptr %ptr, i64 %nz)
176   %eqz = icmp eq i64 %len, 0
177   ret i1 %eqz
181 ; Fold strnlen(s5 + i, n) == 0 for a constant s5 and nonzero n.
182 ; This is first folded to s5[i] == 0 like the above and then finally
183 ; to %0 == 5.
185 define i1 @fold_strnlen_s5_pi_nz_eqz(i64 %i, i64 %n) {
186 ; CHECK-LABEL: @fold_strnlen_s5_pi_nz_eqz(
187 ; CHECK-NEXT:    [[EQZ:%.*]] = icmp eq i64 [[I:%.*]], 5
188 ; CHECK-NEXT:    ret i1 [[EQZ]]
191   %nz = or i64 %n, 1
192   %ptr = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %i
193   %len = call i64 @strnlen(ptr %ptr, i64 %nz)
194   %eqz = icmp eq i64 %len, 0
195   ret i1 %eqz
199 ; Do not fold strnlen(s5 + i, n) for a constant s5 when n might be zero.
201 define i1 @call_strnlen_s5_pi_n_eqz(i64 %i, i64 %n) {
202 ; CHECK-LABEL: @call_strnlen_s5_pi_n_eqz(
203 ; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 [[I:%.*]]
204 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(ptr nonnull [[PTR]], i64 [[N:%.*]])
205 ; CHECK-NEXT:    [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0
206 ; CHECK-NEXT:    ret i1 [[EQZ]]
209   %ptr = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %i
210   %len = call i64 @strnlen(ptr %ptr, i64 %n)
211   %eqz = icmp eq i64 %len, 0
212   ret i1 %eqz