xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/lea-opt.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=CHECK -check-prefix=ENABLED
2*9880d681SAndroid Build Coastguard Worker; RUN: llc --disable-x86-lea-opt < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=CHECK -check-prefix=DISABLED
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker%struct.anon1 = type { i32, i32, i32 }
5*9880d681SAndroid Build Coastguard Worker%struct.anon2 = type { i32, [32 x i32], i32 }
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Worker@arr1 = external global [65 x %struct.anon1], align 16
8*9880d681SAndroid Build Coastguard Worker@arr2 = external global [65 x %struct.anon2], align 16
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Workerdefine void @test1(i64 %x) nounwind {
11*9880d681SAndroid Build Coastguard Workerentry:
12*9880d681SAndroid Build Coastguard Worker  %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
13*9880d681SAndroid Build Coastguard Worker  %tmp = load i32, i32* %a, align 4
14*9880d681SAndroid Build Coastguard Worker  %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
15*9880d681SAndroid Build Coastguard Worker  %tmp1 = load i32, i32* %b, align 4
16*9880d681SAndroid Build Coastguard Worker  %sub = sub i32 %tmp, %tmp1
17*9880d681SAndroid Build Coastguard Worker  %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
18*9880d681SAndroid Build Coastguard Worker  %tmp2 = load i32, i32* %c, align 4
19*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %sub, %tmp2
20*9880d681SAndroid Build Coastguard Worker  switch i32 %add, label %sw.epilog [
21*9880d681SAndroid Build Coastguard Worker    i32 1, label %sw.bb.1
22*9880d681SAndroid Build Coastguard Worker    i32 2, label %sw.bb.2
23*9880d681SAndroid Build Coastguard Worker  ]
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Workersw.bb.1:                                          ; preds = %entry
26*9880d681SAndroid Build Coastguard Worker  store i32 111, i32* %b, align 4
27*9880d681SAndroid Build Coastguard Worker  store i32 222, i32* %c, align 4
28*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Workersw.bb.2:                                          ; preds = %entry
31*9880d681SAndroid Build Coastguard Worker  store i32 333, i32* %b, align 4
32*9880d681SAndroid Build Coastguard Worker  store i32 444, i32* %c, align 4
33*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Workersw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
36*9880d681SAndroid Build Coastguard Worker  ret void
37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test1:
38*9880d681SAndroid Build Coastguard Worker; CHECK:	shlq $2, [[REG1:%[a-z]+]]
39*9880d681SAndroid Build Coastguard Worker; CHECK:	movl arr1([[REG1]],[[REG1]],2), {{.*}}
40*9880d681SAndroid Build Coastguard Worker; CHECK:	leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]]
41*9880d681SAndroid Build Coastguard Worker; CHECK:	subl arr1+4([[REG1]],[[REG1]],2), {{.*}}
42*9880d681SAndroid Build Coastguard Worker; DISABLED:	leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]]
43*9880d681SAndroid Build Coastguard Worker; CHECK:	addl arr1+8([[REG1]],[[REG1]],2), {{.*}}
44*9880d681SAndroid Build Coastguard Worker; CHECK:	movl ${{[1-4]+}}, ([[REG2]])
45*9880d681SAndroid Build Coastguard Worker; ENABLED:	movl ${{[1-4]+}}, 4([[REG2]])
46*9880d681SAndroid Build Coastguard Worker; DISABLED:	movl ${{[1-4]+}}, ([[REG3]])
47*9880d681SAndroid Build Coastguard Worker; CHECK:	movl ${{[1-4]+}}, ([[REG2]])
48*9880d681SAndroid Build Coastguard Worker; ENABLED:	movl ${{[1-4]+}}, 4([[REG2]])
49*9880d681SAndroid Build Coastguard Worker; DISABLED:	movl ${{[1-4]+}}, ([[REG3]])
50*9880d681SAndroid Build Coastguard Worker}
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Workerdefine void @test2(i64 %x) nounwind optsize {
53*9880d681SAndroid Build Coastguard Workerentry:
54*9880d681SAndroid Build Coastguard Worker  %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
55*9880d681SAndroid Build Coastguard Worker  %tmp = load i32, i32* %a, align 4
56*9880d681SAndroid Build Coastguard Worker  %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
57*9880d681SAndroid Build Coastguard Worker  %tmp1 = load i32, i32* %b, align 4
58*9880d681SAndroid Build Coastguard Worker  %sub = sub i32 %tmp, %tmp1
59*9880d681SAndroid Build Coastguard Worker  %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
60*9880d681SAndroid Build Coastguard Worker  %tmp2 = load i32, i32* %c, align 4
61*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %sub, %tmp2
62*9880d681SAndroid Build Coastguard Worker  switch i32 %add, label %sw.epilog [
63*9880d681SAndroid Build Coastguard Worker    i32 1, label %sw.bb.1
64*9880d681SAndroid Build Coastguard Worker    i32 2, label %sw.bb.2
65*9880d681SAndroid Build Coastguard Worker  ]
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Workersw.bb.1:                                          ; preds = %entry
68*9880d681SAndroid Build Coastguard Worker  store i32 111, i32* %b, align 4
69*9880d681SAndroid Build Coastguard Worker  store i32 222, i32* %c, align 4
70*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Workersw.bb.2:                                          ; preds = %entry
73*9880d681SAndroid Build Coastguard Worker  store i32 333, i32* %b, align 4
74*9880d681SAndroid Build Coastguard Worker  store i32 444, i32* %c, align 4
75*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Workersw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
78*9880d681SAndroid Build Coastguard Worker  ret void
79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test2:
80*9880d681SAndroid Build Coastguard Worker; CHECK:	shlq $2, [[REG1:%[a-z]+]]
81*9880d681SAndroid Build Coastguard Worker; DISABLED:	movl arr1([[REG1]],[[REG1]],2), {{.*}}
82*9880d681SAndroid Build Coastguard Worker; CHECK:	leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]]
83*9880d681SAndroid Build Coastguard Worker; ENABLED:	movl -4([[REG2]]), {{.*}}
84*9880d681SAndroid Build Coastguard Worker; ENABLED:	subl ([[REG2]]), {{.*}}
85*9880d681SAndroid Build Coastguard Worker; ENABLED:	addl 4([[REG2]]), {{.*}}
86*9880d681SAndroid Build Coastguard Worker; DISABLED:	subl arr1+4([[REG1]],[[REG1]],2), {{.*}}
87*9880d681SAndroid Build Coastguard Worker; DISABLED:	leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]]
88*9880d681SAndroid Build Coastguard Worker; DISABLED:	addl arr1+8([[REG1]],[[REG1]],2), {{.*}}
89*9880d681SAndroid Build Coastguard Worker; CHECK:	movl ${{[1-4]+}}, ([[REG2]])
90*9880d681SAndroid Build Coastguard Worker; ENABLED:	movl ${{[1-4]+}}, 4([[REG2]])
91*9880d681SAndroid Build Coastguard Worker; DISABLED:	movl ${{[1-4]+}}, ([[REG3]])
92*9880d681SAndroid Build Coastguard Worker; CHECK:	movl ${{[1-4]+}}, ([[REG2]])
93*9880d681SAndroid Build Coastguard Worker; ENABLED:	movl ${{[1-4]+}}, 4([[REG2]])
94*9880d681SAndroid Build Coastguard Worker; DISABLED:	movl ${{[1-4]+}}, ([[REG3]])
95*9880d681SAndroid Build Coastguard Worker}
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker; Check that LEA optimization pass takes into account a resultant address
98*9880d681SAndroid Build Coastguard Worker; displacement when choosing a LEA instruction for replacing a redundant
99*9880d681SAndroid Build Coastguard Worker; address recalculation.
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Workerdefine void @test3(i64 %x) nounwind optsize {
102*9880d681SAndroid Build Coastguard Workerentry:
103*9880d681SAndroid Build Coastguard Worker  %a = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 2
104*9880d681SAndroid Build Coastguard Worker  %tmp = load i32, i32* %a, align 4
105*9880d681SAndroid Build Coastguard Worker  %b = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 0
106*9880d681SAndroid Build Coastguard Worker  %tmp1 = load i32, i32* %b, align 4
107*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %tmp, %tmp1
108*9880d681SAndroid Build Coastguard Worker  switch i32 %add, label %sw.epilog [
109*9880d681SAndroid Build Coastguard Worker    i32 1, label %sw.bb.1
110*9880d681SAndroid Build Coastguard Worker    i32 2, label %sw.bb.2
111*9880d681SAndroid Build Coastguard Worker  ]
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Workersw.bb.1:                                          ; preds = %entry
114*9880d681SAndroid Build Coastguard Worker  store i32 111, i32* %a, align 4
115*9880d681SAndroid Build Coastguard Worker  store i32 222, i32* %b, align 4
116*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Workersw.bb.2:                                          ; preds = %entry
119*9880d681SAndroid Build Coastguard Worker  store i32 333, i32* %a, align 4
120*9880d681SAndroid Build Coastguard Worker  ; Make sure the REG3's definition LEA won't be removed as redundant.
121*9880d681SAndroid Build Coastguard Worker  %cvt = ptrtoint i32* %b to i32
122*9880d681SAndroid Build Coastguard Worker  store i32 %cvt, i32* %b, align 4
123*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Workersw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
126*9880d681SAndroid Build Coastguard Worker  ret void
127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test3:
128*9880d681SAndroid Build Coastguard Worker; CHECK:	imulq {{.*}}, [[REG1:%[a-z]+]]
129*9880d681SAndroid Build Coastguard Worker; CHECK:	leaq arr2+132([[REG1]]), [[REG2:%[a-z]+]]
130*9880d681SAndroid Build Coastguard Worker; CHECK:	leaq arr2([[REG1]]), [[REG3:%[a-z]+]]
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Worker; REG3's definition is closer to movl than REG2's, but the pass still chooses
133*9880d681SAndroid Build Coastguard Worker; REG2 because it provides the resultant address displacement fitting 1 byte.
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker; ENABLED:	movl ([[REG2]]), {{.*}}
136*9880d681SAndroid Build Coastguard Worker; ENABLED:	addl ([[REG3]]), {{.*}}
137*9880d681SAndroid Build Coastguard Worker; DISABLED:	movl arr2+132([[REG1]]), {{.*}}
138*9880d681SAndroid Build Coastguard Worker; DISABLED:	addl arr2([[REG1]]), {{.*}}
139*9880d681SAndroid Build Coastguard Worker; CHECK:	movl ${{[1-4]+}}, ([[REG2]])
140*9880d681SAndroid Build Coastguard Worker; CHECK:	movl ${{[1-4]+}}, ([[REG3]])
141*9880d681SAndroid Build Coastguard Worker; CHECK:	movl ${{[1-4]+}}, ([[REG2]])
142*9880d681SAndroid Build Coastguard Worker; CHECK:	movl {{.*}}, ([[REG3]])
143*9880d681SAndroid Build Coastguard Worker}
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Workerdefine void @test4(i64 %x) nounwind minsize {
146*9880d681SAndroid Build Coastguard Workerentry:
147*9880d681SAndroid Build Coastguard Worker  %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
148*9880d681SAndroid Build Coastguard Worker  %tmp = load i32, i32* %a, align 4
149*9880d681SAndroid Build Coastguard Worker  %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
150*9880d681SAndroid Build Coastguard Worker  %tmp1 = load i32, i32* %b, align 4
151*9880d681SAndroid Build Coastguard Worker  %sub = sub i32 %tmp, %tmp1
152*9880d681SAndroid Build Coastguard Worker  %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
153*9880d681SAndroid Build Coastguard Worker  %tmp2 = load i32, i32* %c, align 4
154*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %sub, %tmp2
155*9880d681SAndroid Build Coastguard Worker  switch i32 %add, label %sw.epilog [
156*9880d681SAndroid Build Coastguard Worker    i32 1, label %sw.bb.1
157*9880d681SAndroid Build Coastguard Worker    i32 2, label %sw.bb.2
158*9880d681SAndroid Build Coastguard Worker  ]
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Workersw.bb.1:                                          ; preds = %entry
161*9880d681SAndroid Build Coastguard Worker  store i32 111, i32* %b, align 4
162*9880d681SAndroid Build Coastguard Worker  store i32 222, i32* %c, align 4
163*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Workersw.bb.2:                                          ; preds = %entry
166*9880d681SAndroid Build Coastguard Worker  store i32 333, i32* %b, align 4
167*9880d681SAndroid Build Coastguard Worker  store i32 444, i32* %c, align 4
168*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Workersw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
171*9880d681SAndroid Build Coastguard Worker  ret void
172*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test4:
173*9880d681SAndroid Build Coastguard Worker; CHECK:	imulq {{.*}}, [[REG1:%[a-z]+]]
174*9880d681SAndroid Build Coastguard Worker; DISABLED:	movl arr1([[REG1]]), {{.*}}
175*9880d681SAndroid Build Coastguard Worker; CHECK:	leaq arr1+4([[REG1]]), [[REG2:%[a-z]+]]
176*9880d681SAndroid Build Coastguard Worker; ENABLED:	movl -4([[REG2]]), {{.*}}
177*9880d681SAndroid Build Coastguard Worker; ENABLED:	subl ([[REG2]]), {{.*}}
178*9880d681SAndroid Build Coastguard Worker; ENABLED:	addl 4([[REG2]]), {{.*}}
179*9880d681SAndroid Build Coastguard Worker; DISABLED:	subl arr1+4([[REG1]]), {{.*}}
180*9880d681SAndroid Build Coastguard Worker; DISABLED:	leaq arr1+8([[REG1]]), [[REG3:%[a-z]+]]
181*9880d681SAndroid Build Coastguard Worker; DISABLED:	addl arr1+8([[REG1]]), {{.*}}
182*9880d681SAndroid Build Coastguard Worker; CHECK:	movl ${{[1-4]+}}, ([[REG2]])
183*9880d681SAndroid Build Coastguard Worker; ENABLED:	movl ${{[1-4]+}}, 4([[REG2]])
184*9880d681SAndroid Build Coastguard Worker; DISABLED:	movl ${{[1-4]+}}, ([[REG3]])
185*9880d681SAndroid Build Coastguard Worker; CHECK:	movl ${{[1-4]+}}, ([[REG2]])
186*9880d681SAndroid Build Coastguard Worker; ENABLED:	movl ${{[1-4]+}}, 4([[REG2]])
187*9880d681SAndroid Build Coastguard Worker; DISABLED:	movl ${{[1-4]+}}, ([[REG3]])
188*9880d681SAndroid Build Coastguard Worker}
189