Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / memcmp-5.ll
blob591131cdb79076f40e35d8b5c386a8df89d4fd55
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; Exercise folding of memcmp calls with constant arrays and nonconstant
5 ; sizes.
7 declare i32 @memcmp(ptr, ptr, i64)
9 @ax = external constant [8 x i8]
10 @a01230123 = constant [8 x i8] c"01230123"
11 @b01230123 = constant [8 x i8] c"01230123"
12 @c01230129 = constant [8 x i8] c"01230129"
13 @d9123012  = constant [7 x i8] c"9123012"
16 ; Exercise memcmp(A, B, N) folding of arrays with the same bytes.
18 define void @fold_memcmp_a_b_n(ptr %pcmp, i64 %n) {
19 ; CHECK-LABEL: @fold_memcmp_a_b_n(
20 ; CHECK-NEXT:    store i32 0, ptr [[PCMP:%.*]], align 4
21 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[N:%.*]], 0
22 ; CHECK-NEXT:    [[C0_1:%.*]] = sext i1 [[TMP1]] to i32
23 ; CHECK-NEXT:    [[S0_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1
24 ; CHECK-NEXT:    store i32 [[C0_1]], ptr [[S0_1]], align 4
25 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[N]], 0
26 ; CHECK-NEXT:    [[C0_2:%.*]] = sext i1 [[TMP2]] to i32
27 ; CHECK-NEXT:    [[S0_2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2
28 ; CHECK-NEXT:    store i32 [[C0_2]], ptr [[S0_2]], align 4
29 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i64 [[N]], 0
30 ; CHECK-NEXT:    [[C0_3:%.*]] = sext i1 [[TMP3]] to i32
31 ; CHECK-NEXT:    [[S0_3:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3
32 ; CHECK-NEXT:    store i32 [[C0_3]], ptr [[S0_3]], align 4
33 ; CHECK-NEXT:    [[S0_4:%.*]] = getelementptr i32, ptr [[PCMP]], i64 4
34 ; CHECK-NEXT:    store i32 0, ptr [[S0_4]], align 4
35 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne i64 [[N]], 0
36 ; CHECK-NEXT:    [[C0_5:%.*]] = sext i1 [[TMP4]] to i32
37 ; CHECK-NEXT:    [[S0_5:%.*]] = getelementptr i32, ptr [[PCMP]], i64 5
38 ; CHECK-NEXT:    store i32 [[C0_5]], ptr [[S0_5]], align 4
39 ; CHECK-NEXT:    ret void
43   %q1 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 1
44   %q2 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 2
45   %q3 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 3
46   %q4 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 4
47   %q5 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 5
49   ; Fold memcmp(a, b, n) to 0.
50   %c0_0 = call i32 @memcmp(ptr @a01230123, ptr @b01230123, i64 %n)
51   store i32 %c0_0, ptr %pcmp
53   ; Fold memcmp(a, b + 1, n) to N != 0 ? -1 : 0.
54   %c0_1 = call i32 @memcmp(ptr @a01230123, ptr %q1, i64 %n)
55   %s0_1 = getelementptr i32, ptr %pcmp, i64 1
56   store i32 %c0_1, ptr %s0_1
58   ; Fold memcmp(a, b + 2, n) to N != 0 ? -1 : 0.
59   %c0_2 = call i32 @memcmp(ptr @a01230123, ptr %q2, i64 %n)
60   %s0_2 = getelementptr i32, ptr %pcmp, i64 2
61   store i32 %c0_2, ptr %s0_2
63   ; Fold memcmp(a, b + 3, n) to N != 0 ? -1 : 0.
64   %c0_3 = call i32 @memcmp(ptr @a01230123, ptr %q3, i64 %n)
65   %s0_3 = getelementptr i32, ptr %pcmp, i64 3
66   store i32 %c0_3, ptr %s0_3
68   ; Fold memcmp(a, b + 4, n) to 0.
69   %c0_4 = call i32 @memcmp(ptr @a01230123, ptr %q4, i64 %n)
70   %s0_4 = getelementptr i32, ptr %pcmp, i64 4
71   store i32 %c0_4, ptr %s0_4
73   ; Fold memcmp(a, b + 5, n) to N != 0 ? -1 : 0.
74   %c0_5 = call i32 @memcmp(ptr @a01230123, ptr %q5, i64 %n)
75   %s0_5 = getelementptr i32, ptr %pcmp, i64 5
76   store i32 %c0_5, ptr %s0_5
78   ret void
81 ; Vefify that a memcmp() call involving a constant array with unknown
82 ; contents is not folded.
84 define void @call_memcmp_a_ax_n(ptr %pcmp, i64 %n) {
85 ; CHECK-LABEL: @call_memcmp_a_ax_n(
86 ; CHECK-NEXT:    [[C0_0:%.*]] = call i32 @memcmp(ptr nonnull @a01230123, ptr nonnull @ax, i64 [[N:%.*]])
87 ; CHECK-NEXT:    store i32 [[C0_0]], ptr [[PCMP:%.*]], align 4
88 ; CHECK-NEXT:    ret void
92   ; Do not fold memcmp(a, ax, n).
93   %c0_0 = call i32 @memcmp(ptr @a01230123, ptr @ax, i64 %n)
94   store i32 %c0_0, ptr %pcmp
96   ret void
100 ; Exercise memcmp(A, C, N) folding of arrays with the same leading bytes
101 ; but a difference in the trailing byte.
103 define void @fold_memcmp_a_c_n(ptr %pcmp, i64 %n) {
104 ; CHECK-LABEL: @fold_memcmp_a_c_n(
105 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i64 [[N:%.*]], 7
106 ; CHECK-NEXT:    [[C0_0:%.*]] = sext i1 [[TMP1]] to i32
107 ; CHECK-NEXT:    store i32 [[C0_0]], ptr [[PCMP:%.*]], align 4
108 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[N]], 0
109 ; CHECK-NEXT:    [[C0_1:%.*]] = sext i1 [[TMP2]] to i32
110 ; CHECK-NEXT:    [[S0_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1
111 ; CHECK-NEXT:    store i32 [[C0_1]], ptr [[S0_1]], align 4
112 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i64 [[N]], 0
113 ; CHECK-NEXT:    [[C0_2:%.*]] = sext i1 [[TMP3]] to i32
114 ; CHECK-NEXT:    [[S0_2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2
115 ; CHECK-NEXT:    store i32 [[C0_2]], ptr [[S0_2]], align 4
116 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne i64 [[N]], 0
117 ; CHECK-NEXT:    [[C0_3:%.*]] = sext i1 [[TMP4]] to i32
118 ; CHECK-NEXT:    [[S0_3:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3
119 ; CHECK-NEXT:    store i32 [[C0_3]], ptr [[S0_3]], align 4
120 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp ugt i64 [[N]], 3
121 ; CHECK-NEXT:    [[C0_4:%.*]] = sext i1 [[TMP5]] to i32
122 ; CHECK-NEXT:    [[S0_4:%.*]] = getelementptr i32, ptr [[PCMP]], i64 4
123 ; CHECK-NEXT:    store i32 [[C0_4]], ptr [[S0_4]], align 4
124 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp ugt i64 [[N]], 3
125 ; CHECK-NEXT:    [[C0_5:%.*]] = sext i1 [[TMP6]] to i32
126 ; CHECK-NEXT:    [[S0_5:%.*]] = getelementptr i32, ptr [[PCMP]], i64 5
127 ; CHECK-NEXT:    store i32 [[C0_5]], ptr [[S0_5]], align 4
128 ; CHECK-NEXT:    ret void
132   %q1 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 1
133   %q2 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 2
134   %q3 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 3
135   %q4 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 4
136   %q5 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 5
138   ; Fold memcmp(a, c, n) to N > 7 ? -1 : 0.
139   %c0_0 = call i32 @memcmp(ptr @a01230123, ptr @c01230129, i64 %n)
140   store i32 %c0_0, ptr %pcmp
142   ; Fold memcmp(a, c + 1, n) to N != 0 ? -1 : 0.
143   %c0_1 = call i32 @memcmp(ptr @a01230123, ptr %q1, i64 %n)
144   %s0_1 = getelementptr i32, ptr %pcmp, i64 1
145   store i32 %c0_1, ptr %s0_1
147   ; Fold memcmp(a, c + 2, n) to N != 0 ? -1 : 0.
148   %c0_2 = call i32 @memcmp(ptr @a01230123, ptr %q2, i64 %n)
149   %s0_2 = getelementptr i32, ptr %pcmp, i64 2
150   store i32 %c0_2, ptr %s0_2
152   ; Fold memcmp(a, c + 3, n) to N != 0 ? -1 : 0.
153   %c0_3 = call i32 @memcmp(ptr @a01230123, ptr %q3, i64 %n)
154   %s0_3 = getelementptr i32, ptr %pcmp, i64 3
155   store i32 %c0_3, ptr %s0_3
157   ; Fold memcmp(a, c + 4, n) to N > 3 ? -1 : 0.
158   %c0_4 = call i32 @memcmp(ptr @a01230123, ptr %q4, i64 %n)
159   %s0_4 = getelementptr i32, ptr %pcmp, i64 4
160   store i32 %c0_4, ptr %s0_4
162   ; Fold memcmp(a, c + 5, n) to N != 0 ? -1 : 0.
163   %c0_5 = call i32 @memcmp(ptr @a01230123, ptr %q4, i64 %n)
164   %s0_5 = getelementptr i32, ptr %pcmp, i64 5
165   store i32 %c0_5, ptr %s0_5
167   ret void
171 ; Exercise memcmp(A, D, N) folding of arrays of different sizes and
172 ; a difference in the leading byte.
174 define void @fold_memcmp_a_d_n(ptr %pcmp, i64 %n) {
175 ; CHECK-LABEL: @fold_memcmp_a_d_n(
176 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[N:%.*]], 0
177 ; CHECK-NEXT:    [[C0_0:%.*]] = sext i1 [[TMP1]] to i32
178 ; CHECK-NEXT:    store i32 [[C0_0]], ptr [[PCMP:%.*]], align 4
179 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[N]], 0
180 ; CHECK-NEXT:    [[C0_1:%.*]] = sext i1 [[TMP2]] to i32
181 ; CHECK-NEXT:    [[S0_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1
182 ; CHECK-NEXT:    store i32 [[C0_1]], ptr [[S0_1]], align 4
183 ; CHECK-NEXT:    [[S1_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2
184 ; CHECK-NEXT:    store i32 0, ptr [[S1_1]], align 4
185 ; CHECK-NEXT:    [[S6_6:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3
186 ; CHECK-NEXT:    store i32 0, ptr [[S6_6]], align 4
187 ; CHECK-NEXT:    ret void
190   %p1 = getelementptr [8 x i8], ptr @a01230123, i64 0, i64 1
191   %p6 = getelementptr [8 x i8], ptr @a01230123, i64 0, i64 6
193   %q1 = getelementptr [7 x i8], ptr @d9123012, i64 0, i64 1
194   %q6 = getelementptr [7 x i8], ptr @d9123012, i64 0, i64 6
196   ; Fold memcmp(a, d, n) to N != 0 ? -1 : 0.
197   %c0_0 = call i32 @memcmp(ptr @a01230123, ptr @d9123012, i64 %n)
198   store i32 %c0_0, ptr %pcmp
200   ; Fold memcmp(a, d + 1, n) to N != 0 -1 : 0.
201   %c0_1 = call i32 @memcmp(ptr @a01230123, ptr %q1, i64 %n)
202   %s0_1 = getelementptr i32, ptr %pcmp, i64 1
203   store i32 %c0_1, ptr %s0_1
205   ; Fold memcmp(a + 1, d + 1, n) to 0.
206   %c1_1 = call i32 @memcmp(ptr %p1, ptr %q1, i64 %n)
207   %s1_1 = getelementptr i32, ptr %pcmp, i64 2
208   store i32 %c1_1, ptr %s1_1
210   ; Fold memcmp(a + 6, d + 6, n) to 0.
211   %c6_6 = call i32 @memcmp(ptr %p6, ptr %q6, i64 %n)
212   %s6_6 = getelementptr i32, ptr %pcmp, i64 3
213   store i32 %c6_6, ptr %s6_6
215   ret void
219 ; Exercise memcmp(A, D, N) folding of arrays with the same bytes and
220 ; a nonzero size.
222 define void @fold_memcmp_a_d_nz(ptr %pcmp, i64 %n) {
223 ; CHECK-LABEL: @fold_memcmp_a_d_nz(
224 ; CHECK-NEXT:    store i32 -1, ptr [[PCMP:%.*]], align 4
225 ; CHECK-NEXT:    ret void
228   %nz = or i64 %n, 1
230   %c0_0 = call i32 @memcmp(ptr @a01230123, ptr @d9123012, i64 %nz)
231   store i32 %c0_0, ptr %pcmp
233   ret void