xref: /llvm-project/llvm/test/Transforms/InstCombine/str-int-4.ll (revision 10f315dc9c96ec2413881ab55a285e35d80def88)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; Verify that calls to strtol and strtoll are interpreted correctly even
3; in corner cases (or not folded).
4;
5; RUN: opt < %s -passes=instcombine -S | FileCheck %s
6
7declare i32 @strtol(ptr, ptr, i32)
8declare i64 @strtoll(ptr, ptr, i32)
9
10
11; All POSIX whitespace characters.
12@ws = constant [7 x i8] c"\09\0d\0a\0b\0c \00"
13
14; A negative and positive number preceded by all POSIX whitespace.
15@ws_im123 = constant [11 x i8] c"\09\0d\0a\0b\0c -123\00"
16@ws_ip234 = constant [11 x i8] c"\09\0d\0a\0b\0c +234\00"
17
18@wsplus = constant [3 x i8] c" +\00"
19@i0 = constant [3 x i8] c" 0\00"
20@i8 = constant [3 x i8] c" 8\00"
21@i9 = constant [3 x i8] c" 9\00"
22@ia = constant [3 x i8] c" a\00"
23@i08 = constant [3 x i8] c"08\00"
24@x0x = constant [3 x i8] c"0x\00"
25@wsplusws0 = constant [5 x i8] c" + 0\00"
26@i19azAZ = constant [7 x i8] c"19azAZ\00"
27@i32min = constant [13 x i8] c" -2147483648\00"
28@i32min_m1 = constant [13 x i8] c" -2147483649\00"
29@o32min = constant [15 x i8] c" +020000000000\00"
30@mo32min = constant [15 x i8] c" -020000000000\00"
31@x32min = constant [13 x i8] c" +0x80000000\00"
32@mx32min = constant [13 x i8] c" -0x80000000\00"
33
34@i32max = constant [12 x i8] c" 2147483647\00"
35@x32max = constant [12 x i8] c" 0x7fffffff\00"
36@i32max_p1 = constant [12 x i8] c" 2147483648\00"
37
38@endptr = external global ptr
39
40
41; Exercise folding calls to 32-bit strtol.
42
43define void @fold_strtol(ptr %ps) {
44; CHECK-LABEL: @fold_strtol(
45; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @ws_im123, i64 10), ptr @endptr, align 8
46; CHECK-NEXT:    store i32 -123, ptr [[PS:%.*]], align 4
47; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @ws_ip234, i64 10), ptr @endptr, align 8
48; CHECK-NEXT:    [[PS1:%.*]] = getelementptr i8, ptr [[PS]], i64 4
49; CHECK-NEXT:    store i32 234, ptr [[PS1]], align 4
50; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @i0, i64 2), ptr @endptr, align 8
51; CHECK-NEXT:    [[PS2:%.*]] = getelementptr i8, ptr [[PS]], i64 8
52; CHECK-NEXT:    store i32 0, ptr [[PS2]], align 4
53; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @i9, i64 2), ptr @endptr, align 8
54; CHECK-NEXT:    [[PS3:%.*]] = getelementptr i8, ptr [[PS]], i64 12
55; CHECK-NEXT:    store i32 9, ptr [[PS3]], align 4
56; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @ia, i64 2), ptr @endptr, align 8
57; CHECK-NEXT:    [[PS4:%.*]] = getelementptr i8, ptr [[PS]], i64 16
58; CHECK-NEXT:    store i32 10, ptr [[PS4]], align 4
59; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @i19azAZ, i64 6), ptr @endptr, align 8
60; CHECK-NEXT:    [[PS5:%.*]] = getelementptr i8, ptr [[PS]], i64 20
61; CHECK-NEXT:    store i32 76095035, ptr [[PS5]], align 4
62; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @i32min, i64 12), ptr @endptr, align 8
63; CHECK-NEXT:    [[PS6:%.*]] = getelementptr i8, ptr [[PS]], i64 24
64; CHECK-NEXT:    store i32 -2147483648, ptr [[PS6]], align 4
65; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @mo32min, i64 14), ptr @endptr, align 8
66; CHECK-NEXT:    [[PS7:%.*]] = getelementptr i8, ptr [[PS]], i64 28
67; CHECK-NEXT:    store i32 -2147483648, ptr [[PS7]], align 4
68; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @mx32min, i64 12), ptr @endptr, align 8
69; CHECK-NEXT:    [[PS8:%.*]] = getelementptr i8, ptr [[PS]], i64 32
70; CHECK-NEXT:    store i32 -2147483648, ptr [[PS8]], align 4
71; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @mx32min, i64 12), ptr @endptr, align 8
72; CHECK-NEXT:    [[PS9:%.*]] = getelementptr i8, ptr [[PS]], i64 36
73; CHECK-NEXT:    store i32 -2147483648, ptr [[PS9]], align 4
74; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @i32max, i64 11), ptr @endptr, align 8
75; CHECK-NEXT:    [[PS10:%.*]] = getelementptr i8, ptr [[PS]], i64 40
76; CHECK-NEXT:    store i32 2147483647, ptr [[PS10]], align 4
77; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @x32max, i64 11), ptr @endptr, align 8
78; CHECK-NEXT:    [[PS11:%.*]] = getelementptr i8, ptr [[PS]], i64 44
79; CHECK-NEXT:    store i32 2147483647, ptr [[PS11]], align 4
80; CHECK-NEXT:    ret void
81;
82; Fold a valid sequence with leading POSIX whitespace and a minus to -123.
83  %im123 = call i32 @strtol(ptr @ws_im123, ptr @endptr, i32 10)
84  store i32 %im123, ptr %ps
85
86; Fold a valid sequence with leading POSIX whitespace and a plus to +234.
87  %ip234 = call i32 @strtol(ptr @ws_ip234, ptr @endptr, i32 10)
88  %ps1 = getelementptr i32, ptr %ps, i32 1
89  store i32 %ip234, ptr %ps1
90
91; Fold " 0" in base 0 to verify correct base autodetection.
92  %i0 = call i32 @strtol(ptr @i0, ptr @endptr, i32 0)
93  %ps2 = getelementptr i32, ptr %ps, i32 2
94  store i32 %i0, ptr %ps2
95
96; Fold " 9" in base 0 to verify correct base autodetection.
97  %i9 = call i32 @strtol(ptr @i9, ptr @endptr, i32 0)
98  %ps3 = getelementptr i32, ptr %ps, i32 3
99  store i32 %i9, ptr %ps3
100
101; Fold " a" in base 16 to 10.
102  %ia = call i32 @strtol(ptr @ia, ptr @endptr, i32 16)
103  %ps4 = getelementptr i32, ptr %ps, i32 4
104  store i32 %ia, ptr %ps4
105
106; Fold "19azAZ" in base 36 to 76095035.
107  %i19azAZ = call i32 @strtol(ptr @i19azAZ, ptr @endptr, i32 36)
108  %ps5 = getelementptr i32, ptr %ps, i32 5
109  store i32 %i19azAZ, ptr %ps5
110
111; Fold INT32_MIN.
112  %min = call i32 @strtol(ptr @i32min, ptr @endptr, i32 10)
113  %ps6 = getelementptr i32, ptr %ps, i32 6
114  store i32 %min, ptr %ps6
115
116; Fold -INT32_MIN in octal.
117  %mo32min = call i32 @strtol(ptr @mo32min, ptr @endptr, i32 0)
118  %ps7 = getelementptr i32, ptr %ps, i32 7
119  store i32 %mo32min, ptr %ps7
120
121; Fold -INT32_MIN in hex and base 0.
122  %mx32min_0 = call i32 @strtol(ptr @mx32min, ptr @endptr, i32 0)
123  %ps8 = getelementptr i32, ptr %ps, i32 8
124  store i32 %mx32min_0, ptr %ps8
125
126; Fold -INT32_MIN in hex and base 16.
127  %mx32min_16 = call i32 @strtol(ptr @mx32min, ptr @endptr, i32 16)
128  %ps9 = getelementptr i32, ptr %ps, i32 9
129  store i32 %mx32min_16, ptr %ps9
130
131; Fold INT32_MAX.
132  %max = call i32 @strtol(ptr @i32max, ptr @endptr, i32 10)
133  %ps10 = getelementptr i32, ptr %ps, i32 10
134  store i32 %max, ptr %ps10
135
136; Fold INT32_MAX in hex.
137  %xmax = call i32 @strtol(ptr @x32max, ptr @endptr, i32 0)
138  %ps11 = getelementptr i32, ptr %ps, i32 11
139  store i32 %xmax, ptr %ps11
140
141  ret void
142}
143
144
145; Exercise not folding calls to 32-bit strtol.
146
147define void @call_strtol(ptr %ps) {
148; CHECK-LABEL: @call_strtol(
149; CHECK-NEXT:    [[MINM1:%.*]] = call i32 @strtol(ptr nonnull @i32min_m1, ptr nonnull @endptr, i32 10)
150; CHECK-NEXT:    store i32 [[MINM1]], ptr [[PS:%.*]], align 4
151; CHECK-NEXT:    [[MAXP1:%.*]] = call i32 @strtol(ptr nonnull @i32max_p1, ptr nonnull @endptr, i32 10)
152; CHECK-NEXT:    [[PS1:%.*]] = getelementptr i8, ptr [[PS]], i64 4
153; CHECK-NEXT:    store i32 [[MAXP1]], ptr [[PS1]], align 4
154; CHECK-NEXT:    [[IPLUS:%.*]] = call i32 @strtol(ptr nonnull @wsplus, ptr nonnull @endptr, i32 0)
155; CHECK-NEXT:    [[PS2:%.*]] = getelementptr i8, ptr [[PS]], i64 8
156; CHECK-NEXT:    store i32 [[IPLUS]], ptr [[PS2]], align 4
157; CHECK-NEXT:    [[IA:%.*]] = call i32 @strtol(ptr nonnull @ia, ptr nonnull @endptr, i32 0)
158; CHECK-NEXT:    [[PS3:%.*]] = getelementptr i8, ptr [[PS]], i64 12
159; CHECK-NEXT:    store i32 [[IA]], ptr [[PS3]], align 4
160; CHECK-NEXT:    [[I8:%.*]] = call i32 @strtol(ptr nonnull @i8, ptr nonnull @endptr, i32 8)
161; CHECK-NEXT:    [[PS4:%.*]] = getelementptr i8, ptr [[PS]], i64 16
162; CHECK-NEXT:    store i32 [[I8]], ptr [[PS4]], align 4
163; CHECK-NEXT:    [[I0X:%.*]] = call i32 @strtol(ptr nonnull @x0x, ptr nonnull @endptr, i32 0)
164; CHECK-NEXT:    [[PS5:%.*]] = getelementptr i8, ptr [[PS]], i64 20
165; CHECK-NEXT:    store i32 [[I0X]], ptr [[PS5]], align 4
166; CHECK-NEXT:    [[IWSPWS0:%.*]] = call i32 @strtol(ptr nonnull @wsplusws0, ptr nonnull @endptr, i32 0)
167; CHECK-NEXT:    [[PS6:%.*]] = getelementptr i8, ptr [[PS]], i64 24
168; CHECK-NEXT:    store i32 [[IWSPWS0]], ptr [[PS6]], align 4
169; CHECK-NEXT:    [[I19AZAZ:%.*]] = call i32 @strtol(ptr nonnull @i19azAZ, ptr nonnull @endptr, i32 35)
170; CHECK-NEXT:    [[PS7:%.*]] = getelementptr i8, ptr [[PS]], i64 28
171; CHECK-NEXT:    store i32 [[I19AZAZ]], ptr [[PS7]], align 4
172; CHECK-NEXT:    [[O32MIN:%.*]] = call i32 @strtol(ptr nonnull @o32min, ptr nonnull @endptr, i32 0)
173; CHECK-NEXT:    [[PS8:%.*]] = getelementptr i8, ptr [[PS]], i64 32
174; CHECK-NEXT:    store i32 [[O32MIN]], ptr [[PS8]], align 4
175; CHECK-NEXT:    [[X32MIN:%.*]] = call i32 @strtol(ptr nonnull @x32min, ptr nonnull @endptr, i32 0)
176; CHECK-NEXT:    [[PS9:%.*]] = getelementptr i8, ptr [[PS]], i64 36
177; CHECK-NEXT:    store i32 [[X32MIN]], ptr [[PS9]], align 4
178; CHECK-NEXT:    [[X32MIN_10:%.*]] = call i32 @strtol(ptr nonnull @x32min, ptr nonnull @endptr, i32 10)
179; CHECK-NEXT:    [[PS10:%.*]] = getelementptr i8, ptr [[PS]], i64 40
180; CHECK-NEXT:    store i32 [[X32MIN_10]], ptr [[PS10]], align 4
181; CHECK-NEXT:    [[NWS:%.*]] = call i32 @strtol(ptr nonnull @ws, ptr nonnull @endptr, i32 10)
182; CHECK-NEXT:    [[PS11:%.*]] = getelementptr i8, ptr [[PS]], i64 44
183; CHECK-NEXT:    store i32 [[NWS]], ptr [[PS11]], align 4
184; CHECK-NEXT:    [[NWSP6:%.*]] = call i32 @strtol(ptr nonnull getelementptr inbounds nuw (i8, ptr @ws, i64 6), ptr nonnull @endptr, i32 10)
185; CHECK-NEXT:    [[PS12:%.*]] = getelementptr i8, ptr [[PS]], i64 48
186; CHECK-NEXT:    store i32 [[NWSP6]], ptr [[PS12]], align 4
187; CHECK-NEXT:    [[I0B1:%.*]] = call i32 @strtol(ptr nonnull @i0, ptr nonnull @endptr, i32 1)
188; CHECK-NEXT:    [[PS13:%.*]] = getelementptr i8, ptr [[PS]], i64 52
189; CHECK-NEXT:    store i32 [[I0B1]], ptr [[PS13]], align 4
190; CHECK-NEXT:    [[I0B256:%.*]] = call i32 @strtol(ptr nonnull @i0, ptr nonnull @endptr, i32 256)
191; CHECK-NEXT:    [[PS14:%.*]] = getelementptr i8, ptr [[PS]], i64 56
192; CHECK-NEXT:    store i32 [[I0B256]], ptr [[PS14]], align 4
193; CHECK-NEXT:    ret void
194;
195
196; Do not fold the result of conversion that's less than INT32_MIN.
197  %minm1 = call i32 @strtol(ptr @i32min_m1, ptr @endptr, i32 10)
198  store i32 %minm1, ptr %ps
199
200; Do not fold the result of conversion that's greater than INT32_MAX.
201  %maxp1 = call i32 @strtol(ptr @i32max_p1, ptr @endptr, i32 10)
202  %ps1 = getelementptr i32, ptr %ps, i32 1
203  store i32 %maxp1, ptr %ps1
204
205; Do not fold " +".
206  %iplus = call i32 @strtol(ptr @wsplus, ptr @endptr, i32 0)
207  %ps2 = getelementptr i32, ptr %ps, i32 2
208  store i32 %iplus, ptr %ps2
209
210; Do not fold " a" in base 0.
211  %ia = call i32 @strtol(ptr @ia, ptr @endptr, i32 0)
212  %ps3 = getelementptr i32, ptr %ps, i32 3
213  store i32 %ia, ptr %ps3
214
215; Do not fold " 8" in base 8.
216  %i8 = call i32 @strtol(ptr @i8, ptr @endptr, i32 8)
217  %ps4 = getelementptr i32, ptr %ps, i32 4
218  store i32 %i8, ptr %ps4
219
220; Do not fold the "0x" alone in base 0 that some implementations (e.g.,
221; BSD and Darwin) set errno to EINVAL for.
222  %i0x = call i32 @strtol(ptr @x0x, ptr @endptr, i32 0)
223  %ps5 = getelementptr i32, ptr %ps, i32 5
224  store i32 %i0x, ptr %ps5
225
226; Do not fold " + 0".
227  %iwspws0 = call i32 @strtol(ptr @wsplusws0, ptr @endptr, i32 0)
228  %ps6 = getelementptr i32, ptr %ps, i32 6
229  store i32 %iwspws0, ptr %ps6
230
231; Do not fold "19azAZ" in base 35.
232  %i19azAZ = call i32 @strtol(ptr @i19azAZ, ptr @endptr, i32 35)
233  %ps7 = getelementptr i32, ptr %ps, i32 7
234  store i32 %i19azAZ, ptr %ps7
235
236; Do not fold INT32_MIN in octal.
237  %o32min = call i32 @strtol(ptr @o32min, ptr @endptr, i32 0)
238  %ps8 = getelementptr i32, ptr %ps, i32 8
239  store i32 %o32min, ptr %ps8
240
241; Do not fold INT32_MIN in hex.
242  %x32min = call i32 @strtol(ptr @x32min, ptr @endptr, i32 0)
243  %ps9 = getelementptr i32, ptr %ps, i32 9
244  store i32 %x32min, ptr %ps9
245
246; Do not fold INT32_MIN in hex in base 10.
247  %x32min_10 = call i32 @strtol(ptr @x32min, ptr @endptr, i32 10)
248  %ps10 = getelementptr i32, ptr %ps, i32 10
249  store i32 %x32min_10, ptr %ps10
250
251; Do not fold a sequence consisting of just whitespace characters.
252  %nws = call i32 @strtol(ptr @ws, ptr @endptr, i32 10)
253  %ps11 = getelementptr i32, ptr %ps, i32 11
254  store i32 %nws, ptr %ps11
255
256; Do not fold an empty sequence.
257  %pswsp6 = getelementptr [7 x i8], ptr @ws, i32 0, i32 6
258  %nwsp6 = call i32 @strtol(ptr %pswsp6, ptr @endptr, i32 10)
259  %ps12 = getelementptr i32, ptr %ps, i32 12
260  store i32 %nwsp6, ptr %ps12
261
262; Do not fold the invalid base 1.
263  %i0b1 = call i32 @strtol(ptr @i0, ptr @endptr, i32 1)
264  %ps13 = getelementptr i32, ptr %ps, i32 13
265  store i32 %i0b1, ptr %ps13
266
267; Do not fold the invalid base 256.
268  %i0b256 = call i32 @strtol(ptr @i0, ptr @endptr, i32 256)
269  %ps14 = getelementptr i32, ptr %ps, i32 14
270  store i32 %i0b256, ptr %ps14
271
272  ret void
273}
274
275
276@i64min = constant [22 x i8] c" -9223372036854775808\00"
277@i64min_m1 = constant [22 x i8] c" -9223372036854775809\00"
278
279@i64max = constant [21 x i8] c" 9223372036854775807\00"
280@i64max_p1 = constant [21 x i8] c" 9223372036854775808\00"
281
282@ui64max = constant [22 x i8] c" 18446744073709551615\00"
283@ui64max_p1 = constant [22 x i8] c" 18446744073709551616\00"
284
285
286; Exercise folding calls to the 64-bit strtoll.
287
288define void @fold_strtoll(ptr %ps) {
289; CHECK-LABEL: @fold_strtoll(
290; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @ws_im123, i64 10), ptr @endptr, align 8
291; CHECK-NEXT:    store i64 -123, ptr [[PS:%.*]], align 4
292; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @ws_ip234, i64 10), ptr @endptr, align 8
293; CHECK-NEXT:    [[PS1:%.*]] = getelementptr i8, ptr [[PS]], i64 8
294; CHECK-NEXT:    store i64 234, ptr [[PS1]], align 4
295; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @i64min, i64 21), ptr @endptr, align 8
296; CHECK-NEXT:    [[PS2:%.*]] = getelementptr i8, ptr [[PS]], i64 16
297; CHECK-NEXT:    store i64 -9223372036854775808, ptr [[PS2]], align 4
298; CHECK-NEXT:    store ptr getelementptr inbounds nuw (i8, ptr @i64max, i64 20), ptr @endptr, align 8
299; CHECK-NEXT:    [[PS3:%.*]] = getelementptr i8, ptr [[PS]], i64 24
300; CHECK-NEXT:    store i64 9223372036854775807, ptr [[PS3]], align 4
301; CHECK-NEXT:    ret void
302;
303; Fold a valid sequence with leading POSIX whitespace and a minus to -123.
304  %im123 = call i64 @strtoll(ptr @ws_im123, ptr @endptr, i32 10)
305  store i64 %im123, ptr %ps
306
307; Fold a valid sequence with leading POSIX whitespace and a plus to +234.
308  %ip234 = call i64 @strtoll(ptr @ws_ip234, ptr @endptr, i32 10)
309  %ps1 = getelementptr i64, ptr %ps, i32 1
310  store i64 %ip234, ptr %ps1
311
312; Fold INT64_MIN.
313  %min = call i64 @strtoll(ptr @i64min, ptr @endptr, i32 10)
314  %ps2 = getelementptr i64, ptr %ps, i32 2
315  store i64 %min, ptr %ps2
316
317; Fold INT64_MAX.
318  %max = call i64 @strtoll(ptr @i64max, ptr @endptr, i32 10)
319  %ps3 = getelementptr i64, ptr %ps, i32 3
320  store i64 %max, ptr %ps3
321
322  ret void
323}
324
325
326; Exercise not folding calls to the 64-bit strtoll.
327
328define void @call_strtoll(ptr %ps) {
329; CHECK-LABEL: @call_strtoll(
330; CHECK-NEXT:    [[MINM1:%.*]] = call i64 @strtoll(ptr nonnull @i64min_m1, ptr nonnull @endptr, i32 10)
331; CHECK-NEXT:    store i64 [[MINM1]], ptr [[PS:%.*]], align 4
332; CHECK-NEXT:    [[MAXP1:%.*]] = call i64 @strtoll(ptr nonnull @i64max_p1, ptr nonnull @endptr, i32 10)
333; CHECK-NEXT:    [[PS1:%.*]] = getelementptr i8, ptr [[PS]], i64 8
334; CHECK-NEXT:    store i64 [[MAXP1]], ptr [[PS1]], align 4
335; CHECK-NEXT:    [[NWS:%.*]] = call i64 @strtoll(ptr nonnull @ws, ptr nonnull @endptr, i32 10)
336; CHECK-NEXT:    [[PS2:%.*]] = getelementptr i8, ptr [[PS]], i64 16
337; CHECK-NEXT:    store i64 [[NWS]], ptr [[PS2]], align 4
338; CHECK-NEXT:    [[NWSP6:%.*]] = call i64 @strtoll(ptr nonnull getelementptr inbounds nuw (i8, ptr @ws, i64 6), ptr nonnull @endptr, i32 10)
339; CHECK-NEXT:    [[PS3:%.*]] = getelementptr i8, ptr [[PS]], i64 24
340; CHECK-NEXT:    store i64 [[NWSP6]], ptr [[PS3]], align 4
341; CHECK-NEXT:    ret void
342;
343; Do not fold the result of conversion that's less than INT64_MIN.
344  %minm1 = call i64 @strtoll(ptr @i64min_m1, ptr @endptr, i32 10)
345  store i64 %minm1, ptr %ps
346
347; Do not fold the result of conversion that's greater than INT64_MAX.
348  %maxp1 = call i64 @strtoll(ptr @i64max_p1, ptr @endptr, i32 10)
349  %ps1 = getelementptr i64, ptr %ps, i32 1
350  store i64 %maxp1, ptr %ps1
351
352; Do not fold a sequence consisting of just whitespace characters.
353  %nws = call i64 @strtoll(ptr @ws, ptr @endptr, i32 10)
354  %ps2 = getelementptr i64, ptr %ps, i32 2
355  store i64 %nws, ptr %ps2
356
357; Do not fold an empty sequence.
358  %pswsp6 = getelementptr [7 x i8], ptr @ws, i32 0, i32 6
359  %nwsp6 = call i64 @strtoll(ptr %pswsp6, ptr @endptr, i32 10)
360  %ps3 = getelementptr i64, ptr %ps, i32 3
361  store i64 %nwsp6, ptr %ps3
362
363  ret void
364}
365
366@i_1_2_3_ = constant [9 x i8] c" 1 2\09\3\0a\00";
367
368; Verify that strings of digits that are followed by whitespace are not
369; folded (the whitespace could be interpreted in locales other than C
370; as part of the leading digits, such as "123 456" is interepreted as
371; 123456 in the French locale).
372
373define void @call_strtol_trailing_space(ptr %ps) {
374; CHECK-LABEL: @call_strtol_trailing_space(
375; CHECK-NEXT:    [[N1:%.*]] = call i32 @strtol(ptr nonnull @i_1_2_3_, ptr nonnull @endptr, i32 10)
376; CHECK-NEXT:    [[PS1:%.*]] = getelementptr i8, ptr [[PS:%.*]], i64 4
377; CHECK-NEXT:    store i32 [[N1]], ptr [[PS1]], align 4
378; CHECK-NEXT:    [[N2:%.*]] = call i32 @strtol(ptr nonnull getelementptr inbounds nuw (i8, ptr @i_1_2_3_, i64 2), ptr nonnull @endptr, i32 10)
379; CHECK-NEXT:    [[PS2:%.*]] = getelementptr i8, ptr [[PS]], i64 8
380; CHECK-NEXT:    store i32 [[N2]], ptr [[PS2]], align 4
381; CHECK-NEXT:    [[N3:%.*]] = call i32 @strtol(ptr nonnull getelementptr inbounds nuw (i8, ptr @i_1_2_3_, i64 4), ptr nonnull @endptr, i32 10)
382; CHECK-NEXT:    [[PS3:%.*]] = getelementptr i8, ptr [[PS]], i64 12
383; CHECK-NEXT:    store i32 [[N3]], ptr [[PS3]], align 4
384; CHECK-NEXT:    ret void
385;
386  %n1 = call i32 @strtol(ptr @i_1_2_3_, ptr @endptr, i32 10)
387  %ps1 = getelementptr i32, ptr %ps, i32 1
388  store i32 %n1, ptr %ps1
389
390  %p2 = getelementptr [9 x i8], ptr @i_1_2_3_, i32 0, i32 2
391  %n2 = call i32 @strtol(ptr %p2, ptr @endptr, i32 10)
392  %ps2 = getelementptr i32, ptr %ps, i32 2
393  store i32 %n2, ptr %ps2
394
395  %p3 = getelementptr [9 x i8], ptr @i_1_2_3_, i32 0, i32 4
396  %n3 = call i32 @strtol(ptr %p3, ptr @endptr, i32 10)
397  %ps3 = getelementptr i32, ptr %ps, i32 3
398  store i32 %n3, ptr %ps3
399
400  ret void
401}
402