xref: /llvm-project/llvm/test/Transforms/InstCombine/strcmp-3.ll (revision 4ab40eca080965c65802710e39adbb78c4ce7bde)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; Verify that strlen calls with elements of constant arrays are folded.
3;
4; RUN: opt < %s -passes=instcombine -S | FileCheck %s
5
6declare i32 @strcmp(ptr, ptr)
7
8@a5 = constant [5 x [4 x i8]] [[4 x i8] c"123\00", [4 x i8] c"123\00", [4 x i8] c"12\00\00", [4 x i8] zeroinitializer, [4 x i8] zeroinitializer]
9
10
11; Fold strcmp(a5[0], a5[1]) to '1' - '1'.
12
13define i32 @fold_strcmp_a5i0_a5i1_to_0() {
14; CHECK-LABEL: @fold_strcmp_a5i0_a5i1_to_0(
15; CHECK-NEXT:    ret i32 0
16;
17  %q = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 1, i64 0
18
19  %cmp = call i32 @strcmp(ptr @a5, ptr %q)
20  ret i32 %cmp
21}
22
23
24; Do not fold strcmp(a5[0], a5[I]) where the index I is not constant.
25
26define i32 @call_strcmp_a5i0_a5iI(i64 %I) {
27; CHECK-LABEL: @call_strcmp_a5i0_a5iI(
28; CHECK-NEXT:    [[Q:%.*]] = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 [[I:%.*]], i64 0
29; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(4) @a5, ptr noundef nonnull dereferenceable(1) [[Q]])
30; CHECK-NEXT:    ret i32 [[CMP]]
31;
32  %q = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 %I, i64 0
33
34  %cmp = call i32 @strcmp(ptr @a5, ptr %q)
35  ret i32 %cmp
36}
37
38
39; Same as above but for strcmp(a5[I], a5[0]).
40
41define i32 @call_strcmp_a5iI_a5i0(i64 %I) {
42; CHECK-LABEL: @call_strcmp_a5iI_a5i0(
43; CHECK-NEXT:    [[P:%.*]] = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 [[I:%.*]], i64 0
44; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[P]], ptr noundef nonnull dereferenceable(4) @a5)
45; CHECK-NEXT:    ret i32 [[CMP]]
46;
47  %p = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 %I, i64 0
48
49  %cmp = call i32 @strcmp(ptr %p, ptr @a5)
50  ret i32 %cmp
51}
52
53
54; Fold strcmp(a5[0], &a5[1][1]) to '1' - '2'.
55
56define i32 @fold_strcmp_a5i0_a5i1_p1_to_0() {
57; CHECK-LABEL: @fold_strcmp_a5i0_a5i1_p1_to_0(
58; CHECK-NEXT:    ret i32 -1
59;
60  %q = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 1, i64 1
61
62  %cmp = call i32 @strcmp(ptr @a5, ptr %q)
63  ret i32 %cmp
64}
65
66
67; Do not fold strcmp(a5[0], &a5[1][I]) when the index I is not constant.
68
69define i32 @call_strcmp_a5i0_a5i1_pI(i64 %I) {
70; CHECK-LABEL: @call_strcmp_a5i0_a5i1_pI(
71; CHECK-NEXT:    [[Q:%.*]] = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 1, i64 [[I:%.*]]
72; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(4) @a5, ptr noundef nonnull dereferenceable(1) [[Q]])
73; CHECK-NEXT:    ret i32 [[CMP]]
74;
75  %q = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 1, i64 %I
76
77  %cmp = call i32 @strcmp(ptr @a5, ptr %q)
78  ret i32 %cmp
79}
80
81
82; Fold strcmp(&a5[0][1], a5[1]) to '2' - '1'.
83
84define i32 @fold_strcmp_a5i0_p1_a5i1_to_0() {
85; CHECK-LABEL: @fold_strcmp_a5i0_p1_a5i1_to_0(
86; CHECK-NEXT:    ret i32 1
87;
88  %p = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 0, i64 1
89  %q = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 1, i64 0
90
91  %cmp = call i32 @strcmp(ptr %p, ptr %q)
92  ret i32 %cmp
93}
94
95
96; Fold strcmp(a5[0], a5[2]) to a5[0][2] - a5[2][2] or 1.
97
98define i32 @fold_strcmp_a5i0_a5i2_to_0() {
99; CHECK-LABEL: @fold_strcmp_a5i0_a5i2_to_0(
100; CHECK-NEXT:    ret i32 1
101;
102  %q = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 2, i64 0
103
104  %cmp = call i32 @strcmp(ptr @a5, ptr %q)
105  ret i32 %cmp
106}
107
108
109; Fold strcmp(a5[2], a5[0]) to a5[0][2] - a5[2][2] or 1.
110
111define i32 @fold_strcmp_a5i2_a5i0_to_m1() {
112; CHECK-LABEL: @fold_strcmp_a5i2_a5i0_to_m1(
113; CHECK-NEXT:    ret i32 -1
114;
115  %q = getelementptr [5 x [4 x i8]], ptr @a5, i64 0, i64 2, i64 0
116
117  %cmp = call i32 @strcmp(ptr %q, ptr @a5)
118  ret i32 %cmp
119}
120