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(i8*, i8*)
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:    [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0))
16; CHECK-NEXT:    ret i32 [[CMP]]
17;
18  %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
19  %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0
20
21  %cmp = call i32 @strcmp(i8* %p, i8* %q)
22  ret i32 %cmp
23}
24
25
26; Do not fold strcmp(a5[0], a5[I]) where the index I is not constant.
27
28define i32 @call_strcmp_a5i0_a5iI(i64 %I) {
29; CHECK-LABEL: @call_strcmp_a5i0_a5iI(
30; CHECK-NEXT:    [[Q:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 [[I:%.*]], i64 0
31; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) [[Q]])
32; CHECK-NEXT:    ret i32 [[CMP]]
33;
34  %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
35  %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 %I, i64 0
36
37  %cmp = call i32 @strcmp(i8* %p, i8* %q)
38  ret i32 %cmp
39}
40
41
42; Same as above but for strcmp(a5[I], a5[0]).
43
44define i32 @call_strcmp_a5iI_a5i0(i64 %I) {
45; CHECK-LABEL: @call_strcmp_a5iI_a5i0(
46; CHECK-NEXT:    [[P:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 [[I:%.*]], i64 0
47; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) [[P]], i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0))
48; CHECK-NEXT:    ret i32 [[CMP]]
49;
50  %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 %I, i64 0
51  %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
52
53  %cmp = call i32 @strcmp(i8* %p, i8* %q)
54  ret i32 %cmp
55}
56
57
58; Fold strcmp(a5[0], &a5[1][1]) to '1' - '2'.
59
60define i32 @fold_strcmp_a5i0_a5i1_p1_to_0() {
61; CHECK-LABEL: @fold_strcmp_a5i0_a5i1_p1_to_0(
62; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 1))
63; CHECK-NEXT:    ret i32 [[CMP]]
64;
65  %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
66  %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 1
67
68  %cmp = call i32 @strcmp(i8* %p, i8* %q)
69  ret i32 %cmp
70}
71
72
73; Do not fold strcmp(a5[0], &a5[1][I]) when the index I is not constant.
74
75define i32 @call_strcmp_a5i0_a5i1_pI(i64 %I) {
76; CHECK-LABEL: @call_strcmp_a5i0_a5i1_pI(
77; CHECK-NEXT:    [[Q:%.*]] = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 [[I:%.*]]
78; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) [[Q]])
79; CHECK-NEXT:    ret i32 [[CMP]]
80;
81  %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
82  %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 %I
83
84  %cmp = call i32 @strcmp(i8* %p, i8* %q)
85  ret i32 %cmp
86}
87
88
89; Fold strcmp(&a5[0][1], a5[1]) to '2' - '1'.
90
91define i32 @fold_strcmp_a5i0_p1_a5i1_to_0() {
92; CHECK-LABEL: @fold_strcmp_a5i0_p1_a5i1_to_0(
93; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 1), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0))
94; CHECK-NEXT:    ret i32 [[CMP]]
95;
96  %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 1
97  %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 1, i64 0
98
99  %cmp = call i32 @strcmp(i8* %p, i8* %q)
100  ret i32 %cmp
101}
102
103
104; Fold strcmp(a5[0], a5[2]) to a5[0][2] - a5[2][2] or 1.
105
106define i32 @fold_strcmp_a5i0_a5i2_to_0() {
107; CHECK-LABEL: @fold_strcmp_a5i0_a5i2_to_0(
108; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0))
109; CHECK-NEXT:    ret i32 [[CMP]]
110;
111  %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
112  %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0
113
114  %cmp = call i32 @strcmp(i8* %p, i8* %q)
115  ret i32 %cmp
116}
117
118
119; Fold strcmp(a5[2], a5[0]) to a5[0][2] - a5[2][2] or 1.
120
121define i32 @fold_strcmp_a5i2_a5i0_to_m1() {
122; CHECK-LABEL: @fold_strcmp_a5i2_a5i0_to_m1(
123; CHECK-NEXT:    [[CMP:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0))
124; CHECK-NEXT:    ret i32 [[CMP]]
125;
126  %p = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 0, i64 0
127  %q = getelementptr [5 x [4 x i8]], [5 x [4 x i8]]* @a5, i64 0, i64 2, i64 0
128
129  %cmp = call i32 @strcmp(i8* %q, i8* %p)
130  ret i32 %cmp
131}
132