xref: /llvm-project/llvm/test/CodeGen/X86/lea-dagdag.ll (revision d96529af3c362c53ef2e8c883a9e571fb3626927)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-- -mattr=+slow-3ops-lea | FileCheck %s
3; RUN: llc < %s -mtriple=x86_64-- -mattr=-slow-3ops-lea | FileCheck %s
4
5define i16 @and_i8_zext_shl_add_i16(i16 %t0, i8 %t1) {
6; CHECK-LABEL: and_i8_zext_shl_add_i16:
7; CHECK:       # %bb.0:
8; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
9; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
10; CHECK-NEXT:    andl $8, %esi
11; CHECK-NEXT:    leal (%rdi,%rsi,4), %eax
12; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
13; CHECK-NEXT:    retq
14  %t4 = and i8 %t1, 8
15  %t5 = zext i8 %t4 to i16
16  %sh = shl i16 %t5, 2
17  %t6 = add i16 %sh, %t0
18  ret i16 %t6
19}
20
21define i16 @and_i8_shl_zext_add_i16(i16 %t0, i8 %t1) {
22; CHECK-LABEL: and_i8_shl_zext_add_i16:
23; CHECK:       # %bb.0:
24; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
25; CHECK-NEXT:    andb $8, %sil
26; CHECK-NEXT:    movzbl %sil, %eax
27; CHECK-NEXT:    leal (%rdi,%rax,4), %eax
28; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
29; CHECK-NEXT:    retq
30  %t4 = and i8 %t1, 8
31  %sh = shl i8 %t4, 2
32  %t5 = zext i8 %sh to i16
33  %t6 = add i16 %t5, %t0
34  ret i16 %t6
35}
36
37define i32 @and_i8_zext_shl_add_i32(i32 %t0, i8 %t1) {
38; CHECK-LABEL: and_i8_zext_shl_add_i32:
39; CHECK:       # %bb.0:
40; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
41; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
42; CHECK-NEXT:    andl $8, %esi
43; CHECK-NEXT:    leal (%rdi,%rsi,8), %eax
44; CHECK-NEXT:    retq
45  %t4 = and i8 %t1, 8
46  %t5 = zext i8 %t4 to i32
47  %sh = shl i32 %t5, 3
48  %t6 = add i32 %sh, %t0
49  ret i32 %t6
50}
51
52define i32 @and_i8_shl_zext_add_i32(i32 %t0, i8 %t1) {
53; CHECK-LABEL: and_i8_shl_zext_add_i32:
54; CHECK:       # %bb.0:
55; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
56; CHECK-NEXT:    andb $8, %sil
57; CHECK-NEXT:    movzbl %sil, %eax
58; CHECK-NEXT:    leal (%rdi,%rax,8), %eax
59; CHECK-NEXT:    retq
60  %t4 = and i8 %t1, 8
61  %sh = shl i8 %t4, 3
62  %t5 = zext i8 %sh to i32
63  %t6 = add i32 %t5, %t0
64  ret i32 %t6
65}
66
67define i32 @and_i16_zext_shl_add_i32(i32 %t0, i16 %t1) {
68; CHECK-LABEL: and_i16_zext_shl_add_i32:
69; CHECK:       # %bb.0:
70; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
71; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
72; CHECK-NEXT:    andl $8, %esi
73; CHECK-NEXT:    leal (%rdi,%rsi,4), %eax
74; CHECK-NEXT:    retq
75  %t4 = and i16 %t1, 8
76  %t5 = zext i16 %t4 to i32
77  %sh = shl i32 %t5, 2
78  %t6 = add i32 %sh, %t0
79  ret i32 %t6
80}
81
82define i32 @and_i16_shl_zext_add_i32(i32 %t0, i16 %t1) {
83; CHECK-LABEL: and_i16_shl_zext_add_i32:
84; CHECK:       # %bb.0:
85; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
86; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
87; CHECK-NEXT:    andl $8, %esi
88; CHECK-NEXT:    leal (%rdi,%rsi,4), %eax
89; CHECK-NEXT:    retq
90  %t4 = and i16 %t1, 8
91  %sh = shl i16 %t4, 2
92  %t5 = zext i16 %sh to i32
93  %t6 = add i32 %t5, %t0
94  ret i32 %t6
95}
96
97define i64 @and_i8_zext_shl_add_i64(i64 %t0, i8 %t1) {
98; CHECK-LABEL: and_i8_zext_shl_add_i64:
99; CHECK:       # %bb.0:
100; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
101; CHECK-NEXT:    andl $8, %esi
102; CHECK-NEXT:    leaq (%rdi,%rsi,2), %rax
103; CHECK-NEXT:    retq
104  %t4 = and i8 %t1, 8
105  %t5 = zext i8 %t4 to i64
106  %sh = shl i64 %t5, 1
107  %t6 = add i64 %sh, %t0
108  ret i64 %t6
109}
110
111define i64 @and_i8_shl_zext_add_i64(i64 %t0, i8 %t1) {
112; CHECK-LABEL: and_i8_shl_zext_add_i64:
113; CHECK:       # %bb.0:
114; CHECK-NEXT:    andb $8, %sil
115; CHECK-NEXT:    movzbl %sil, %eax
116; CHECK-NEXT:    leaq (%rdi,%rax,2), %rax
117; CHECK-NEXT:    retq
118  %t4 = and i8 %t1, 8
119  %sh = shl i8 %t4, 1
120  %t5 = zext i8 %sh to i64
121  %t6 = add i64 %t5, %t0
122  ret i64 %t6
123}
124
125define i64 @and_i32_zext_shl_add_i64(i64 %t0, i32 %t1) {
126; CHECK-LABEL: and_i32_zext_shl_add_i64:
127; CHECK:       # %bb.0:
128; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
129; CHECK-NEXT:    andl $8, %esi
130; CHECK-NEXT:    leaq (%rdi,%rsi,8), %rax
131; CHECK-NEXT:    retq
132  %t4 = and i32 %t1, 8
133  %t5 = zext i32 %t4 to i64
134  %sh = shl i64 %t5, 3
135  %t6 = add i64 %sh, %t0
136  ret i64 %t6
137}
138
139define i64 @and_i32_shl_zext_add_i64(i64 %t0, i32 %t1) {
140; CHECK-LABEL: and_i32_shl_zext_add_i64:
141; CHECK:       # %bb.0:
142; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
143; CHECK-NEXT:    andl $8, %esi
144; CHECK-NEXT:    leaq (%rdi,%rsi,8), %rax
145; CHECK-NEXT:    retq
146  %t4 = and i32 %t1, 8
147  %sh = shl i32 %t4, 3
148  %t5 = zext i32 %sh to i64
149  %t6 = add i64 %t5, %t0
150  ret i64 %t6
151}
152
153define i64 @shl_and_i8_zext_add_i64(i64 %t0, i8 %t1) {
154; CHECK-LABEL: shl_and_i8_zext_add_i64:
155; CHECK:       # %bb.0:
156; CHECK-NEXT:    andb $15, %sil
157; CHECK-NEXT:    movzbl %sil, %eax
158; CHECK-NEXT:    leaq (%rdi,%rax,4), %rax
159; CHECK-NEXT:    retq
160  %s = shl i8 %t1, 2
161  %m = and i8 %s, 60
162  %z = zext i8 %m to i64
163  %a = add i64 %t0, %z
164  ret i64 %a
165}
166
167define i64 @shl_and_i16_zext_add_i64(i64 %t0, i16 %t1) {
168; CHECK-LABEL: shl_and_i16_zext_add_i64:
169; CHECK:       # %bb.0:
170; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
171; CHECK-NEXT:    andl $8, %esi
172; CHECK-NEXT:    leaq (%rdi,%rsi,2), %rax
173; CHECK-NEXT:    retq
174  %s = shl i16 %t1, 1
175  %m = and i16 %s, 17
176  %z = zext i16 %m to i64
177  %a = add i64 %t0, %z
178  ret i64 %a
179}
180
181define i64 @shl_and_i32_zext_add_i64(i64 %t0, i32 %t1) {
182; CHECK-LABEL: shl_and_i32_zext_add_i64:
183; CHECK:       # %bb.0:
184; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
185; CHECK-NEXT:    andl $749, %esi # imm = 0x2ED
186; CHECK-NEXT:    leaq (%rdi,%rsi,8), %rax
187; CHECK-NEXT:    retq
188  %s = shl i32 %t1, 3
189  %m = and i32 %s, 5999
190  %z = zext i32 %m to i64
191  %a = add i64 %t0, %z
192  ret i64 %a
193}
194
195; Negative test - shift can't be converted to scale factor.
196
197define i64 @and_i32_zext_shl_add_i64_overshift(i64 %t0, i32 %t1) {
198; CHECK-LABEL: and_i32_zext_shl_add_i64_overshift:
199; CHECK:       # %bb.0:
200; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
201; CHECK-NEXT:    andl $8, %esi
202; CHECK-NEXT:    shll $4, %esi
203; CHECK-NEXT:    leaq (%rsi,%rdi), %rax
204; CHECK-NEXT:    retq
205  %t4 = and i32 %t1, 8
206  %t5 = zext i32 %t4 to i64
207  %sh = shl i64 %t5, 4
208  %t6 = add i64 %sh, %t0
209  ret i64 %t6
210}
211
212define i64 @and_i32_shl_zext_add_i64_overshift(i64 %t0, i32 %t1) {
213; CHECK-LABEL: and_i32_shl_zext_add_i64_overshift:
214; CHECK:       # %bb.0:
215; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
216; CHECK-NEXT:    andl $8, %esi
217; CHECK-NEXT:    shll $4, %esi
218; CHECK-NEXT:    leaq (%rsi,%rdi), %rax
219; CHECK-NEXT:    retq
220  %t4 = and i32 %t1, 8
221  %sh = shl i32 %t4, 4
222  %t5 = zext i32 %sh to i64
223  %t6 = add i64 %t5, %t0
224  ret i64 %t6
225}
226