xref: /llvm-project/llvm/test/CodeGen/X86/bmi-intrinsics-fast-isel.ll (revision 2d92f7de800a1b1b3dca3dab1e11da712cd55f2b)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -fast-isel -mtriple=i686-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X86
3; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X64
4; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi,+egpr --show-mc-encoding | FileCheck %s --check-prefix=EGPR
5; NOTE: This should use IR equivalent to what is generated by clang/test/CodeGen/bmi-builtins.c
6
7;
8; AMD Intrinsics
9;
10
11define i16 @test__tzcnt_u16(i16 %a0) {
12; X86-LABEL: test__tzcnt_u16:
13; X86:       # %bb.0:
14; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
15; X86-NEXT:    orl $65536, %eax # imm = 0x10000
16; X86-NEXT:    tzcntl %eax, %eax
17; X86-NEXT:    # kill: def $ax killed $ax killed $eax
18; X86-NEXT:    retl
19;
20; X64-LABEL: test__tzcnt_u16:
21; X64:       # %bb.0:
22; X64-NEXT:    orl $65536, %edi # imm = 0x10000
23; X64-NEXT:    tzcntl %edi, %eax
24; X64-NEXT:    # kill: def $ax killed $ax killed $eax
25; X64-NEXT:    retq
26;
27; EGPR-LABEL: test__tzcnt_u16:
28; EGPR:       # %bb.0:
29; EGPR-NEXT:    orl $65536, %edi # encoding: [0x81,0xcf,0x00,0x00,0x01,0x00]
30; EGPR-NEXT:    # imm = 0x10000
31; EGPR-NEXT:    tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]
32; EGPR-NEXT:    # kill: def $ax killed $ax killed $eax
33; EGPR-NEXT:    retq # encoding: [0xc3]
34  %zext = zext i16 %a0 to i32
35  %cmp = icmp ne i32 %zext, 0
36  %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false)
37  ret i16 %cttz
38}
39
40define i32 @test__andn_u32(i32 %a0, i32 %a1) {
41; X86-LABEL: test__andn_u32:
42; X86:       # %bb.0:
43; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
44; X86-NEXT:    xorl $-1, %eax
45; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
46; X86-NEXT:    retl
47;
48; X64-LABEL: test__andn_u32:
49; X64:       # %bb.0:
50; X64-NEXT:    movl %edi, %eax
51; X64-NEXT:    xorl $-1, %eax
52; X64-NEXT:    andl %esi, %eax
53; X64-NEXT:    retq
54;
55; EGPR-LABEL: test__andn_u32:
56; EGPR:       # %bb.0:
57; EGPR-NEXT:    movl %edi, %eax # encoding: [0x89,0xf8]
58; EGPR-NEXT:    xorl $-1, %eax # encoding: [0x83,0xf0,0xff]
59; EGPR-NEXT:    andl %esi, %eax # encoding: [0x21,0xf0]
60; EGPR-NEXT:    retq # encoding: [0xc3]
61  %xor = xor i32 %a0, -1
62  %res = and i32 %xor, %a1
63  ret i32 %res
64}
65
66define i32 @test__bextr_u32(i32 %a0, i32 %a1) {
67; X86-LABEL: test__bextr_u32:
68; X86:       # %bb.0:
69; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
70; X86-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
71; X86-NEXT:    retl
72;
73; X64-LABEL: test__bextr_u32:
74; X64:       # %bb.0:
75; X64-NEXT:    bextrl %esi, %edi, %eax
76; X64-NEXT:    retq
77;
78; EGPR-LABEL: test__bextr_u32:
79; EGPR:       # %bb.0:
80; EGPR-NEXT:    bextrl %esi, %edi, %eax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x48,0xf7,0xc7]
81; EGPR-NEXT:    retq # encoding: [0xc3]
82  %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %a1)
83  ret i32 %res
84}
85
86define i32 @test__blsi_u32(i32 %a0) {
87; X86-LABEL: test__blsi_u32:
88; X86:       # %bb.0:
89; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
90; X86-NEXT:    xorl %eax, %eax
91; X86-NEXT:    subl %ecx, %eax
92; X86-NEXT:    andl %ecx, %eax
93; X86-NEXT:    retl
94;
95; X64-LABEL: test__blsi_u32:
96; X64:       # %bb.0:
97; X64-NEXT:    xorl %eax, %eax
98; X64-NEXT:    subl %edi, %eax
99; X64-NEXT:    andl %edi, %eax
100; X64-NEXT:    retq
101;
102; EGPR-LABEL: test__blsi_u32:
103; EGPR:       # %bb.0:
104; EGPR-NEXT:    xorl %eax, %eax # encoding: [0x31,0xc0]
105; EGPR-NEXT:    subl %edi, %eax # encoding: [0x29,0xf8]
106; EGPR-NEXT:    andl %edi, %eax # encoding: [0x21,0xf8]
107; EGPR-NEXT:    retq # encoding: [0xc3]
108  %neg = sub i32 0, %a0
109  %res = and i32 %a0, %neg
110  ret i32 %res
111}
112
113define i32 @test__blsmsk_u32(i32 %a0) {
114; X86-LABEL: test__blsmsk_u32:
115; X86:       # %bb.0:
116; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
117; X86-NEXT:    leal -1(%ecx), %eax
118; X86-NEXT:    xorl %ecx, %eax
119; X86-NEXT:    retl
120;
121; X64-LABEL: test__blsmsk_u32:
122; X64:       # %bb.0:
123; X64-NEXT:    # kill: def $edi killed $edi def $rdi
124; X64-NEXT:    leal -1(%rdi), %eax
125; X64-NEXT:    xorl %edi, %eax
126; X64-NEXT:    retq
127;
128; EGPR-LABEL: test__blsmsk_u32:
129; EGPR:       # %bb.0:
130; EGPR-NEXT:    # kill: def $edi killed $edi def $rdi
131; EGPR-NEXT:    leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff]
132; EGPR-NEXT:    xorl %edi, %eax # encoding: [0x31,0xf8]
133; EGPR-NEXT:    retq # encoding: [0xc3]
134  %dec = sub i32 %a0, 1
135  %res = xor i32 %a0, %dec
136  ret i32 %res
137}
138
139define i32 @test__blsr_u32(i32 %a0) {
140; X86-LABEL: test__blsr_u32:
141; X86:       # %bb.0:
142; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
143; X86-NEXT:    leal -1(%ecx), %eax
144; X86-NEXT:    andl %ecx, %eax
145; X86-NEXT:    retl
146;
147; X64-LABEL: test__blsr_u32:
148; X64:       # %bb.0:
149; X64-NEXT:    # kill: def $edi killed $edi def $rdi
150; X64-NEXT:    leal -1(%rdi), %eax
151; X64-NEXT:    andl %edi, %eax
152; X64-NEXT:    retq
153;
154; EGPR-LABEL: test__blsr_u32:
155; EGPR:       # %bb.0:
156; EGPR-NEXT:    # kill: def $edi killed $edi def $rdi
157; EGPR-NEXT:    leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff]
158; EGPR-NEXT:    andl %edi, %eax # encoding: [0x21,0xf8]
159; EGPR-NEXT:    retq # encoding: [0xc3]
160  %dec = sub i32 %a0, 1
161  %res = and i32 %a0, %dec
162  ret i32 %res
163}
164
165define i32 @test__tzcnt_u32(i32 %a0) {
166; X86-LABEL: test__tzcnt_u32:
167; X86:       # %bb.0:
168; X86-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax
169; X86-NEXT:    retl
170;
171; X64-LABEL: test__tzcnt_u32:
172; X64:       # %bb.0:
173; X64-NEXT:    tzcntl %edi, %eax
174; X64-NEXT:    retq
175;
176; EGPR-LABEL: test__tzcnt_u32:
177; EGPR:       # %bb.0:
178; EGPR-NEXT:    tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]
179; EGPR-NEXT:    retq # encoding: [0xc3]
180  %cmp = icmp ne i32 %a0, 0
181  %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)
182  ret i32 %cttz
183}
184
185;
186; Intel intrinsics
187;
188
189define i16 @test_tzcnt_u16(i16 %a0) {
190; X86-LABEL: test_tzcnt_u16:
191; X86:       # %bb.0:
192; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
193; X86-NEXT:    orl $65536, %eax # imm = 0x10000
194; X86-NEXT:    tzcntl %eax, %eax
195; X86-NEXT:    # kill: def $ax killed $ax killed $eax
196; X86-NEXT:    retl
197;
198; X64-LABEL: test_tzcnt_u16:
199; X64:       # %bb.0:
200; X64-NEXT:    orl $65536, %edi # imm = 0x10000
201; X64-NEXT:    tzcntl %edi, %eax
202; X64-NEXT:    # kill: def $ax killed $ax killed $eax
203; X64-NEXT:    retq
204;
205; EGPR-LABEL: test_tzcnt_u16:
206; EGPR:       # %bb.0:
207; EGPR-NEXT:    orl $65536, %edi # encoding: [0x81,0xcf,0x00,0x00,0x01,0x00]
208; EGPR-NEXT:    # imm = 0x10000
209; EGPR-NEXT:    tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]
210; EGPR-NEXT:    # kill: def $ax killed $ax killed $eax
211; EGPR-NEXT:    retq # encoding: [0xc3]
212  %zext = zext i16 %a0 to i32
213  %cmp = icmp ne i32 %zext, 0
214  %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false)
215  ret i16 %cttz
216}
217
218define i32 @test_andn_u32(i32 %a0, i32 %a1) {
219; X86-LABEL: test_andn_u32:
220; X86:       # %bb.0:
221; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
222; X86-NEXT:    xorl $-1, %eax
223; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
224; X86-NEXT:    retl
225;
226; X64-LABEL: test_andn_u32:
227; X64:       # %bb.0:
228; X64-NEXT:    movl %edi, %eax
229; X64-NEXT:    xorl $-1, %eax
230; X64-NEXT:    andl %esi, %eax
231; X64-NEXT:    retq
232;
233; EGPR-LABEL: test_andn_u32:
234; EGPR:       # %bb.0:
235; EGPR-NEXT:    movl %edi, %eax # encoding: [0x89,0xf8]
236; EGPR-NEXT:    xorl $-1, %eax # encoding: [0x83,0xf0,0xff]
237; EGPR-NEXT:    andl %esi, %eax # encoding: [0x21,0xf0]
238; EGPR-NEXT:    retq # encoding: [0xc3]
239  %xor = xor i32 %a0, -1
240  %res = and i32 %xor, %a1
241  ret i32 %res
242}
243
244define i32 @test_bextr_u32(i32 %a0, i32 %a1, i32 %a2) {
245; X86-LABEL: test_bextr_u32:
246; X86:       # %bb.0:
247; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
248; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
249; X86-NEXT:    andl $255, %ecx
250; X86-NEXT:    andl $255, %eax
251; X86-NEXT:    shll $8, %eax
252; X86-NEXT:    orl %ecx, %eax
253; X86-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
254; X86-NEXT:    retl
255;
256; X64-LABEL: test_bextr_u32:
257; X64:       # %bb.0:
258; X64-NEXT:    andl $255, %esi
259; X64-NEXT:    andl $255, %edx
260; X64-NEXT:    shll $8, %edx
261; X64-NEXT:    orl %esi, %edx
262; X64-NEXT:    bextrl %edx, %edi, %eax
263; X64-NEXT:    retq
264;
265; EGPR-LABEL: test_bextr_u32:
266; EGPR:       # %bb.0:
267; EGPR-NEXT:    andl $255, %esi # encoding: [0x81,0xe6,0xff,0x00,0x00,0x00]
268; EGPR-NEXT:    andl $255, %edx # encoding: [0x81,0xe2,0xff,0x00,0x00,0x00]
269; EGPR-NEXT:    shll $8, %edx # encoding: [0xc1,0xe2,0x08]
270; EGPR-NEXT:    orl %esi, %edx # encoding: [0x09,0xf2]
271; EGPR-NEXT:    bextrl %edx, %edi, %eax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x68,0xf7,0xc7]
272; EGPR-NEXT:    retq # encoding: [0xc3]
273  %and1 = and i32 %a1, 255
274  %and2 = and i32 %a2, 255
275  %shl = shl i32 %and2, 8
276  %or = or i32 %and1, %shl
277  %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %or)
278  ret i32 %res
279}
280
281define i32 @test_blsi_u32(i32 %a0) {
282; X86-LABEL: test_blsi_u32:
283; X86:       # %bb.0:
284; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
285; X86-NEXT:    xorl %eax, %eax
286; X86-NEXT:    subl %ecx, %eax
287; X86-NEXT:    andl %ecx, %eax
288; X86-NEXT:    retl
289;
290; X64-LABEL: test_blsi_u32:
291; X64:       # %bb.0:
292; X64-NEXT:    xorl %eax, %eax
293; X64-NEXT:    subl %edi, %eax
294; X64-NEXT:    andl %edi, %eax
295; X64-NEXT:    retq
296;
297; EGPR-LABEL: test_blsi_u32:
298; EGPR:       # %bb.0:
299; EGPR-NEXT:    xorl %eax, %eax # encoding: [0x31,0xc0]
300; EGPR-NEXT:    subl %edi, %eax # encoding: [0x29,0xf8]
301; EGPR-NEXT:    andl %edi, %eax # encoding: [0x21,0xf8]
302; EGPR-NEXT:    retq # encoding: [0xc3]
303  %neg = sub i32 0, %a0
304  %res = and i32 %a0, %neg
305  ret i32 %res
306}
307
308define i32 @test_blsmsk_u32(i32 %a0) {
309; X86-LABEL: test_blsmsk_u32:
310; X86:       # %bb.0:
311; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
312; X86-NEXT:    leal -1(%ecx), %eax
313; X86-NEXT:    xorl %ecx, %eax
314; X86-NEXT:    retl
315;
316; X64-LABEL: test_blsmsk_u32:
317; X64:       # %bb.0:
318; X64-NEXT:    # kill: def $edi killed $edi def $rdi
319; X64-NEXT:    leal -1(%rdi), %eax
320; X64-NEXT:    xorl %edi, %eax
321; X64-NEXT:    retq
322;
323; EGPR-LABEL: test_blsmsk_u32:
324; EGPR:       # %bb.0:
325; EGPR-NEXT:    # kill: def $edi killed $edi def $rdi
326; EGPR-NEXT:    leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff]
327; EGPR-NEXT:    xorl %edi, %eax # encoding: [0x31,0xf8]
328; EGPR-NEXT:    retq # encoding: [0xc3]
329  %dec = sub i32 %a0, 1
330  %res = xor i32 %a0, %dec
331  ret i32 %res
332}
333
334define i32 @test_blsr_u32(i32 %a0) {
335; X86-LABEL: test_blsr_u32:
336; X86:       # %bb.0:
337; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
338; X86-NEXT:    leal -1(%ecx), %eax
339; X86-NEXT:    andl %ecx, %eax
340; X86-NEXT:    retl
341;
342; X64-LABEL: test_blsr_u32:
343; X64:       # %bb.0:
344; X64-NEXT:    # kill: def $edi killed $edi def $rdi
345; X64-NEXT:    leal -1(%rdi), %eax
346; X64-NEXT:    andl %edi, %eax
347; X64-NEXT:    retq
348;
349; EGPR-LABEL: test_blsr_u32:
350; EGPR:       # %bb.0:
351; EGPR-NEXT:    # kill: def $edi killed $edi def $rdi
352; EGPR-NEXT:    leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff]
353; EGPR-NEXT:    andl %edi, %eax # encoding: [0x21,0xf8]
354; EGPR-NEXT:    retq # encoding: [0xc3]
355  %dec = sub i32 %a0, 1
356  %res = and i32 %a0, %dec
357  ret i32 %res
358}
359
360define i32 @test_tzcnt_u32(i32 %a0) {
361; X86-LABEL: test_tzcnt_u32:
362; X86:       # %bb.0:
363; X86-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax
364; X86-NEXT:    retl
365;
366; X64-LABEL: test_tzcnt_u32:
367; X64:       # %bb.0:
368; X64-NEXT:    tzcntl %edi, %eax
369; X64-NEXT:    retq
370;
371; EGPR-LABEL: test_tzcnt_u32:
372; EGPR:       # %bb.0:
373; EGPR-NEXT:    tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]
374; EGPR-NEXT:    retq # encoding: [0xc3]
375  %cmp = icmp ne i32 %a0, 0
376  %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)
377  ret i32 %cttz
378}
379
380declare i16 @llvm.cttz.i16(i16, i1)
381declare i32 @llvm.cttz.i32(i32, i1)
382declare i32 @llvm.x86.bmi.bextr.32(i32, i32)
383