blob: 4c9187169e5fdb63e0ebd1a2b6ce3fcae6f0c526 [file] [log] [blame]
Andrey Turetskiy9994b882016-02-20 11:11:55 +00001; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s
Alexey Bataev7cf32472015-12-04 10:53:15 +00002
3%struct.anon1 = type { i32, i32, i32 }
4%struct.anon2 = type { i32, [32 x i32], i32 }
5
6@arr1 = external global [65 x %struct.anon1], align 16
7@arr2 = external global [65 x %struct.anon2], align 16
8
9define void @test1(i64 %x) nounwind {
10entry:
11 %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
12 %tmp = load i32, i32* %a, align 4
13 %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
14 %tmp1 = load i32, i32* %b, align 4
15 %sub = sub i32 %tmp, %tmp1
16 %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
17 %tmp2 = load i32, i32* %c, align 4
18 %add = add nsw i32 %sub, %tmp2
19 switch i32 %add, label %sw.epilog [
20 i32 1, label %sw.bb.1
21 i32 2, label %sw.bb.2
22 ]
23
24sw.bb.1: ; preds = %entry
25 store i32 111, i32* %b, align 4
26 store i32 222, i32* %c, align 4
27 br label %sw.epilog
28
29sw.bb.2: ; preds = %entry
30 store i32 333, i32* %b, align 4
31 store i32 444, i32* %c, align 4
32 br label %sw.epilog
33
34sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
35 ret void
36; CHECK-LABEL: test1:
Dan Gohman0bf3ae82016-01-22 03:57:34 +000037; CHECK: shlq $2, [[REG1:%[a-z]+]]
38; CHECK: movl arr1([[REG1]],[[REG1]],2), {{.*}}
39; CHECK: leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]]
40; CHECK: subl arr1+4([[REG1]],[[REG1]],2), {{.*}}
41; CHECK: leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]]
42; CHECK: addl arr1+8([[REG1]],[[REG1]],2), {{.*}}
Alexey Bataev7cf32472015-12-04 10:53:15 +000043; CHECK: movl ${{[1-4]+}}, ([[REG2]])
44; CHECK: movl ${{[1-4]+}}, ([[REG3]])
45; CHECK: movl ${{[1-4]+}}, ([[REG2]])
46; CHECK: movl ${{[1-4]+}}, ([[REG3]])
47}
48
49define void @test2(i64 %x) nounwind optsize {
50entry:
51 %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
52 %tmp = load i32, i32* %a, align 4
53 %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
54 %tmp1 = load i32, i32* %b, align 4
55 %sub = sub i32 %tmp, %tmp1
56 %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
57 %tmp2 = load i32, i32* %c, align 4
58 %add = add nsw i32 %sub, %tmp2
59 switch i32 %add, label %sw.epilog [
60 i32 1, label %sw.bb.1
61 i32 2, label %sw.bb.2
62 ]
63
64sw.bb.1: ; preds = %entry
65 store i32 111, i32* %b, align 4
66 store i32 222, i32* %c, align 4
67 br label %sw.epilog
68
69sw.bb.2: ; preds = %entry
70 store i32 333, i32* %b, align 4
71 store i32 444, i32* %c, align 4
72 br label %sw.epilog
73
74sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
75 ret void
76; CHECK-LABEL: test2:
Dan Gohman0bf3ae82016-01-22 03:57:34 +000077; CHECK: shlq $2, [[REG1:%[a-z]+]]
78; CHECK: leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]]
Alexey Bataev7cf32472015-12-04 10:53:15 +000079; CHECK: movl -4([[REG2]]), {{.*}}
80; CHECK: subl ([[REG2]]), {{.*}}
Dan Gohman0bf3ae82016-01-22 03:57:34 +000081; CHECK: leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]]
Alexey Bataev7cf32472015-12-04 10:53:15 +000082; CHECK: addl ([[REG3]]), {{.*}}
83; CHECK: movl ${{[1-4]+}}, ([[REG2]])
84; CHECK: movl ${{[1-4]+}}, ([[REG3]])
85; CHECK: movl ${{[1-4]+}}, ([[REG2]])
86; CHECK: movl ${{[1-4]+}}, ([[REG3]])
87}
88
89; Check that LEA optimization pass takes into account a resultant address
90; displacement when choosing a LEA instruction for replacing a redundant
91; address recalculation.
92
93define void @test3(i64 %x) nounwind optsize {
94entry:
95 %a = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 2
96 %tmp = load i32, i32* %a, align 4
97 %b = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 0
98 %tmp1 = load i32, i32* %b, align 4
99 %add = add nsw i32 %tmp, %tmp1
100 switch i32 %add, label %sw.epilog [
101 i32 1, label %sw.bb.1
102 i32 2, label %sw.bb.2
103 ]
104
105sw.bb.1: ; preds = %entry
106 store i32 111, i32* %a, align 4
107 store i32 222, i32* %b, align 4
108 br label %sw.epilog
109
110sw.bb.2: ; preds = %entry
111 store i32 333, i32* %a, align 4
112 store i32 444, i32* %b, align 4
113 br label %sw.epilog
114
115sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
116 ret void
117; CHECK-LABEL: test3:
118; CHECK: imulq {{.*}}, [[REG1:%[a-z]+]]
119; CHECK: leaq arr2+132([[REG1]]), [[REG2:%[a-z]+]]
120; CHECK: leaq arr2([[REG1]]), [[REG3:%[a-z]+]]
121
122; REG3's definition is closer to movl than REG2's, but the pass still chooses
123; REG2 because it provides the resultant address displacement fitting 1 byte.
124
125; CHECK: movl ([[REG2]]), {{.*}}
126; CHECK: addl ([[REG3]]), {{.*}}
127; CHECK: movl ${{[1-4]+}}, ([[REG2]])
128; CHECK: movl ${{[1-4]+}}, ([[REG3]])
129; CHECK: movl ${{[1-4]+}}, ([[REG2]])
130; CHECK: movl ${{[1-4]+}}, ([[REG3]])
131}
Andrey Turetskiy1ce2c992016-01-13 11:30:44 +0000132
133define void @test4(i64 %x) nounwind minsize {
134entry:
135 %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
136 %tmp = load i32, i32* %a, align 4
137 %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
138 %tmp1 = load i32, i32* %b, align 4
139 %sub = sub i32 %tmp, %tmp1
140 %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
141 %tmp2 = load i32, i32* %c, align 4
142 %add = add nsw i32 %sub, %tmp2
143 switch i32 %add, label %sw.epilog [
144 i32 1, label %sw.bb.1
145 i32 2, label %sw.bb.2
146 ]
147
148sw.bb.1: ; preds = %entry
149 store i32 111, i32* %b, align 4
150 store i32 222, i32* %c, align 4
151 br label %sw.epilog
152
153sw.bb.2: ; preds = %entry
154 store i32 333, i32* %b, align 4
155 store i32 444, i32* %c, align 4
156 br label %sw.epilog
157
158sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
159 ret void
160; CHECK-LABEL: test4:
161; CHECK: leaq arr1+4({{.*}}), [[REG2:%[a-z]+]]
162; CHECK: movl -4([[REG2]]), {{.*}}
163; CHECK: subl ([[REG2]]), {{.*}}
164; CHECK: addl 4([[REG2]]), {{.*}}
165; CHECK: movl ${{[1-4]+}}, ([[REG2]])
166; CHECK: movl ${{[1-4]+}}, 4([[REG2]])
167; CHECK: movl ${{[1-4]+}}, ([[REG2]])
168; CHECK: movl ${{[1-4]+}}, 4([[REG2]])
169}