| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; Verify that calls to strtol and strtoll are interpreted correctly even |
| ; in corner cases (or not folded). |
| ; |
| ; RUN: opt < %s -passes=instcombine -S | FileCheck %s |
| |
| declare i32 @strtol(ptr, ptr, i32) |
| declare i64 @strtoll(ptr, ptr, i32) |
| |
| |
| ; All POSIX whitespace characters. |
| @ws = constant [7 x i8] c"\09\0d\0a\0b\0c \00" |
| |
| ; A negative and positive number preceded by all POSIX whitespace. |
| @ws_im123 = constant [11 x i8] c"\09\0d\0a\0b\0c -123\00" |
| @ws_ip234 = constant [11 x i8] c"\09\0d\0a\0b\0c +234\00" |
| |
| @wsplus = constant [3 x i8] c" +\00" |
| @i0 = constant [3 x i8] c" 0\00" |
| @i8 = constant [3 x i8] c" 8\00" |
| @i9 = constant [3 x i8] c" 9\00" |
| @ia = constant [3 x i8] c" a\00" |
| @i08 = constant [3 x i8] c"08\00" |
| @x0x = constant [3 x i8] c"0x\00" |
| @wsplusws0 = constant [5 x i8] c" + 0\00" |
| @i19azAZ = constant [7 x i8] c"19azAZ\00" |
| @i32min = constant [13 x i8] c" -2147483648\00" |
| @i32min_m1 = constant [13 x i8] c" -2147483649\00" |
| @o32min = constant [15 x i8] c" +020000000000\00" |
| @mo32min = constant [15 x i8] c" -020000000000\00" |
| @x32min = constant [13 x i8] c" +0x80000000\00" |
| @mx32min = constant [13 x i8] c" -0x80000000\00" |
| |
| @i32max = constant [12 x i8] c" 2147483647\00" |
| @x32max = constant [12 x i8] c" 0x7fffffff\00" |
| @i32max_p1 = constant [12 x i8] c" 2147483648\00" |
| |
| @endptr = external global ptr |
| |
| |
| ; Exercise folding calls to 32-bit strtol. |
| |
| define void @fold_strtol(ptr %ps) { |
| ; CHECK-LABEL: @fold_strtol( |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_im123, i64 0, i64 10), ptr @endptr, align 8 |
| ; CHECK-NEXT: store i32 -123, ptr [[PS:%.*]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_ip234, i64 0, i64 10), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, ptr [[PS]], i64 1 |
| ; CHECK-NEXT: store i32 234, ptr [[PS1]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([3 x i8], ptr @i0, i64 0, i64 2), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, ptr [[PS]], i64 2 |
| ; CHECK-NEXT: store i32 0, ptr [[PS2]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([3 x i8], ptr @i9, i64 0, i64 2), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, ptr [[PS]], i64 3 |
| ; CHECK-NEXT: store i32 9, ptr [[PS3]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([3 x i8], ptr @ia, i64 0, i64 2), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS4:%.*]] = getelementptr i32, ptr [[PS]], i64 4 |
| ; CHECK-NEXT: store i32 10, ptr [[PS4]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([7 x i8], ptr @i19azAZ, i64 0, i64 6), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS5:%.*]] = getelementptr i32, ptr [[PS]], i64 5 |
| ; CHECK-NEXT: store i32 76095035, ptr [[PS5]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @i32min, i64 0, i64 12), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS6:%.*]] = getelementptr i32, ptr [[PS]], i64 6 |
| ; CHECK-NEXT: store i32 -2147483648, ptr [[PS6]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([15 x i8], ptr @mo32min, i64 0, i64 14), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS7:%.*]] = getelementptr i32, ptr [[PS]], i64 7 |
| ; CHECK-NEXT: store i32 -2147483648, ptr [[PS7]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @mx32min, i64 0, i64 12), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS8:%.*]] = getelementptr i32, ptr [[PS]], i64 8 |
| ; CHECK-NEXT: store i32 -2147483648, ptr [[PS8]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @mx32min, i64 0, i64 12), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS9:%.*]] = getelementptr i32, ptr [[PS]], i64 9 |
| ; CHECK-NEXT: store i32 -2147483648, ptr [[PS9]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([12 x i8], ptr @i32max, i64 0, i64 11), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS10:%.*]] = getelementptr i32, ptr [[PS]], i64 10 |
| ; CHECK-NEXT: store i32 2147483647, ptr [[PS10]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([12 x i8], ptr @x32max, i64 0, i64 11), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS11:%.*]] = getelementptr i32, ptr [[PS]], i64 11 |
| ; CHECK-NEXT: store i32 2147483647, ptr [[PS11]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| ; Fold a valid sequence with leading POSIX whitespace and a minus to -123. |
| %im123 = call i32 @strtol(ptr @ws_im123, ptr @endptr, i32 10) |
| store i32 %im123, ptr %ps |
| |
| ; Fold a valid sequence with leading POSIX whitespace and a plus to +234. |
| %ip234 = call i32 @strtol(ptr @ws_ip234, ptr @endptr, i32 10) |
| %ps1 = getelementptr i32, ptr %ps, i32 1 |
| store i32 %ip234, ptr %ps1 |
| |
| ; Fold " 0" in base 0 to verify correct base autodetection. |
| %i0 = call i32 @strtol(ptr @i0, ptr @endptr, i32 0) |
| %ps2 = getelementptr i32, ptr %ps, i32 2 |
| store i32 %i0, ptr %ps2 |
| |
| ; Fold " 9" in base 0 to verify correct base autodetection. |
| %i9 = call i32 @strtol(ptr @i9, ptr @endptr, i32 0) |
| %ps3 = getelementptr i32, ptr %ps, i32 3 |
| store i32 %i9, ptr %ps3 |
| |
| ; Fold " a" in base 16 to 10. |
| %ia = call i32 @strtol(ptr @ia, ptr @endptr, i32 16) |
| %ps4 = getelementptr i32, ptr %ps, i32 4 |
| store i32 %ia, ptr %ps4 |
| |
| ; Fold "19azAZ" in base 36 to 76095035. |
| %i19azAZ = call i32 @strtol(ptr @i19azAZ, ptr @endptr, i32 36) |
| %ps5 = getelementptr i32, ptr %ps, i32 5 |
| store i32 %i19azAZ, ptr %ps5 |
| |
| ; Fold INT32_MIN. |
| %min = call i32 @strtol(ptr @i32min, ptr @endptr, i32 10) |
| %ps6 = getelementptr i32, ptr %ps, i32 6 |
| store i32 %min, ptr %ps6 |
| |
| ; Fold -INT32_MIN in octal. |
| %mo32min = call i32 @strtol(ptr @mo32min, ptr @endptr, i32 0) |
| %ps7 = getelementptr i32, ptr %ps, i32 7 |
| store i32 %mo32min, ptr %ps7 |
| |
| ; Fold -INT32_MIN in hex and base 0. |
| %mx32min_0 = call i32 @strtol(ptr @mx32min, ptr @endptr, i32 0) |
| %ps8 = getelementptr i32, ptr %ps, i32 8 |
| store i32 %mx32min_0, ptr %ps8 |
| |
| ; Fold -INT32_MIN in hex and base 16. |
| %mx32min_16 = call i32 @strtol(ptr @mx32min, ptr @endptr, i32 16) |
| %ps9 = getelementptr i32, ptr %ps, i32 9 |
| store i32 %mx32min_16, ptr %ps9 |
| |
| ; Fold INT32_MAX. |
| %max = call i32 @strtol(ptr @i32max, ptr @endptr, i32 10) |
| %ps10 = getelementptr i32, ptr %ps, i32 10 |
| store i32 %max, ptr %ps10 |
| |
| ; Fold INT32_MAX in hex. |
| %xmax = call i32 @strtol(ptr @x32max, ptr @endptr, i32 0) |
| %ps11 = getelementptr i32, ptr %ps, i32 11 |
| store i32 %xmax, ptr %ps11 |
| |
| ret void |
| } |
| |
| |
| ; Exercise not folding calls to 32-bit strtol. |
| |
| define void @call_strtol(ptr %ps) { |
| ; CHECK-LABEL: @call_strtol( |
| ; CHECK-NEXT: [[MINM1:%.*]] = call i32 @strtol(ptr nonnull @i32min_m1, ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: store i32 [[MINM1]], ptr [[PS:%.*]], align 4 |
| ; CHECK-NEXT: [[MAXP1:%.*]] = call i32 @strtol(ptr nonnull @i32max_p1, ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, ptr [[PS]], i64 1 |
| ; CHECK-NEXT: store i32 [[MAXP1]], ptr [[PS1]], align 4 |
| ; CHECK-NEXT: [[IPLUS:%.*]] = call i32 @strtol(ptr nonnull @wsplus, ptr nonnull @endptr, i32 0) |
| ; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, ptr [[PS]], i64 2 |
| ; CHECK-NEXT: store i32 [[IPLUS]], ptr [[PS2]], align 4 |
| ; CHECK-NEXT: [[IA:%.*]] = call i32 @strtol(ptr nonnull @ia, ptr nonnull @endptr, i32 0) |
| ; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, ptr [[PS]], i64 3 |
| ; CHECK-NEXT: store i32 [[IA]], ptr [[PS3]], align 4 |
| ; CHECK-NEXT: [[I8:%.*]] = call i32 @strtol(ptr nonnull @i8, ptr nonnull @endptr, i32 8) |
| ; CHECK-NEXT: [[PS4:%.*]] = getelementptr i32, ptr [[PS]], i64 4 |
| ; CHECK-NEXT: store i32 [[I8]], ptr [[PS4]], align 4 |
| ; CHECK-NEXT: [[I0X:%.*]] = call i32 @strtol(ptr nonnull @x0x, ptr nonnull @endptr, i32 0) |
| ; CHECK-NEXT: [[PS5:%.*]] = getelementptr i32, ptr [[PS]], i64 5 |
| ; CHECK-NEXT: store i32 [[I0X]], ptr [[PS5]], align 4 |
| ; CHECK-NEXT: [[IWSPWS0:%.*]] = call i32 @strtol(ptr nonnull @wsplusws0, ptr nonnull @endptr, i32 0) |
| ; CHECK-NEXT: [[PS6:%.*]] = getelementptr i32, ptr [[PS]], i64 6 |
| ; CHECK-NEXT: store i32 [[IWSPWS0]], ptr [[PS6]], align 4 |
| ; CHECK-NEXT: [[I19AZAZ:%.*]] = call i32 @strtol(ptr nonnull @i19azAZ, ptr nonnull @endptr, i32 35) |
| ; CHECK-NEXT: [[PS7:%.*]] = getelementptr i32, ptr [[PS]], i64 7 |
| ; CHECK-NEXT: store i32 [[I19AZAZ]], ptr [[PS7]], align 4 |
| ; CHECK-NEXT: [[O32MIN:%.*]] = call i32 @strtol(ptr nonnull @o32min, ptr nonnull @endptr, i32 0) |
| ; CHECK-NEXT: [[PS8:%.*]] = getelementptr i32, ptr [[PS]], i64 8 |
| ; CHECK-NEXT: store i32 [[O32MIN]], ptr [[PS8]], align 4 |
| ; CHECK-NEXT: [[X32MIN:%.*]] = call i32 @strtol(ptr nonnull @x32min, ptr nonnull @endptr, i32 0) |
| ; CHECK-NEXT: [[PS9:%.*]] = getelementptr i32, ptr [[PS]], i64 9 |
| ; CHECK-NEXT: store i32 [[X32MIN]], ptr [[PS9]], align 4 |
| ; CHECK-NEXT: [[X32MIN_10:%.*]] = call i32 @strtol(ptr nonnull @x32min, ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS10:%.*]] = getelementptr i32, ptr [[PS]], i64 10 |
| ; CHECK-NEXT: store i32 [[X32MIN_10]], ptr [[PS10]], align 4 |
| ; CHECK-NEXT: [[NWS:%.*]] = call i32 @strtol(ptr nonnull @ws, ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS11:%.*]] = getelementptr i32, ptr [[PS]], i64 11 |
| ; CHECK-NEXT: store i32 [[NWS]], ptr [[PS11]], align 4 |
| ; CHECK-NEXT: [[NWSP6:%.*]] = call i32 @strtol(ptr nonnull getelementptr inbounds ([7 x i8], ptr @ws, i64 0, i64 6), ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS12:%.*]] = getelementptr i32, ptr [[PS]], i64 12 |
| ; CHECK-NEXT: store i32 [[NWSP6]], ptr [[PS12]], align 4 |
| ; CHECK-NEXT: [[I0B1:%.*]] = call i32 @strtol(ptr nonnull @i0, ptr nonnull @endptr, i32 1) |
| ; CHECK-NEXT: [[PS13:%.*]] = getelementptr i32, ptr [[PS]], i64 13 |
| ; CHECK-NEXT: store i32 [[I0B1]], ptr [[PS13]], align 4 |
| ; CHECK-NEXT: [[I0B256:%.*]] = call i32 @strtol(ptr nonnull @i0, ptr nonnull @endptr, i32 256) |
| ; CHECK-NEXT: [[PS14:%.*]] = getelementptr i32, ptr [[PS]], i64 14 |
| ; CHECK-NEXT: store i32 [[I0B256]], ptr [[PS14]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| |
| ; Do not fold the result of conversion that's less than INT32_MIN. |
| %minm1 = call i32 @strtol(ptr @i32min_m1, ptr @endptr, i32 10) |
| store i32 %minm1, ptr %ps |
| |
| ; Do not fold the result of conversion that's greater than INT32_MAX. |
| %maxp1 = call i32 @strtol(ptr @i32max_p1, ptr @endptr, i32 10) |
| %ps1 = getelementptr i32, ptr %ps, i32 1 |
| store i32 %maxp1, ptr %ps1 |
| |
| ; Do not fold " +". |
| %iplus = call i32 @strtol(ptr @wsplus, ptr @endptr, i32 0) |
| %ps2 = getelementptr i32, ptr %ps, i32 2 |
| store i32 %iplus, ptr %ps2 |
| |
| ; Do not fold " a" in base 0. |
| %ia = call i32 @strtol(ptr @ia, ptr @endptr, i32 0) |
| %ps3 = getelementptr i32, ptr %ps, i32 3 |
| store i32 %ia, ptr %ps3 |
| |
| ; Do not fold " 8" in base 8. |
| %i8 = call i32 @strtol(ptr @i8, ptr @endptr, i32 8) |
| %ps4 = getelementptr i32, ptr %ps, i32 4 |
| store i32 %i8, ptr %ps4 |
| |
| ; Do not fold the "0x" alone in base 0 that some implementations (e.g., |
| ; BSD and Darwin) set errno to EINVAL for. |
| %i0x = call i32 @strtol(ptr @x0x, ptr @endptr, i32 0) |
| %ps5 = getelementptr i32, ptr %ps, i32 5 |
| store i32 %i0x, ptr %ps5 |
| |
| ; Do not fold " + 0". |
| %iwspws0 = call i32 @strtol(ptr @wsplusws0, ptr @endptr, i32 0) |
| %ps6 = getelementptr i32, ptr %ps, i32 6 |
| store i32 %iwspws0, ptr %ps6 |
| |
| ; Do not fold "19azAZ" in base 35. |
| %i19azAZ = call i32 @strtol(ptr @i19azAZ, ptr @endptr, i32 35) |
| %ps7 = getelementptr i32, ptr %ps, i32 7 |
| store i32 %i19azAZ, ptr %ps7 |
| |
| ; Do not fold INT32_MIN in octal. |
| %o32min = call i32 @strtol(ptr @o32min, ptr @endptr, i32 0) |
| %ps8 = getelementptr i32, ptr %ps, i32 8 |
| store i32 %o32min, ptr %ps8 |
| |
| ; Do not fold INT32_MIN in hex. |
| %x32min = call i32 @strtol(ptr @x32min, ptr @endptr, i32 0) |
| %ps9 = getelementptr i32, ptr %ps, i32 9 |
| store i32 %x32min, ptr %ps9 |
| |
| ; Do not fold INT32_MIN in hex in base 10. |
| %x32min_10 = call i32 @strtol(ptr @x32min, ptr @endptr, i32 10) |
| %ps10 = getelementptr i32, ptr %ps, i32 10 |
| store i32 %x32min_10, ptr %ps10 |
| |
| ; Do not fold a sequence consisting of just whitespace characters. |
| %nws = call i32 @strtol(ptr @ws, ptr @endptr, i32 10) |
| %ps11 = getelementptr i32, ptr %ps, i32 11 |
| store i32 %nws, ptr %ps11 |
| |
| ; Do not fold an empty sequence. |
| %pswsp6 = getelementptr [7 x i8], ptr @ws, i32 0, i32 6 |
| %nwsp6 = call i32 @strtol(ptr %pswsp6, ptr @endptr, i32 10) |
| %ps12 = getelementptr i32, ptr %ps, i32 12 |
| store i32 %nwsp6, ptr %ps12 |
| |
| ; Do not fold the invalid base 1. |
| %i0b1 = call i32 @strtol(ptr @i0, ptr @endptr, i32 1) |
| %ps13 = getelementptr i32, ptr %ps, i32 13 |
| store i32 %i0b1, ptr %ps13 |
| |
| ; Do not fold the invalid base 256. |
| %i0b256 = call i32 @strtol(ptr @i0, ptr @endptr, i32 256) |
| %ps14 = getelementptr i32, ptr %ps, i32 14 |
| store i32 %i0b256, ptr %ps14 |
| |
| ret void |
| } |
| |
| |
| @i64min = constant [22 x i8] c" -9223372036854775808\00" |
| @i64min_m1 = constant [22 x i8] c" -9223372036854775809\00" |
| |
| @i64max = constant [21 x i8] c" 9223372036854775807\00" |
| @i64max_p1 = constant [21 x i8] c" 9223372036854775808\00" |
| |
| @ui64max = constant [22 x i8] c" 18446744073709551615\00" |
| @ui64max_p1 = constant [22 x i8] c" 18446744073709551616\00" |
| |
| |
| ; Exercise folding calls to the 64-bit strtoll. |
| |
| define void @fold_strtoll(ptr %ps) { |
| ; CHECK-LABEL: @fold_strtoll( |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_im123, i64 0, i64 10), ptr @endptr, align 8 |
| ; CHECK-NEXT: store i64 -123, ptr [[PS:%.*]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_ip234, i64 0, i64 10), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, ptr [[PS]], i64 1 |
| ; CHECK-NEXT: store i64 234, ptr [[PS1]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([22 x i8], ptr @i64min, i64 0, i64 21), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, ptr [[PS]], i64 2 |
| ; CHECK-NEXT: store i64 -9223372036854775808, ptr [[PS2]], align 4 |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([21 x i8], ptr @i64max, i64 0, i64 20), ptr @endptr, align 8 |
| ; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, ptr [[PS]], i64 3 |
| ; CHECK-NEXT: store i64 9223372036854775807, ptr [[PS3]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| ; Fold a valid sequence with leading POSIX whitespace and a minus to -123. |
| %im123 = call i64 @strtoll(ptr @ws_im123, ptr @endptr, i32 10) |
| store i64 %im123, ptr %ps |
| |
| ; Fold a valid sequence with leading POSIX whitespace and a plus to +234. |
| %ip234 = call i64 @strtoll(ptr @ws_ip234, ptr @endptr, i32 10) |
| %ps1 = getelementptr i64, ptr %ps, i32 1 |
| store i64 %ip234, ptr %ps1 |
| |
| ; Fold INT64_MIN. |
| %min = call i64 @strtoll(ptr @i64min, ptr @endptr, i32 10) |
| %ps2 = getelementptr i64, ptr %ps, i32 2 |
| store i64 %min, ptr %ps2 |
| |
| ; Fold INT64_MAX. |
| %max = call i64 @strtoll(ptr @i64max, ptr @endptr, i32 10) |
| %ps3 = getelementptr i64, ptr %ps, i32 3 |
| store i64 %max, ptr %ps3 |
| |
| ret void |
| } |
| |
| |
| ; Exercise not folding calls to the 64-bit strtoll. |
| |
| define void @call_strtoll(ptr %ps) { |
| ; CHECK-LABEL: @call_strtoll( |
| ; CHECK-NEXT: [[MINM1:%.*]] = call i64 @strtoll(ptr nonnull @i64min_m1, ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: store i64 [[MINM1]], ptr [[PS:%.*]], align 4 |
| ; CHECK-NEXT: [[MAXP1:%.*]] = call i64 @strtoll(ptr nonnull @i64max_p1, ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, ptr [[PS]], i64 1 |
| ; CHECK-NEXT: store i64 [[MAXP1]], ptr [[PS1]], align 4 |
| ; CHECK-NEXT: [[NWS:%.*]] = call i64 @strtoll(ptr nonnull @ws, ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, ptr [[PS]], i64 2 |
| ; CHECK-NEXT: store i64 [[NWS]], ptr [[PS2]], align 4 |
| ; CHECK-NEXT: [[NWSP6:%.*]] = call i64 @strtoll(ptr nonnull getelementptr inbounds ([7 x i8], ptr @ws, i64 0, i64 6), ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, ptr [[PS]], i64 3 |
| ; CHECK-NEXT: store i64 [[NWSP6]], ptr [[PS3]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| ; Do not fold the result of conversion that's less than INT64_MIN. |
| %minm1 = call i64 @strtoll(ptr @i64min_m1, ptr @endptr, i32 10) |
| store i64 %minm1, ptr %ps |
| |
| ; Do not fold the result of conversion that's greater than INT64_MAX. |
| %maxp1 = call i64 @strtoll(ptr @i64max_p1, ptr @endptr, i32 10) |
| %ps1 = getelementptr i64, ptr %ps, i32 1 |
| store i64 %maxp1, ptr %ps1 |
| |
| ; Do not fold a sequence consisting of just whitespace characters. |
| %nws = call i64 @strtoll(ptr @ws, ptr @endptr, i32 10) |
| %ps2 = getelementptr i64, ptr %ps, i32 2 |
| store i64 %nws, ptr %ps2 |
| |
| ; Do not fold an empty sequence. |
| %pswsp6 = getelementptr [7 x i8], ptr @ws, i32 0, i32 6 |
| %nwsp6 = call i64 @strtoll(ptr %pswsp6, ptr @endptr, i32 10) |
| %ps3 = getelementptr i64, ptr %ps, i32 3 |
| store i64 %nwsp6, ptr %ps3 |
| |
| ret void |
| } |
| |
| @i_1_2_3_ = constant [9 x i8] c" 1 2\09\3\0a\00"; |
| |
| ; Verify that strings of digits that are followed by whitespace are not |
| ; folded (the whitespace could be interpreted in locales other than C |
| ; as part of the leading digits, such as "123 456" is interepreted as |
| ; 123456 in the French locale). |
| |
| define void @call_strtol_trailing_space(ptr %ps) { |
| ; CHECK-LABEL: @call_strtol_trailing_space( |
| ; CHECK-NEXT: [[N1:%.*]] = call i32 @strtol(ptr nonnull @i_1_2_3_, ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, ptr [[PS:%.*]], i64 1 |
| ; CHECK-NEXT: store i32 [[N1]], ptr [[PS1]], align 4 |
| ; CHECK-NEXT: [[N2:%.*]] = call i32 @strtol(ptr nonnull getelementptr inbounds ([9 x i8], ptr @i_1_2_3_, i64 0, i64 2), ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, ptr [[PS]], i64 2 |
| ; CHECK-NEXT: store i32 [[N2]], ptr [[PS2]], align 4 |
| ; CHECK-NEXT: [[N3:%.*]] = call i32 @strtol(ptr nonnull getelementptr inbounds ([9 x i8], ptr @i_1_2_3_, i64 0, i64 4), ptr nonnull @endptr, i32 10) |
| ; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, ptr [[PS]], i64 3 |
| ; CHECK-NEXT: store i32 [[N3]], ptr [[PS3]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| %n1 = call i32 @strtol(ptr @i_1_2_3_, ptr @endptr, i32 10) |
| %ps1 = getelementptr i32, ptr %ps, i32 1 |
| store i32 %n1, ptr %ps1 |
| |
| %p2 = getelementptr [9 x i8], ptr @i_1_2_3_, i32 0, i32 2 |
| %n2 = call i32 @strtol(ptr %p2, ptr @endptr, i32 10) |
| %ps2 = getelementptr i32, ptr %ps, i32 2 |
| store i32 %n2, ptr %ps2 |
| |
| %p3 = getelementptr [9 x i8], ptr @i_1_2_3_, i32 0, i32 4 |
| %n3 = call i32 @strtol(ptr %p3, ptr @endptr, i32 10) |
| %ps3 = getelementptr i32, ptr %ps, i32 3 |
| store i32 %n3, ptr %ps3 |
| |
| ret void |
| } |