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(i8*, 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(i8* %ptr, i64 %n) {
18 ; CHECK-LABEL: @no_access_strnlen_p_n(
19 ; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR:%.*]], i64 [[N:%.*]])
20 ; CHECK-NEXT: ret i64 [[LEN]]
22 %len = call i64 @strnlen(i8* %ptr, i64 %n)
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(i8* %ptr) {
31 ; CHECK-LABEL: @access_strnlen_p_2(
32 ; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR:%.*]], i64 2)
33 ; CHECK-NEXT: ret i64 [[LEN]]
35 %len = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) %ptr, i64 2)
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(i8* %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(i8* noundef nonnull dereferenceable(1) [[PTR:%.*]], i64 [[NNZ]])
47 ; CHECK-NEXT: ret i64 [[LEN]]
50 %len = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) %ptr, i64 %nnz)
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 %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i32 0, i32 0
62 %len = call i64 @strnlen(i8* %ptr, i64 0)
67 ; Fold strnlen(ax, 1) to *ax ? 1 : 0.
69 define i64 @fold_strnlen_ax_1() {
70 ; CHECK-LABEL: @fold_strnlen_ax_1(
71 ; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), align 1
72 ; CHECK-NEXT: [[STRNLEN_CHAR0CMP_NOT:%.*]] = icmp ne i8 [[STRNLEN_CHAR0]], 0
73 ; CHECK-NEXT: [[STRNLEN_SEL:%.*]] = zext i1 [[STRNLEN_CHAR0CMP_NOT]] to i64
74 ; CHECK-NEXT: ret i64 [[STRNLEN_SEL]]
76 %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i32 0, i32 0
77 %len = call i64 @strnlen(i8* %ptr, i64 1)
82 ; Fold strnlen(s5, 0) to 0.
84 define i64 @fold_strnlen_s5_0() {
85 ; CHECK-LABEL: @fold_strnlen_s5_0(
86 ; CHECK-NEXT: ret i64 0
88 %ptr = getelementptr [6 x i8], [6 x i8]* @s5, i32 0, i32 0
89 %len = call i64 @strnlen(i8* %ptr, i64 0)
94 ; Fold strnlen(s5, 4) to 4.
96 define i64 @fold_strnlen_s5_4() {
97 ; CHECK-LABEL: @fold_strnlen_s5_4(
98 ; CHECK-NEXT: ret i64 4
100 %ptr = getelementptr [6 x i8], [6 x i8]* @s5, i32 0, i32 0
101 %len = call i64 @strnlen(i8* %ptr, i64 4)
106 ; Fold strnlen(s5, 5) to 5.
108 define i64 @fold_strnlen_s5_5() {
109 ; CHECK-LABEL: @fold_strnlen_s5_5(
110 ; CHECK-NEXT: ret i64 5
112 %ptr = getelementptr [6 x i8], [6 x i8]* @s5, i32 0, i32 0
113 %len = call i64 @strnlen(i8* %ptr, i64 5)
118 ; Fold strnlen(s5, (size_t)-1) to 5.
120 define i64 @fold_strnlen_s5_m1() {
121 ; CHECK-LABEL: @fold_strnlen_s5_m1(
122 ; CHECK-NEXT: ret i64 5
124 %ptr = getelementptr [6 x i8], [6 x i8]* @s5, i32 0, i32 0
125 %len = call i64 @strnlen(i8* %ptr, i64 -1)
130 ; Fold strnlen(s5_3 + 4, 5) to 1.
132 define i64 @fold_strnlen_s5_3_p4_5() {
133 ; CHECK-LABEL: @fold_strnlen_s5_3_p4_5(
134 ; CHECK-NEXT: ret i64 1
136 %ptr = getelementptr [9 x i8], [9 x i8]* @s5_3, i32 0, i32 4
137 %len = call i64 @strnlen(i8* %ptr, i64 5)
142 ; Fold strnlen(s5_3 + 5, 5) to 0.
144 define i64 @fold_strnlen_s5_3_p5_5() {
145 ; CHECK-LABEL: @fold_strnlen_s5_3_p5_5(
146 ; CHECK-NEXT: ret i64 0
148 %ptr = getelementptr [9 x i8], [9 x i8]* @s5_3, i32 0, i32 5
149 %len = call i64 @strnlen(i8* %ptr, i64 5)
154 ; Fold strnlen(s5_3 + 6, 5) to 3.
156 define i64 @fold_strnlen_s5_3_p6_5() {
157 ; CHECK-LABEL: @fold_strnlen_s5_3_p6_5(
158 ; CHECK-NEXT: ret i64 3
160 %ptr = getelementptr [9 x i8], [9 x i8]* @s5_3, i32 0, i32 6
161 %len = call i64 @strnlen(i8* %ptr, i64 5)