xref: /llvm-project/llvm/test/CodeGen/X86/bmi-x86_64.ll (revision 2d92f7de800a1b1b3dca3dab1e11da712cd55f2b)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefixes=CHECK,BEXTR-SLOW,BMI1-SLOW
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+bmi2 | FileCheck %s --check-prefixes=CHECK,BEXTR-SLOW,BMI2-SLOW
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+fast-bextr | FileCheck %s --check-prefixes=CHECK,BEXTR-FAST
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+bmi2,+fast-bextr | FileCheck %s --check-prefixes=CHECK,BEXTR-FAST
6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+bmi2,+egpr --show-mc-encoding | FileCheck %s --check-prefix=EGPR
7
8declare i64 @llvm.x86.bmi.bextr.64(i64, i64)
9
10define i64 @bextr64(i64 %x, i64 %y)   {
11; CHECK-LABEL: bextr64:
12; CHECK:       # %bb.0:
13; CHECK-NEXT:    bextrq %rsi, %rdi, %rax
14; CHECK-NEXT:    retq
15;
16; EGPR-LABEL: bextr64:
17; EGPR:       # %bb.0:
18; EGPR-NEXT:    bextrq %rsi, %rdi, %rax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0xc8,0xf7,0xc7]
19; EGPR-NEXT:    retq # encoding: [0xc3]
20  %tmp = tail call i64 @llvm.x86.bmi.bextr.64(i64 %x, i64 %y)
21  ret i64 %tmp
22}
23
24define i64 @bextr64b(i64 %x)  uwtable  ssp {
25; BEXTR-SLOW-LABEL: bextr64b:
26; BEXTR-SLOW:       # %bb.0:
27; BEXTR-SLOW-NEXT:    movq %rdi, %rax
28; BEXTR-SLOW-NEXT:    shrl $4, %eax
29; BEXTR-SLOW-NEXT:    andl $4095, %eax # imm = 0xFFF
30; BEXTR-SLOW-NEXT:    retq
31;
32; BEXTR-FAST-LABEL: bextr64b:
33; BEXTR-FAST:       # %bb.0:
34; BEXTR-FAST-NEXT:    movl $3076, %eax # imm = 0xC04
35; BEXTR-FAST-NEXT:    bextrl %eax, %edi, %eax
36; BEXTR-FAST-NEXT:    retq
37;
38; EGPR-LABEL: bextr64b:
39; EGPR:       # %bb.0:
40; EGPR-NEXT:    movq %rdi, %rax # encoding: [0x48,0x89,0xf8]
41; EGPR-NEXT:    shrl $4, %eax # encoding: [0xc1,0xe8,0x04]
42; EGPR-NEXT:    andl $4095, %eax # encoding: [0x25,0xff,0x0f,0x00,0x00]
43; EGPR-NEXT:    # imm = 0xFFF
44; EGPR-NEXT:    retq # encoding: [0xc3]
45  %1 = lshr i64 %x, 4
46  %2 = and i64 %1, 4095
47  ret i64 %2
48}
49
50; Make sure we still use the AH subreg trick to extract 15:8
51define i64 @bextr64_subreg(i64 %x)  uwtable  ssp {
52; CHECK-LABEL: bextr64_subreg:
53; CHECK:       # %bb.0:
54; CHECK-NEXT:    movq %rdi, %rax
55; CHECK-NEXT:    movzbl %ah, %eax
56; CHECK-NEXT:    retq
57;
58; EGPR-LABEL: bextr64_subreg:
59; EGPR:       # %bb.0:
60; EGPR-NEXT:    movq %rdi, %rax # encoding: [0x48,0x89,0xf8]
61; EGPR-NEXT:    movzbl %ah, %eax # encoding: [0x0f,0xb6,0xc4]
62; EGPR-NEXT:    retq # encoding: [0xc3]
63  %1 = lshr i64 %x, 8
64  %2 = and i64 %1, 255
65  ret i64 %2
66}
67
68define i64 @bextr64b_load(ptr %x) {
69; BEXTR-SLOW-LABEL: bextr64b_load:
70; BEXTR-SLOW:       # %bb.0:
71; BEXTR-SLOW-NEXT:    movl (%rdi), %eax
72; BEXTR-SLOW-NEXT:    shrl $4, %eax
73; BEXTR-SLOW-NEXT:    andl $4095, %eax # imm = 0xFFF
74; BEXTR-SLOW-NEXT:    retq
75;
76; BEXTR-FAST-LABEL: bextr64b_load:
77; BEXTR-FAST:       # %bb.0:
78; BEXTR-FAST-NEXT:    movl $3076, %eax # imm = 0xC04
79; BEXTR-FAST-NEXT:    bextrl %eax, (%rdi), %eax
80; BEXTR-FAST-NEXT:    retq
81;
82; EGPR-LABEL: bextr64b_load:
83; EGPR:       # %bb.0:
84; EGPR-NEXT:    movl (%rdi), %eax # encoding: [0x8b,0x07]
85; EGPR-NEXT:    shrl $4, %eax # encoding: [0xc1,0xe8,0x04]
86; EGPR-NEXT:    andl $4095, %eax # encoding: [0x25,0xff,0x0f,0x00,0x00]
87; EGPR-NEXT:    # imm = 0xFFF
88; EGPR-NEXT:    retq # encoding: [0xc3]
89  %1 = load i64, ptr %x, align 8
90  %2 = lshr i64 %1, 4
91  %3 = and i64 %2, 4095
92  ret i64 %3
93}
94
95; PR34042
96define i64 @bextr64c(i64 %x, i32 %y) {
97; CHECK-LABEL: bextr64c:
98; CHECK:       # %bb.0:
99; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
100; CHECK-NEXT:    bextrq %rsi, %rdi, %rax
101; CHECK-NEXT:    retq
102;
103; EGPR-LABEL: bextr64c:
104; EGPR:       # %bb.0:
105; EGPR-NEXT:    # kill: def $esi killed $esi def $rsi
106; EGPR-NEXT:    bextrq %rsi, %rdi, %rax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0xc8,0xf7,0xc7]
107; EGPR-NEXT:    retq # encoding: [0xc3]
108  %tmp0 = sext i32 %y to i64
109  %tmp1 = tail call i64 @llvm.x86.bmi.bextr.64(i64 %x, i64 %tmp0)
110  ret i64 %tmp1
111}
112
113define i64 @bextr64d(i64 %a) {
114; BMI1-SLOW-LABEL: bextr64d:
115; BMI1-SLOW:       # %bb.0: # %entry
116; BMI1-SLOW-NEXT:    shrq $2, %rdi
117; BMI1-SLOW-NEXT:    movl $8448, %eax # imm = 0x2100
118; BMI1-SLOW-NEXT:    bextrq %rax, %rdi, %rax
119; BMI1-SLOW-NEXT:    retq
120;
121; BMI2-SLOW-LABEL: bextr64d:
122; BMI2-SLOW:       # %bb.0: # %entry
123; BMI2-SLOW-NEXT:    movl $35, %eax
124; BMI2-SLOW-NEXT:    bzhiq %rax, %rdi, %rax
125; BMI2-SLOW-NEXT:    shrq $2, %rax
126; BMI2-SLOW-NEXT:    retq
127;
128; BEXTR-FAST-LABEL: bextr64d:
129; BEXTR-FAST:       # %bb.0: # %entry
130; BEXTR-FAST-NEXT:    movl $8450, %eax # imm = 0x2102
131; BEXTR-FAST-NEXT:    bextrq %rax, %rdi, %rax
132; BEXTR-FAST-NEXT:    retq
133;
134; EGPR-LABEL: bextr64d:
135; EGPR:       # %bb.0: # %entry
136; EGPR-NEXT:    movl $35, %eax # encoding: [0xb8,0x23,0x00,0x00,0x00]
137; EGPR-NEXT:    bzhiq %rax, %rdi, %rax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0xf8,0xf5,0xc7]
138; EGPR-NEXT:    shrq $2, %rax # encoding: [0x48,0xc1,0xe8,0x02]
139; EGPR-NEXT:    retq # encoding: [0xc3]
140entry:
141  %shr = lshr i64 %a, 2
142  %and = and i64 %shr, 8589934591
143  ret i64 %and
144}
145
146define i64 @bextr64d_load(ptr %aptr) {
147; BMI1-SLOW-LABEL: bextr64d_load:
148; BMI1-SLOW:       # %bb.0: # %entry
149; BMI1-SLOW-NEXT:    movq (%rdi), %rax
150; BMI1-SLOW-NEXT:    shrq $2, %rax
151; BMI1-SLOW-NEXT:    movl $8448, %ecx # imm = 0x2100
152; BMI1-SLOW-NEXT:    bextrq %rcx, %rax, %rax
153; BMI1-SLOW-NEXT:    retq
154;
155; BMI2-SLOW-LABEL: bextr64d_load:
156; BMI2-SLOW:       # %bb.0: # %entry
157; BMI2-SLOW-NEXT:    movl $35, %eax
158; BMI2-SLOW-NEXT:    bzhiq %rax, (%rdi), %rax
159; BMI2-SLOW-NEXT:    shrq $2, %rax
160; BMI2-SLOW-NEXT:    retq
161;
162; BEXTR-FAST-LABEL: bextr64d_load:
163; BEXTR-FAST:       # %bb.0: # %entry
164; BEXTR-FAST-NEXT:    movl $8450, %eax # imm = 0x2102
165; BEXTR-FAST-NEXT:    bextrq %rax, (%rdi), %rax
166; BEXTR-FAST-NEXT:    retq
167;
168; EGPR-LABEL: bextr64d_load:
169; EGPR:       # %bb.0: # %entry
170; EGPR-NEXT:    movl $35, %eax # encoding: [0xb8,0x23,0x00,0x00,0x00]
171; EGPR-NEXT:    bzhiq %rax, (%rdi), %rax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0xf8,0xf5,0x07]
172; EGPR-NEXT:    shrq $2, %rax # encoding: [0x48,0xc1,0xe8,0x02]
173; EGPR-NEXT:    retq # encoding: [0xc3]
174entry:
175  %a = load i64, ptr %aptr, align 8
176  %shr = lshr i64 %a, 2
177  %and = and i64 %shr, 8589934591
178  ret i64 %and
179}
180
181define i64 @non_bextr64(i64 %x) {
182; CHECK-LABEL: non_bextr64:
183; CHECK:       # %bb.0: # %entry
184; CHECK-NEXT:    shrq $2, %rdi
185; CHECK-NEXT:    movabsq $8589934590, %rax # imm = 0x1FFFFFFFE
186; CHECK-NEXT:    andq %rdi, %rax
187; CHECK-NEXT:    retq
188;
189; EGPR-LABEL: non_bextr64:
190; EGPR:       # %bb.0: # %entry
191; EGPR-NEXT:    shrq $2, %rdi # encoding: [0x48,0xc1,0xef,0x02]
192; EGPR-NEXT:    movabsq $8589934590, %rax # encoding: [0x48,0xb8,0xfe,0xff,0xff,0xff,0x01,0x00,0x00,0x00]
193; EGPR-NEXT:    # imm = 0x1FFFFFFFE
194; EGPR-NEXT:    andq %rdi, %rax # encoding: [0x48,0x21,0xf8]
195; EGPR-NEXT:    retq # encoding: [0xc3]
196entry:
197  %shr = lshr i64 %x, 2
198  %and = and i64 %shr, 8589934590
199  ret i64 %and
200}
201