Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / strnlen-1.ll
blob9cf4efe542eace4a0fc76a88a59188ed3df3a634
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; Verify that strnlen calls with constant string arguments and offsets
3 ; and constant bounds are folded correctly.
5 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
7 declare i64 @strnlen(ptr, i64)
9 @ax = external global [0 x i8]
10 @s5 = constant [6 x i8] c"12345\00"
11 @s5_3 = constant [9 x i8] c"12345\00xyz"
14 ; Verify that the strnlen pointer argument is not annotated nonnull when
15 ; nothing is known about the bound.
17 define i64 @no_access_strnlen_p_n(ptr %ptr, i64 %n) {
18 ; CHECK-LABEL: @no_access_strnlen_p_n(
19 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(ptr [[PTR:%.*]], i64 [[N:%.*]])
20 ; CHECK-NEXT:    ret i64 [[LEN]]
22   %len = call i64 @strnlen(ptr %ptr, i64 %n)
23   ret i64 %len
27 ; Verify that the strnlen pointer argument is annotated dereferenceable(1)
28 ; (and not more) when the constant bound is greater than 1.
30 define i64 @access_strnlen_p_2(ptr %ptr) {
31 ; CHECK-LABEL: @access_strnlen_p_2(
32 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) [[PTR:%.*]], i64 2)
33 ; CHECK-NEXT:    ret i64 [[LEN]]
35   %len = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %ptr, i64 2)
36   ret i64 %len
40 ; Verify that the strnlen pointer argument is annotated nonnull etc.,
41 ; when the bound is known to be nonzero.
43 define i64 @access_strnlen_p_nz(ptr %ptr, i64 %n) {
44 ; CHECK-LABEL: @access_strnlen_p_nz(
45 ; CHECK-NEXT:    [[NNZ:%.*]] = or i64 [[N:%.*]], 1
46 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) [[PTR:%.*]], i64 [[NNZ]])
47 ; CHECK-NEXT:    ret i64 [[LEN]]
49   %nnz = or i64 %n, 1
50   %len = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %ptr, i64 %nnz)
51   ret i64 %len
55 ; Fold strnlen(ax, 0) to 0.
57 define i64 @fold_strnlen_ax_0() {
58 ; CHECK-LABEL: @fold_strnlen_ax_0(
59 ; CHECK-NEXT:    ret i64 0
61   %len = call i64 @strnlen(ptr @ax, i64 0)
62   ret i64 %len
66 ; Fold strnlen(ax, 1) to *ax ? 1 : 0.
68 define i64 @fold_strnlen_ax_1() {
69 ; CHECK-LABEL: @fold_strnlen_ax_1(
70 ; CHECK-NEXT:    [[STRNLEN_CHAR0:%.*]] = load i8, ptr @ax, align 1
71 ; CHECK-NEXT:    [[STRNLEN_CHAR0CMP:%.*]] = icmp ne i8 [[STRNLEN_CHAR0]], 0
72 ; CHECK-NEXT:    [[LEN:%.*]] = zext i1 [[STRNLEN_CHAR0CMP]] to i64
73 ; CHECK-NEXT:    ret i64 [[LEN]]
75   %len = call i64 @strnlen(ptr @ax, i64 1)
76   ret i64 %len
80 ; Fold strnlen(s5, 0) to 0.
82 define i64 @fold_strnlen_s5_0() {
83 ; CHECK-LABEL: @fold_strnlen_s5_0(
84 ; CHECK-NEXT:    ret i64 0
86   %len = call i64 @strnlen(ptr @s5, i64 0)
87   ret i64 %len
91 ; Fold strnlen(s5, 4) to 4.
93 define i64 @fold_strnlen_s5_4() {
94 ; CHECK-LABEL: @fold_strnlen_s5_4(
95 ; CHECK-NEXT:    ret i64 4
97   %len = call i64 @strnlen(ptr @s5, i64 4)
98   ret i64 %len
102 ; Fold strnlen(s5, 5) to 5.
104 define i64 @fold_strnlen_s5_5() {
105 ; CHECK-LABEL: @fold_strnlen_s5_5(
106 ; CHECK-NEXT:    ret i64 5
108   %len = call i64 @strnlen(ptr @s5, i64 5)
109   ret i64 %len
113 ; Fold strnlen(s5, (size_t)-1) to 5.
115 define i64 @fold_strnlen_s5_m1() {
116 ; CHECK-LABEL: @fold_strnlen_s5_m1(
117 ; CHECK-NEXT:    ret i64 5
119   %len = call i64 @strnlen(ptr @s5, i64 -1)
120   ret i64 %len
124 ; Fold strnlen(s5_3 + 4, 5) to 1.
126 define i64 @fold_strnlen_s5_3_p4_5() {
127 ; CHECK-LABEL: @fold_strnlen_s5_3_p4_5(
128 ; CHECK-NEXT:    ret i64 1
130   %ptr = getelementptr [9 x i8], ptr @s5_3, i32 0, i32 4
131   %len = call i64 @strnlen(ptr %ptr, i64 5)
132   ret i64 %len
136 ; Fold strnlen(s5_3 + 5, 5) to 0.
138 define i64 @fold_strnlen_s5_3_p5_5() {
139 ; CHECK-LABEL: @fold_strnlen_s5_3_p5_5(
140 ; CHECK-NEXT:    ret i64 0
142   %ptr = getelementptr [9 x i8], ptr @s5_3, i32 0, i32 5
143   %len = call i64 @strnlen(ptr %ptr, i64 5)
144   ret i64 %len
148 ; Fold strnlen(s5_3 + 6, 3) to 3.
150 define i64 @fold_strnlen_s5_3_p6_3() {
151 ; CHECK-LABEL: @fold_strnlen_s5_3_p6_3(
152 ; CHECK-NEXT:    ret i64 3
154   %ptr = getelementptr [9 x i8], ptr @s5_3, i32 0, i32 6
155   %len = call i64 @strnlen(ptr %ptr, i64 3)
156   ret i64 %len
160 ; Fold even the invalid strnlen(s5_3 + 6, 4) call where the bound exceeds
161 ; the number of characters in the array.  This is arguably safer than
162 ; making the library call (although the low bound makes it unlikely that
163 ; the call would misbehave).
165 define i64 @call_strnlen_s5_3_p6_4() {
166 ; CHECK-LABEL: @call_strnlen_s5_3_p6_4(
167 ; CHECK-NEXT:    ret i64 3
169   %ptr = getelementptr [9 x i8], ptr @s5_3, i32 0, i32 6
170   %len = call i64 @strnlen(ptr %ptr, i64 4)
171   ret i64 %len