blob: 9e0e34b1e09a1a7eeaaacb08d74318b22f72be7f [file] [log] [blame]
Andrey Turetskiy45b22a42016-05-19 10:18:29 +00001; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=CHECK -check-prefix=ENABLED
2; RUN: llc --disable-x86-lea-opt < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=CHECK -check-prefix=DISABLED
Alexey Bataev7cf32472015-12-04 10:53:15 +00003
4%struct.anon1 = type { i32, i32, i32 }
5%struct.anon2 = type { i32, [32 x i32], i32 }
6
7@arr1 = external global [65 x %struct.anon1], align 16
8@arr2 = external global [65 x %struct.anon2], align 16
9
10define void @test1(i64 %x) nounwind {
11entry:
12 %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
13 %tmp = load i32, i32* %a, align 4
14 %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
15 %tmp1 = load i32, i32* %b, align 4
16 %sub = sub i32 %tmp, %tmp1
17 %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
18 %tmp2 = load i32, i32* %c, align 4
19 %add = add nsw i32 %sub, %tmp2
20 switch i32 %add, label %sw.epilog [
21 i32 1, label %sw.bb.1
22 i32 2, label %sw.bb.2
23 ]
24
25sw.bb.1: ; preds = %entry
26 store i32 111, i32* %b, align 4
27 store i32 222, i32* %c, align 4
28 br label %sw.epilog
29
30sw.bb.2: ; preds = %entry
31 store i32 333, i32* %b, align 4
32 store i32 444, i32* %c, align 4
33 br label %sw.epilog
34
35sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
36 ret void
37; CHECK-LABEL: test1:
Dan Gohman0bf3ae82016-01-22 03:57:34 +000038; CHECK: shlq $2, [[REG1:%[a-z]+]]
39; CHECK: movl arr1([[REG1]],[[REG1]],2), {{.*}}
40; CHECK: leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]]
41; CHECK: subl arr1+4([[REG1]],[[REG1]],2), {{.*}}
Andrey Turetskiy45b22a42016-05-19 10:18:29 +000042; DISABLED: leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]]
Dan Gohman0bf3ae82016-01-22 03:57:34 +000043; CHECK: addl arr1+8([[REG1]],[[REG1]],2), {{.*}}
Alexey Bataev7cf32472015-12-04 10:53:15 +000044; CHECK: movl ${{[1-4]+}}, ([[REG2]])
Andrey Turetskiy45b22a42016-05-19 10:18:29 +000045; ENABLED: movl ${{[1-4]+}}, 4([[REG2]])
46; DISABLED: movl ${{[1-4]+}}, ([[REG3]])
Alexey Bataev7cf32472015-12-04 10:53:15 +000047; CHECK: movl ${{[1-4]+}}, ([[REG2]])
Andrey Turetskiy45b22a42016-05-19 10:18:29 +000048; ENABLED: movl ${{[1-4]+}}, 4([[REG2]])
49; DISABLED: movl ${{[1-4]+}}, ([[REG3]])
Alexey Bataev7cf32472015-12-04 10:53:15 +000050}
51
52define void @test2(i64 %x) nounwind optsize {
53entry:
54 %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
55 %tmp = load i32, i32* %a, align 4
56 %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
57 %tmp1 = load i32, i32* %b, align 4
58 %sub = sub i32 %tmp, %tmp1
59 %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
60 %tmp2 = load i32, i32* %c, align 4
61 %add = add nsw i32 %sub, %tmp2
62 switch i32 %add, label %sw.epilog [
63 i32 1, label %sw.bb.1
64 i32 2, label %sw.bb.2
65 ]
66
67sw.bb.1: ; preds = %entry
68 store i32 111, i32* %b, align 4
69 store i32 222, i32* %c, align 4
70 br label %sw.epilog
71
72sw.bb.2: ; preds = %entry
73 store i32 333, i32* %b, align 4
74 store i32 444, i32* %c, align 4
75 br label %sw.epilog
76
77sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
78 ret void
79; CHECK-LABEL: test2:
Dan Gohman0bf3ae82016-01-22 03:57:34 +000080; CHECK: shlq $2, [[REG1:%[a-z]+]]
Andrey Turetskiy45b22a42016-05-19 10:18:29 +000081; DISABLED: movl arr1([[REG1]],[[REG1]],2), {{.*}}
Dan Gohman0bf3ae82016-01-22 03:57:34 +000082; CHECK: leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]]
Andrey Turetskiy45b22a42016-05-19 10:18:29 +000083; ENABLED: movl -4([[REG2]]), {{.*}}
84; ENABLED: subl ([[REG2]]), {{.*}}
85; ENABLED: addl 4([[REG2]]), {{.*}}
86; DISABLED: subl arr1+4([[REG1]],[[REG1]],2), {{.*}}
87; DISABLED: leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]]
88; DISABLED: addl arr1+8([[REG1]],[[REG1]],2), {{.*}}
Alexey Bataev7cf32472015-12-04 10:53:15 +000089; CHECK: movl ${{[1-4]+}}, ([[REG2]])
Andrey Turetskiy45b22a42016-05-19 10:18:29 +000090; ENABLED: movl ${{[1-4]+}}, 4([[REG2]])
91; DISABLED: movl ${{[1-4]+}}, ([[REG3]])
Alexey Bataev7cf32472015-12-04 10:53:15 +000092; CHECK: movl ${{[1-4]+}}, ([[REG2]])
Andrey Turetskiy45b22a42016-05-19 10:18:29 +000093; ENABLED: movl ${{[1-4]+}}, 4([[REG2]])
94; DISABLED: movl ${{[1-4]+}}, ([[REG3]])
Alexey Bataev7cf32472015-12-04 10:53:15 +000095}
96
97; Check that LEA optimization pass takes into account a resultant address
98; displacement when choosing a LEA instruction for replacing a redundant
99; address recalculation.
100
101define void @test3(i64 %x) nounwind optsize {
102entry:
103 %a = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 2
104 %tmp = load i32, i32* %a, align 4
105 %b = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 0
106 %tmp1 = load i32, i32* %b, align 4
107 %add = add nsw i32 %tmp, %tmp1
108 switch i32 %add, label %sw.epilog [
109 i32 1, label %sw.bb.1
110 i32 2, label %sw.bb.2
111 ]
112
113sw.bb.1: ; preds = %entry
114 store i32 111, i32* %a, align 4
115 store i32 222, i32* %b, align 4
116 br label %sw.epilog
117
118sw.bb.2: ; preds = %entry
119 store i32 333, i32* %a, align 4
Andrey Turetskiy45b22a42016-05-19 10:18:29 +0000120 ; Make sure the REG3's definition LEA won't be removed as redundant.
121 %cvt = ptrtoint i32* %b to i32
122 store i32 %cvt, i32* %b, align 4
Alexey Bataev7cf32472015-12-04 10:53:15 +0000123 br label %sw.epilog
124
125sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
126 ret void
127; CHECK-LABEL: test3:
128; CHECK: imulq {{.*}}, [[REG1:%[a-z]+]]
129; CHECK: leaq arr2+132([[REG1]]), [[REG2:%[a-z]+]]
130; CHECK: leaq arr2([[REG1]]), [[REG3:%[a-z]+]]
131
132; REG3's definition is closer to movl than REG2's, but the pass still chooses
133; REG2 because it provides the resultant address displacement fitting 1 byte.
134
Andrey Turetskiy45b22a42016-05-19 10:18:29 +0000135; ENABLED: movl ([[REG2]]), {{.*}}
136; ENABLED: addl ([[REG3]]), {{.*}}
137; DISABLED: movl arr2+132([[REG1]]), {{.*}}
138; DISABLED: addl arr2([[REG1]]), {{.*}}
Alexey Bataev7cf32472015-12-04 10:53:15 +0000139; CHECK: movl ${{[1-4]+}}, ([[REG2]])
140; CHECK: movl ${{[1-4]+}}, ([[REG3]])
141; CHECK: movl ${{[1-4]+}}, ([[REG2]])
Andrey Turetskiy45b22a42016-05-19 10:18:29 +0000142; CHECK: movl {{.*}}, ([[REG3]])
Alexey Bataev7cf32472015-12-04 10:53:15 +0000143}
Andrey Turetskiy1ce2c992016-01-13 11:30:44 +0000144
145define void @test4(i64 %x) nounwind minsize {
146entry:
147 %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
148 %tmp = load i32, i32* %a, align 4
149 %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
150 %tmp1 = load i32, i32* %b, align 4
151 %sub = sub i32 %tmp, %tmp1
152 %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
153 %tmp2 = load i32, i32* %c, align 4
154 %add = add nsw i32 %sub, %tmp2
155 switch i32 %add, label %sw.epilog [
156 i32 1, label %sw.bb.1
157 i32 2, label %sw.bb.2
158 ]
159
160sw.bb.1: ; preds = %entry
161 store i32 111, i32* %b, align 4
162 store i32 222, i32* %c, align 4
163 br label %sw.epilog
164
165sw.bb.2: ; preds = %entry
166 store i32 333, i32* %b, align 4
167 store i32 444, i32* %c, align 4
168 br label %sw.epilog
169
170sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
171 ret void
172; CHECK-LABEL: test4:
Andrey Turetskiy45b22a42016-05-19 10:18:29 +0000173; CHECK: imulq {{.*}}, [[REG1:%[a-z]+]]
174; DISABLED: movl arr1([[REG1]]), {{.*}}
175; CHECK: leaq arr1+4([[REG1]]), [[REG2:%[a-z]+]]
176; ENABLED: movl -4([[REG2]]), {{.*}}
177; ENABLED: subl ([[REG2]]), {{.*}}
178; ENABLED: addl 4([[REG2]]), {{.*}}
179; DISABLED: subl arr1+4([[REG1]]), {{.*}}
180; DISABLED: leaq arr1+8([[REG1]]), [[REG3:%[a-z]+]]
181; DISABLED: addl arr1+8([[REG1]]), {{.*}}
Andrey Turetskiy1ce2c992016-01-13 11:30:44 +0000182; CHECK: movl ${{[1-4]+}}, ([[REG2]])
Andrey Turetskiy45b22a42016-05-19 10:18:29 +0000183; ENABLED: movl ${{[1-4]+}}, 4([[REG2]])
184; DISABLED: movl ${{[1-4]+}}, ([[REG3]])
Andrey Turetskiy1ce2c992016-01-13 11:30:44 +0000185; CHECK: movl ${{[1-4]+}}, ([[REG2]])
Andrey Turetskiy45b22a42016-05-19 10:18:29 +0000186; ENABLED: movl ${{[1-4]+}}, 4([[REG2]])
187; DISABLED: movl ${{[1-4]+}}, ([[REG3]])
Andrey Turetskiy1ce2c992016-01-13 11:30:44 +0000188}