[SLP] Add cost model for `llvm.powi.*` intrinsics
[llvm-project.git] / llvm / test / Transforms / InstCombine / strnlen-2.ll
blob2c16d85f3fb98033a42b4a59c11c13eac3fdfd69
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; Verify that strnlen calls with conditional expressions involving constant
3 ; string arguments and constant bounds are folded correctly.
5 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
7 declare i64 @strnlen(i8*, i64)
9 @s3 = constant [4 x i8] c"123\00"
10 @s5 = constant [6 x i8] c"12345\00"
11 @s5_3 = constant [10 x i8] c"12345\00678\00"
12 @s6 = constant [7 x i8] c"123456\00"
13 @s7 = constant [8 x i8] c"1234567\00"
16 ; Fold strnlen (C ? s3 : s5, 0) to 0.
18 define i64 @fold_strnlen_s3_s5_0(i1 %C) {
19 ; CHECK-LABEL: @fold_strnlen_s3_s5_0(
20 ; CHECK-NEXT:    ret i64 0
22   %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
24   %len = call i64 @strnlen(i8* %ptr, i64 0)
25   ret i64 %len
29 ; Fold strnlen (C ? s3 : s5, 1) to 1.
31 define i64 @fold_strnlen_s3_s5_1(i1 %C) {
32 ; CHECK-LABEL: @fold_strnlen_s3_s5_1(
33 ; CHECK-NEXT:    ret i64 1
35   %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
37   %len = call i64 @strnlen(i8* %ptr, i64 1)
38   ret i64 %len
42 ; Fold strnlen (C ? s3 : s5, 3) to 3.
44 define i64 @fold_strnlen_s3_s5_3(i1 %C) {
45 ; CHECK-LABEL: @fold_strnlen_s3_s5_3(
46 ; CHECK-NEXT:    [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
47 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 3)
48 ; CHECK-NEXT:    ret i64 [[LEN]]
50   %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
52   %len = call i64 @strnlen(i8* %ptr, i64 3)
53   ret i64 %len
57 ; Fold strnlen (C ? s3 : s5, 4) to C ? 3 : 4.
59 define i64 @fold_strnlen_s3_s5_4(i1 %C) {
60 ; CHECK-LABEL: @fold_strnlen_s3_s5_4(
61 ; CHECK-NEXT:    [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
62 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 4)
63 ; CHECK-NEXT:    ret i64 [[LEN]]
65   %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
67   %len = call i64 @strnlen(i8* %ptr, i64 4)
68   ret i64 %len
72 ; Fold strnlen (C ? s3 : s5, 5) to C ? 3 : 5.
74 define i64 @fold_strnlen_s3_s5_5(i1 %C) {
75 ; CHECK-LABEL: @fold_strnlen_s3_s5_5(
76 ; CHECK-NEXT:    [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
77 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 5)
78 ; CHECK-NEXT:    ret i64 [[LEN]]
80   %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
82   %len = call i64 @strnlen(i8* %ptr, i64 5)
83   ret i64 %len
87 ; Fold strnlen (C ? s3 : s5, 6) to C ? 3 : 5.
89 define i64 @fold_strnlen_s5_6(i1 %C) {
90 ; CHECK-LABEL: @fold_strnlen_s5_6(
91 ; CHECK-NEXT:    [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
92 ; CHECK-NEXT:    [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 6)
93 ; CHECK-NEXT:    ret i64 [[LEN]]
96   %ptr = select i1 %C, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0)
98   %len = call i64 @strnlen(i8* %ptr, i64 6)
99   ret i64 %len
103 ; Fold strnlen(E, N) with E being two conditional expressions:
104 ;   strlen (x == 3 ? s3 : x == 5 ? s5 : s7, 4) to x == 3 ? 3 : 4.
106 define i64 @fold_strnlen_s3_s5_s7_4(i32 %X) {
107 ; CHECK-LABEL: @fold_strnlen_s3_s5_s7_4(
108 ; CHECK-NEXT:    [[X_EQ_3:%.*]] = icmp eq i32 [[X:%.*]], 3
109 ; CHECK-NEXT:    [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5
110 ; CHECK-NEXT:    [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0)
111 ; CHECK-NEXT:    [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]]
112 ; CHECK-NEXT:    [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[SEL_X_EQ_3]], i64 4)
113 ; CHECK-NEXT:    ret i64 [[LEN]]
116   %x_eq_3 = icmp eq i32 %X, 3
117   %x_eq_5 = icmp eq i32 %X, 5
118   %sel_x_eq_5 = select i1 %x_eq_5, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([8 x i8], [8 x i8]* @s7, i64 0, i64 0)
119   %sel_x_eq_3 = select i1 %x_eq_3, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* %sel_x_eq_5
120   %len = tail call i64 @strnlen(i8* %sel_x_eq_3, i64 4)
121   ret i64 %len
125 ; As above, fold strnlen(E, N) with E being two conditional expressions
126 ; but with N == 6:
127 ;   strlen (x == 3 ? s3 : x == 5 ? s5 : s7, 6) to x == 3 ? 3 : x == 5 ? 5 : 6.
129 define i64 @fold_strnlen_s3_s5_s7_6(i32 %X) {
130 ; CHECK-LABEL: @fold_strnlen_s3_s5_s7_6(
131 ; CHECK-NEXT:    [[X_EQ_3:%.*]] = icmp eq i32 [[X:%.*]], 3
132 ; CHECK-NEXT:    [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5
133 ; CHECK-NEXT:    [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0)
134 ; CHECK-NEXT:    [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]]
135 ; CHECK-NEXT:    [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[SEL_X_EQ_3]], i64 6)
136 ; CHECK-NEXT:    ret i64 [[LEN]]
139   %x_eq_3 = icmp eq i32 %X, 3
140   %x_eq_5 = icmp eq i32 %X, 5
141   %sel_x_eq_5 = select i1 %x_eq_5, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([8 x i8], [8 x i8]* @s7, i64 0, i64 0)
142   %sel_x_eq_3 = select i1 %x_eq_3, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* %sel_x_eq_5
143   %len = tail call i64 @strnlen(i8* %sel_x_eq_3, i64 6)
144   ret i64 %len
148 ; And again, fold strnlen(E, N) with E being two conditional expressions
149 ; but with N == 8:
150 ;   strlen (x == 3 ? s3 : x == 5 ? s5 : s7, 8) to x == 3 ? 3 : x == 5 ? 5 : 7.
152 define i64 @fold_strnlen_s3_s5_s7_8(i32 %X) {
153 ; CHECK-LABEL: @fold_strnlen_s3_s5_s7_8(
154 ; CHECK-NEXT:    [[X_EQ_3:%.*]] = icmp eq i32 [[X:%.*]], 3
155 ; CHECK-NEXT:    [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5
156 ; CHECK-NEXT:    [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0)
157 ; CHECK-NEXT:    [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]]
158 ; CHECK-NEXT:    [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[SEL_X_EQ_3]], i64 8)
159 ; CHECK-NEXT:    ret i64 [[LEN]]
162   %x_eq_3 = icmp eq i32 %X, 3
163   %x_eq_5 = icmp eq i32 %X, 5
164   %sel_x_eq_5 = select i1 %x_eq_5, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([8 x i8], [8 x i8]* @s7, i64 0, i64 0)
165   %sel_x_eq_3 = select i1 %x_eq_3, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* %sel_x_eq_5
166   %len = tail call i64 @strnlen(i8* %sel_x_eq_3, i64 8)
167   ret i64 %len