xref: /llvm-project/llvm/test/Transforms/InstCombine/strncmp-4.ll (revision 90ba33099cbb17e7c159e9ebc5a512037db99d6d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; Verify that strncmp calls with members of constant structs are folded.
3;
4; RUN: opt < %s -passes=instcombine -S | FileCheck %s
5
6; struct A { char a[3], b[4], c[4]; };
7%struct.A = type { [3 x i8], [4 x i8], [4 x i8] }
8
9@a = constant %struct.A { [3 x i8] c"123", [4 x i8] c"1231", [4 x i8] c"2345" }
10
11declare i32 @strncmp(ptr, ptr, i64)
12
13define void @fold_strncmp_Aa_b(ptr %pcmp) {
14; CHECK-LABEL: @fold_strncmp_Aa_b(
15; CHECK-NEXT:    store i32 0, ptr [[PCMP:%.*]], align 4
16; CHECK-NEXT:    [[PCMP1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 4
17; CHECK-NEXT:    store i32 0, ptr [[PCMP1]], align 4
18; CHECK-NEXT:    [[PCMP2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8
19; CHECK-NEXT:    store i32 0, ptr [[PCMP2]], align 4
20; CHECK-NEXT:    [[PCMP3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 12
21; CHECK-NEXT:    store i32 0, ptr [[PCMP3]], align 4
22; CHECK-NEXT:    [[PCMP4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16
23; CHECK-NEXT:    store i32 0, ptr [[PCMP4]], align 4
24; CHECK-NEXT:    [[PCMP5:%.*]] = getelementptr i8, ptr [[PCMP]], i64 20
25; CHECK-NEXT:    store i32 0, ptr [[PCMP5]], align 4
26; CHECK-NEXT:    [[PCMP6:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24
27; CHECK-NEXT:    store i32 0, ptr [[PCMP6]], align 4
28; CHECK-NEXT:    [[PCMP7:%.*]] = getelementptr i8, ptr [[PCMP]], i64 28
29; CHECK-NEXT:    store i32 -1, ptr [[PCMP7]], align 4
30; CHECK-NEXT:    [[PCMP8:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32
31; CHECK-NEXT:    store i32 -1, ptr [[PCMP8]], align 4
32; CHECK-NEXT:    [[PCMP9:%.*]] = getelementptr i8, ptr [[PCMP]], i64 36
33; CHECK-NEXT:    store i32 -1, ptr [[PCMP9]], align 4
34; CHECK-NEXT:    ret void
35;
36; p1 = a.a
37; p2 = a.b
38  %p2 = getelementptr %struct.A, ptr @a, i32 0, i32 1, i32 0
39
40; Fold strncmp(a.a = "123", a.b = "1231", 0) to 0.
41  %cmp0 = call i32 @strncmp(ptr @a, ptr %p2, i64 0)
42  store i32 %cmp0, ptr %pcmp
43
44; Fold strncmp(a.a = "123", a.b = "1231", 1) to 0.
45  %cmp1 = call i32 @strncmp(ptr @a, ptr %p2, i64 1)
46  %pcmp1 = getelementptr i32, ptr %pcmp, i64 1
47  store i32 %cmp1, ptr %pcmp1
48
49; Fold strncmp(a.a = "123", a.b = "1231", 2) to 0.
50  %cmp2 = call i32 @strncmp(ptr @a, ptr %p2, i64 2)
51  %pcmp2 = getelementptr i32, ptr %pcmp, i64 2
52  store i32 %cmp2, ptr %pcmp2
53
54; Fold strncmp(a.a = "123", a.b = "1231", 3) to 0.
55  %cmp3 = call i32 @strncmp(ptr @a, ptr %p2, i64 3)
56  %pcmp3 = getelementptr i32, ptr %pcmp, i64 3
57  store i32 %cmp3, ptr %pcmp3
58
59; Fold strncmp(a.a = "123", a.b = "1231", 4) to 0.
60; In this and the subsequent tests, reading past the end of a.a is
61; strictly undefined in C/C++ (because it forms a pointer to a distinct
62; subobject) but handling such cases as if they were well-defined is
63; simpler than trying to exclude them.
64
65  %cmp4 = call i32 @strncmp(ptr @a, ptr %p2, i64 4)
66  %pcmp4 = getelementptr i32, ptr %pcmp, i64 4
67  store i32 %cmp4, ptr %pcmp4
68
69; Fold strncmp("123", "1231" "2", 5) to 0.
70  %cmp5 = call i32 @strncmp(ptr @a, ptr %p2, i64 5)
71  %pcmp5 = getelementptr i32, ptr %pcmp, i64 5
72  store i32 %cmp5, ptr %pcmp5
73
74; Fold strncmp("123", "1231" "23", 6) to 0.
75  %cmp6 = call i32 @strncmp(ptr @a, ptr %p2, i64 6)
76  %pcmp6 = getelementptr i32, ptr %pcmp, i64 6
77  store i32 %cmp6, ptr %pcmp6
78
79; Fold strncmp("123", "1231" "2345", 7) to 1.
80  %cmp7 = call i32 @strncmp(ptr @a, ptr %p2, i64 7)
81  %pcmp7 = getelementptr i32, ptr %pcmp, i64 7
82  store i32 %cmp7, ptr %pcmp7
83
84; Fold strncmp("123", "1231" "2345", 8) to 1.
85  %cmp8 = call i32 @strncmp(ptr @a, ptr %p2, i64 8)
86  %pcmp8 = getelementptr i32, ptr %pcmp, i64 8
87  store i32 %cmp8, ptr %pcmp8
88
89; Fold strncmp("123", "1231" "2345", 9) to 1.
90  %cmp9 = call i32 @strncmp(ptr @a, ptr %p2, i64 9)
91  %pcmp9 = getelementptr i32, ptr %pcmp, i64 9
92  store i32 %cmp9, ptr %pcmp9
93
94  ret void
95}
96
97
98define void @fold_strncmp_Ab_a(ptr %pcmp) {
99; CHECK-LABEL: @fold_strncmp_Ab_a(
100; CHECK-NEXT:    store i32 0, ptr [[PCMP:%.*]], align 4
101; CHECK-NEXT:    [[PCMP1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 4
102; CHECK-NEXT:    store i32 0, ptr [[PCMP1]], align 4
103; CHECK-NEXT:    [[PCMP2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8
104; CHECK-NEXT:    store i32 0, ptr [[PCMP2]], align 4
105; CHECK-NEXT:    [[PCMP3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 12
106; CHECK-NEXT:    store i32 0, ptr [[PCMP3]], align 4
107; CHECK-NEXT:    [[PCMP4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16
108; CHECK-NEXT:    store i32 1, ptr [[PCMP4]], align 4
109; CHECK-NEXT:    [[PCMP5:%.*]] = getelementptr i8, ptr [[PCMP]], i64 20
110; CHECK-NEXT:    store i32 1, ptr [[PCMP5]], align 4
111; CHECK-NEXT:    ret void
112;
113; p1 = &a.b[3]
114  %p1 = getelementptr %struct.A, ptr @a, i32 0, i32 1, i32 3
115; p2 = &a.a
116
117; Fold strncmp(a.a = "123", &a.b[3] = "1" "2345", 0) to 0.
118  %cmp0 = call i32 @strncmp(ptr %p1, ptr @a, i64 0)
119  store i32 %cmp0, ptr %pcmp
120
121; Fold strncmp(a.a = "123", &a.b[3] = "1" "2345", 1) to 0.
122  %cmp1 = call i32 @strncmp(ptr %p1, ptr @a, i64 1)
123  %pcmp1 = getelementptr i32, ptr %pcmp, i64 1
124  store i32 %cmp1, ptr %pcmp1
125
126; Fold strncmp(a.a = "123", &a.b[3] = "1" "2345", 2) to 0.
127  %cmp2 = call i32 @strncmp(ptr %p1, ptr @a, i64 2)
128  %pcmp2 = getelementptr i32, ptr %pcmp, i64 2
129  store i32 %cmp2, ptr %pcmp2
130
131; Fold strncmp(a.a = "123", &a.b[3] = "1" "2345", 3) to 0.
132  %cmp3 = call i32 @strncmp(ptr %p1, ptr @a, i64 3)
133  %pcmp3 = getelementptr i32, ptr %pcmp, i64 3
134  store i32 %cmp3, ptr %pcmp3
135
136; Fold strncmp(a.a = "123", &a.b[3] = "1" "2345", 4) to 1.
137  %cmp4 = call i32 @strncmp(ptr %p1, ptr @a, i64 4)
138  %pcmp4 = getelementptr i32, ptr %pcmp, i64 4
139  store i32 %cmp4, ptr %pcmp4
140
141; Fold strncmp(a.a = "123", &a.b[3] = "1" "2345", 5) to 1.
142  %cmp5 = call i32 @strncmp(ptr %p1, ptr @a, i64 5)
143  %pcmp5 = getelementptr i32, ptr %pcmp, i64 5
144  store i32 %cmp5, ptr %pcmp5
145
146  ret void
147}
148