1
1
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2
- ; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s
2
+ ; RUN: llc < %s -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=X86
3
+ ; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefixes=X64
3
4
4
5
; fold (shl (zext (lshr (A, X))), X) -> (zext (shl (lshr (A, X)), X))
5
6
11
12
; and if there is only one use of the zext.
12
13
13
14
define i16 @fun1 (i8 zeroext %v ) {
14
- ; CHECK-LABEL: fun1:
15
- ; CHECK: # %bb.0: # %entry
16
- ; CHECK-NEXT: movl %edi, %eax
17
- ; CHECK-NEXT: andl $-16, %eax
18
- ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
19
- ; CHECK-NEXT: retq
15
+ ; X86-LABEL: fun1:
16
+ ; X86: # %bb.0: # %entry
17
+ ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
18
+ ; X86-NEXT: andl $-16, %eax
19
+ ; X86-NEXT: # kill: def $ax killed $ax killed $eax
20
+ ; X86-NEXT: retl
21
+ ;
22
+ ; X64-LABEL: fun1:
23
+ ; X64: # %bb.0: # %entry
24
+ ; X64-NEXT: movl %edi, %eax
25
+ ; X64-NEXT: andl $-16, %eax
26
+ ; X64-NEXT: # kill: def $ax killed $ax killed $eax
27
+ ; X64-NEXT: retq
20
28
entry:
21
29
%shr = lshr i8 %v , 4
22
30
%ext = zext i8 %shr to i16
@@ -25,11 +33,17 @@ entry:
25
33
}
26
34
27
35
define i32 @fun2 (i8 zeroext %v ) {
28
- ; CHECK-LABEL: fun2:
29
- ; CHECK: # %bb.0: # %entry
30
- ; CHECK-NEXT: movl %edi, %eax
31
- ; CHECK-NEXT: andl $-16, %eax
32
- ; CHECK-NEXT: retq
36
+ ; X86-LABEL: fun2:
37
+ ; X86: # %bb.0: # %entry
38
+ ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
39
+ ; X86-NEXT: andl $-16, %eax
40
+ ; X86-NEXT: retl
41
+ ;
42
+ ; X64-LABEL: fun2:
43
+ ; X64: # %bb.0: # %entry
44
+ ; X64-NEXT: movl %edi, %eax
45
+ ; X64-NEXT: andl $-16, %eax
46
+ ; X64-NEXT: retq
33
47
entry:
34
48
%shr = lshr i8 %v , 4
35
49
%ext = zext i8 %shr to i32
@@ -38,11 +52,17 @@ entry:
38
52
}
39
53
40
54
define i32 @fun3 (i16 zeroext %v ) {
41
- ; CHECK-LABEL: fun3:
42
- ; CHECK: # %bb.0: # %entry
43
- ; CHECK-NEXT: movl %edi, %eax
44
- ; CHECK-NEXT: andl $-16, %eax
45
- ; CHECK-NEXT: retq
55
+ ; X86-LABEL: fun3:
56
+ ; X86: # %bb.0: # %entry
57
+ ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
58
+ ; X86-NEXT: andl $-16, %eax
59
+ ; X86-NEXT: retl
60
+ ;
61
+ ; X64-LABEL: fun3:
62
+ ; X64: # %bb.0: # %entry
63
+ ; X64-NEXT: movl %edi, %eax
64
+ ; X64-NEXT: andl $-16, %eax
65
+ ; X64-NEXT: retq
46
66
entry:
47
67
%shr = lshr i16 %v , 4
48
68
%ext = zext i16 %shr to i32
@@ -51,11 +71,18 @@ entry:
51
71
}
52
72
53
73
define i64 @fun4 (i8 zeroext %v ) {
54
- ; CHECK-LABEL: fun4:
55
- ; CHECK: # %bb.0: # %entry
56
- ; CHECK-NEXT: movl %edi, %eax
57
- ; CHECK-NEXT: andl $-16, %eax
58
- ; CHECK-NEXT: retq
74
+ ; X86-LABEL: fun4:
75
+ ; X86: # %bb.0: # %entry
76
+ ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
77
+ ; X86-NEXT: andl $-16, %eax
78
+ ; X86-NEXT: xorl %edx, %edx
79
+ ; X86-NEXT: retl
80
+ ;
81
+ ; X64-LABEL: fun4:
82
+ ; X64: # %bb.0: # %entry
83
+ ; X64-NEXT: movl %edi, %eax
84
+ ; X64-NEXT: andl $-16, %eax
85
+ ; X64-NEXT: retq
59
86
entry:
60
87
%shr = lshr i8 %v , 4
61
88
%ext = zext i8 %shr to i64
@@ -64,11 +91,18 @@ entry:
64
91
}
65
92
66
93
define i64 @fun5 (i16 zeroext %v ) {
67
- ; CHECK-LABEL: fun5:
68
- ; CHECK: # %bb.0: # %entry
69
- ; CHECK-NEXT: movl %edi, %eax
70
- ; CHECK-NEXT: andl $-16, %eax
71
- ; CHECK-NEXT: retq
94
+ ; X86-LABEL: fun5:
95
+ ; X86: # %bb.0: # %entry
96
+ ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
97
+ ; X86-NEXT: andl $-16, %eax
98
+ ; X86-NEXT: xorl %edx, %edx
99
+ ; X86-NEXT: retl
100
+ ;
101
+ ; X64-LABEL: fun5:
102
+ ; X64: # %bb.0: # %entry
103
+ ; X64-NEXT: movl %edi, %eax
104
+ ; X64-NEXT: andl $-16, %eax
105
+ ; X64-NEXT: retq
72
106
entry:
73
107
%shr = lshr i16 %v , 4
74
108
%ext = zext i16 %shr to i64
@@ -77,11 +111,18 @@ entry:
77
111
}
78
112
79
113
define i64 @fun6 (i32 zeroext %v ) {
80
- ; CHECK-LABEL: fun6:
81
- ; CHECK: # %bb.0: # %entry
82
- ; CHECK-NEXT: movl %edi, %eax
83
- ; CHECK-NEXT: andl $-16, %eax
84
- ; CHECK-NEXT: retq
114
+ ; X86-LABEL: fun6:
115
+ ; X86: # %bb.0: # %entry
116
+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
117
+ ; X86-NEXT: andl $-16, %eax
118
+ ; X86-NEXT: xorl %edx, %edx
119
+ ; X86-NEXT: retl
120
+ ;
121
+ ; X64-LABEL: fun6:
122
+ ; X64: # %bb.0: # %entry
123
+ ; X64-NEXT: movl %edi, %eax
124
+ ; X64-NEXT: andl $-16, %eax
125
+ ; X64-NEXT: retq
85
126
entry:
86
127
%shr = lshr i32 %v , 4
87
128
%ext = zext i32 %shr to i64
@@ -92,12 +133,21 @@ entry:
92
133
; Don't fold the pattern if we use arithmetic shifts.
93
134
94
135
define i64 @fun7 (i8 zeroext %v ) {
95
- ; CHECK-LABEL: fun7:
96
- ; CHECK: # %bb.0: # %entry
97
- ; CHECK-NEXT: sarb $4, %dil
98
- ; CHECK-NEXT: movzbl %dil, %eax
99
- ; CHECK-NEXT: shlq $4, %rax
100
- ; CHECK-NEXT: retq
136
+ ; X86-LABEL: fun7:
137
+ ; X86: # %bb.0: # %entry
138
+ ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
139
+ ; X86-NEXT: sarb $4, %al
140
+ ; X86-NEXT: movzbl %al, %eax
141
+ ; X86-NEXT: shll $4, %eax
142
+ ; X86-NEXT: xorl %edx, %edx
143
+ ; X86-NEXT: retl
144
+ ;
145
+ ; X64-LABEL: fun7:
146
+ ; X64: # %bb.0: # %entry
147
+ ; X64-NEXT: sarb $4, %dil
148
+ ; X64-NEXT: movzbl %dil, %eax
149
+ ; X64-NEXT: shlq $4, %rax
150
+ ; X64-NEXT: retq
101
151
entry:
102
152
%shr = ashr i8 %v , 4
103
153
%ext = zext i8 %shr to i64
@@ -106,13 +156,20 @@ entry:
106
156
}
107
157
108
158
define i64 @fun8 (i16 zeroext %v ) {
109
- ; CHECK-LABEL: fun8:
110
- ; CHECK: # %bb.0: # %entry
111
- ; CHECK-NEXT: movswl %di, %eax
112
- ; CHECK-NEXT: shrl $4, %eax
113
- ; CHECK-NEXT: movzwl %ax, %eax
114
- ; CHECK-NEXT: shlq $4, %rax
115
- ; CHECK-NEXT: retq
159
+ ; X86-LABEL: fun8:
160
+ ; X86: # %bb.0: # %entry
161
+ ; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax
162
+ ; X86-NEXT: andl $1048560, %eax # imm = 0xFFFF0
163
+ ; X86-NEXT: xorl %edx, %edx
164
+ ; X86-NEXT: retl
165
+ ;
166
+ ; X64-LABEL: fun8:
167
+ ; X64: # %bb.0: # %entry
168
+ ; X64-NEXT: movswl %di, %eax
169
+ ; X64-NEXT: shrl $4, %eax
170
+ ; X64-NEXT: movzwl %ax, %eax
171
+ ; X64-NEXT: shlq $4, %rax
172
+ ; X64-NEXT: retq
116
173
entry:
117
174
%shr = ashr i16 %v , 4
118
175
%ext = zext i16 %shr to i64
@@ -121,12 +178,21 @@ entry:
121
178
}
122
179
123
180
define i64 @fun9 (i32 zeroext %v ) {
124
- ; CHECK-LABEL: fun9:
125
- ; CHECK: # %bb.0: # %entry
126
- ; CHECK-NEXT: movl %edi, %eax
127
- ; CHECK-NEXT: sarl $4, %eax
128
- ; CHECK-NEXT: shlq $4, %rax
129
- ; CHECK-NEXT: retq
181
+ ; X86-LABEL: fun9:
182
+ ; X86: # %bb.0: # %entry
183
+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
184
+ ; X86-NEXT: movl %eax, %edx
185
+ ; X86-NEXT: sarl $4, %edx
186
+ ; X86-NEXT: andl $-16, %eax
187
+ ; X86-NEXT: shrl $28, %edx
188
+ ; X86-NEXT: retl
189
+ ;
190
+ ; X64-LABEL: fun9:
191
+ ; X64: # %bb.0: # %entry
192
+ ; X64-NEXT: movl %edi, %eax
193
+ ; X64-NEXT: sarl $4, %eax
194
+ ; X64-NEXT: shlq $4, %rax
195
+ ; X64-NEXT: retq
130
196
entry:
131
197
%shr = ashr i32 %v , 4
132
198
%ext = zext i32 %shr to i64
@@ -138,14 +204,25 @@ entry:
138
204
; operand in input to the shift left.
139
205
140
206
define i64 @fun10 (i8 zeroext %v ) {
141
- ; CHECK-LABEL: fun10:
142
- ; CHECK: # %bb.0: # %entry
143
- ; CHECK-NEXT: shrb $4, %dil
144
- ; CHECK-NEXT: movzbl %dil, %ecx
145
- ; CHECK-NEXT: movq %rcx, %rax
146
- ; CHECK-NEXT: shlq $4, %rax
147
- ; CHECK-NEXT: orq %rcx, %rax
148
- ; CHECK-NEXT: retq
207
+ ; X86-LABEL: fun10:
208
+ ; X86: # %bb.0: # %entry
209
+ ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
210
+ ; X86-NEXT: shrb $4, %al
211
+ ; X86-NEXT: movzbl %al, %ecx
212
+ ; X86-NEXT: movl %ecx, %eax
213
+ ; X86-NEXT: shll $4, %eax
214
+ ; X86-NEXT: orl %ecx, %eax
215
+ ; X86-NEXT: xorl %edx, %edx
216
+ ; X86-NEXT: retl
217
+ ;
218
+ ; X64-LABEL: fun10:
219
+ ; X64: # %bb.0: # %entry
220
+ ; X64-NEXT: shrb $4, %dil
221
+ ; X64-NEXT: movzbl %dil, %ecx
222
+ ; X64-NEXT: movq %rcx, %rax
223
+ ; X64-NEXT: shlq $4, %rax
224
+ ; X64-NEXT: orq %rcx, %rax
225
+ ; X64-NEXT: retq
149
226
entry:
150
227
%shr = lshr i8 %v , 4
151
228
%ext = zext i8 %shr to i64
@@ -155,14 +232,24 @@ entry:
155
232
}
156
233
157
234
define i64 @fun11 (i16 zeroext %v ) {
158
- ; CHECK-LABEL: fun11:
159
- ; CHECK: # %bb.0: # %entry
160
- ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
161
- ; CHECK-NEXT: shrl $4, %edi
162
- ; CHECK-NEXT: movq %rdi, %rax
163
- ; CHECK-NEXT: shlq $4, %rax
164
- ; CHECK-NEXT: addq %rdi, %rax
165
- ; CHECK-NEXT: retq
235
+ ; X86-LABEL: fun11:
236
+ ; X86: # %bb.0: # %entry
237
+ ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
238
+ ; X86-NEXT: movl %eax, %ecx
239
+ ; X86-NEXT: shrl $4, %ecx
240
+ ; X86-NEXT: andl $-16, %eax
241
+ ; X86-NEXT: addl %ecx, %eax
242
+ ; X86-NEXT: xorl %edx, %edx
243
+ ; X86-NEXT: retl
244
+ ;
245
+ ; X64-LABEL: fun11:
246
+ ; X64: # %bb.0: # %entry
247
+ ; X64-NEXT: # kill: def $edi killed $edi def $rdi
248
+ ; X64-NEXT: shrl $4, %edi
249
+ ; X64-NEXT: movq %rdi, %rax
250
+ ; X64-NEXT: shlq $4, %rax
251
+ ; X64-NEXT: addq %rdi, %rax
252
+ ; X64-NEXT: retq
166
253
entry:
167
254
%shr = lshr i16 %v , 4
168
255
%ext = zext i16 %shr to i64
@@ -172,14 +259,25 @@ entry:
172
259
}
173
260
174
261
define i64 @fun12 (i32 zeroext %v ) {
175
- ; CHECK-LABEL: fun12:
176
- ; CHECK: # %bb.0: # %entry
177
- ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
178
- ; CHECK-NEXT: shrl $4, %edi
179
- ; CHECK-NEXT: movq %rdi, %rax
180
- ; CHECK-NEXT: shlq $4, %rax
181
- ; CHECK-NEXT: addq %rdi, %rax
182
- ; CHECK-NEXT: retq
262
+ ; X86-LABEL: fun12:
263
+ ; X86: # %bb.0: # %entry
264
+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
265
+ ; X86-NEXT: movl %eax, %ecx
266
+ ; X86-NEXT: shrl $4, %ecx
267
+ ; X86-NEXT: andl $-16, %eax
268
+ ; X86-NEXT: xorl %edx, %edx
269
+ ; X86-NEXT: addl %ecx, %eax
270
+ ; X86-NEXT: setb %dl
271
+ ; X86-NEXT: retl
272
+ ;
273
+ ; X64-LABEL: fun12:
274
+ ; X64: # %bb.0: # %entry
275
+ ; X64-NEXT: # kill: def $edi killed $edi def $rdi
276
+ ; X64-NEXT: shrl $4, %edi
277
+ ; X64-NEXT: movq %rdi, %rax
278
+ ; X64-NEXT: shlq $4, %rax
279
+ ; X64-NEXT: addq %rdi, %rax
280
+ ; X64-NEXT: retq
183
281
entry:
184
282
%shr = lshr i32 %v , 4
185
283
%ext = zext i32 %shr to i64
@@ -199,12 +297,24 @@ entry:
199
297
; Verify also that we correctly fold the shl-shr sequence into an
200
298
; AND with bitmask.
201
299
202
- define void @g (i32 %a ) {
203
- ; CHECK-LABEL: g:
204
- ; CHECK: # %bb.0:
205
- ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
206
- ; CHECK-NEXT: andl $-4, %edi
207
- ; CHECK-NEXT: jmp f # TAILCALL
300
+ define void @g (i32 %a ) nounwind {
301
+ ; X86-LABEL: g:
302
+ ; X86: # %bb.0:
303
+ ; X86-NEXT: subl $12, %esp
304
+ ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
305
+ ; X86-NEXT: andl $-4, %eax
306
+ ; X86-NEXT: subl $8, %esp
307
+ ; X86-NEXT: pushl $0
308
+ ; X86-NEXT: pushl %eax
309
+ ; X86-NEXT: calll f
310
+ ; X86-NEXT: addl $28, %esp
311
+ ; X86-NEXT: retl
312
+ ;
313
+ ; X64-LABEL: g:
314
+ ; X64: # %bb.0:
315
+ ; X64-NEXT: # kill: def $edi killed $edi def $rdi
316
+ ; X64-NEXT: andl $-4, %edi
317
+ ; X64-NEXT: jmp f # TAILCALL
208
318
%b = lshr i32 %a , 2
209
319
%c = zext i32 %b to i64
210
320
%d = add i64 %c , 1
0 commit comments