Skip to content

Commit 76fd79b

Browse files
committed
[X86] Recognize standalone (1 << nbits) - 1 pattern as bzhi
This can be thought as a subcase of `x & ((1 << nbits) - 1)` where x == -1 Differential Revision: https://reviews.llvm.org/D155622
1 parent c1013a6 commit 76fd79b

File tree

3 files changed

+94
-159
lines changed

3 files changed

+94
-159
lines changed

llvm/lib/Target/X86/X86ISelDAGToDAG.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3504,9 +3504,11 @@ bool X86DAGToDAGISel::foldLoadStoreIntoMemOperand(SDNode *Node) {
35043504
// b) x & ~(-1 << nbits)
35053505
// c) x & (-1 >> (32 - y))
35063506
// d) x << (32 - y) >> (32 - y)
3507+
// e) (1 << nbits) - 1
35073508
bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
35083509
assert(
3509-
(Node->getOpcode() == ISD::AND || Node->getOpcode() == ISD::SRL) &&
3510+
(Node->getOpcode() == ISD::ADD || Node->getOpcode() == ISD::AND ||
3511+
Node->getOpcode() == ISD::SRL) &&
35103512
"Should be either an and-mask, or right-shift after clearing high bits.");
35113513

35123514
// BEXTR is BMI instruction, BZHI is BMI2 instruction. We need at least one.
@@ -3692,6 +3694,8 @@ bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
36923694
if (!matchLowBitMask(Mask))
36933695
return false;
36943696
}
3697+
} else if (matchLowBitMask(SDValue(Node, 0))) {
3698+
X = CurDAG->getAllOnesConstant(SDLoc(Node), NVT);
36953699
} else if (!matchPatternD(Node))
36963700
return false;
36973701

@@ -5067,6 +5071,9 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
50675071

50685072
[[fallthrough]];
50695073
case ISD::ADD:
5074+
if (Opcode == ISD::ADD && matchBitExtract(Node))
5075+
return;
5076+
[[fallthrough]];
50705077
case ISD::SUB: {
50715078
// Try to avoid folding immediates with multiple uses for optsize.
50725079
// This code tries to select to register form directly to avoid going

llvm/test/CodeGen/X86/extract-bits.ll

Lines changed: 36 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4068,10 +4068,8 @@ define i32 @bextr32_c0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
40684068
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx
40694069
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax
40704070
; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %esi
4071-
; X86-BMI2-NEXT: movl %ebx, %eax
4072-
; X86-BMI2-NEXT: negb %al
4073-
; X86-BMI2-NEXT: movl $-1, %ecx
4074-
; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax
4071+
; X86-BMI2-NEXT: movl $-1, %eax
4072+
; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax
40754073
; X86-BMI2-NEXT: movl %eax, (%esp)
40764074
; X86-BMI2-NEXT: calll use32@PLT
40774075
; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax
@@ -4131,10 +4129,8 @@ define i32 @bextr32_c0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {
41314129
; X64-BMI2-NEXT: pushq %rax
41324130
; X64-BMI2-NEXT: movl %edx, %ebx
41334131
; X64-BMI2-NEXT: shrxl %esi, %edi, %ebp
4134-
; X64-BMI2-NEXT: movl %ebx, %eax
4135-
; X64-BMI2-NEXT: negb %al
4136-
; X64-BMI2-NEXT: movl $-1, %ecx
4137-
; X64-BMI2-NEXT: shrxl %eax, %ecx, %edi
4132+
; X64-BMI2-NEXT: movl $-1, %eax
4133+
; X64-BMI2-NEXT: bzhil %edx, %eax, %edi
41384134
; X64-BMI2-NEXT: callq use32@PLT
41394135
; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax
41404136
; X64-BMI2-NEXT: addq $8, %rsp
@@ -4202,10 +4198,8 @@ define i32 @bextr32_c1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) noun
42024198
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx
42034199
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax
42044200
; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %esi
4205-
; X86-BMI2-NEXT: movl %ebx, %eax
4206-
; X86-BMI2-NEXT: negb %al
4207-
; X86-BMI2-NEXT: movl $-1, %ecx
4208-
; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax
4201+
; X86-BMI2-NEXT: movl $-1, %eax
4202+
; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax
42094203
; X86-BMI2-NEXT: movl %eax, (%esp)
42104204
; X86-BMI2-NEXT: calll use32@PLT
42114205
; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax
@@ -4265,10 +4259,8 @@ define i32 @bextr32_c1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) noun
42654259
; X64-BMI2-NEXT: pushq %rax
42664260
; X64-BMI2-NEXT: movl %edx, %ebx
42674261
; X64-BMI2-NEXT: shrxl %esi, %edi, %ebp
4268-
; X64-BMI2-NEXT: movl %ebx, %eax
4269-
; X64-BMI2-NEXT: negb %al
4270-
; X64-BMI2-NEXT: movl $-1, %ecx
4271-
; X64-BMI2-NEXT: shrxl %eax, %ecx, %edi
4262+
; X64-BMI2-NEXT: movl $-1, %eax
4263+
; X64-BMI2-NEXT: bzhil %edx, %eax, %edi
42724264
; X64-BMI2-NEXT: callq use32@PLT
42734265
; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax
42744266
; X64-BMI2-NEXT: addq $8, %rsp
@@ -4341,10 +4333,8 @@ define i32 @bextr32_c2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind
43414333
; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
43424334
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
43434335
; X86-BMI2-NEXT: shrxl %ecx, (%eax), %esi
4344-
; X86-BMI2-NEXT: movl %ebx, %eax
4345-
; X86-BMI2-NEXT: negb %al
4346-
; X86-BMI2-NEXT: movl $-1, %ecx
4347-
; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax
4336+
; X86-BMI2-NEXT: movl $-1, %eax
4337+
; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax
43484338
; X86-BMI2-NEXT: movl %eax, (%esp)
43494339
; X86-BMI2-NEXT: calll use32@PLT
43504340
; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax
@@ -4404,10 +4394,8 @@ define i32 @bextr32_c2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind
44044394
; X64-BMI2-NEXT: pushq %rax
44054395
; X64-BMI2-NEXT: movl %edx, %ebx
44064396
; X64-BMI2-NEXT: shrxl %esi, (%rdi), %ebp
4407-
; X64-BMI2-NEXT: movl %ebx, %eax
4408-
; X64-BMI2-NEXT: negb %al
4409-
; X64-BMI2-NEXT: movl $-1, %ecx
4410-
; X64-BMI2-NEXT: shrxl %eax, %ecx, %edi
4397+
; X64-BMI2-NEXT: movl $-1, %eax
4398+
; X64-BMI2-NEXT: bzhil %edx, %eax, %edi
44114399
; X64-BMI2-NEXT: callq use32@PLT
44124400
; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax
44134401
; X64-BMI2-NEXT: addq $8, %rsp
@@ -4479,10 +4467,8 @@ define i32 @bextr32_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) n
44794467
; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax
44804468
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
44814469
; X86-BMI2-NEXT: shrxl %ecx, (%eax), %esi
4482-
; X86-BMI2-NEXT: movl %ebx, %eax
4483-
; X86-BMI2-NEXT: negb %al
4484-
; X86-BMI2-NEXT: movl $-1, %ecx
4485-
; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax
4470+
; X86-BMI2-NEXT: movl $-1, %eax
4471+
; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax
44864472
; X86-BMI2-NEXT: movl %eax, (%esp)
44874473
; X86-BMI2-NEXT: calll use32@PLT
44884474
; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax
@@ -4542,10 +4528,8 @@ define i32 @bextr32_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) n
45424528
; X64-BMI2-NEXT: pushq %rax
45434529
; X64-BMI2-NEXT: movl %edx, %ebx
45444530
; X64-BMI2-NEXT: shrxl %esi, (%rdi), %ebp
4545-
; X64-BMI2-NEXT: movl %ebx, %eax
4546-
; X64-BMI2-NEXT: negb %al
4547-
; X64-BMI2-NEXT: movl $-1, %ecx
4548-
; X64-BMI2-NEXT: shrxl %eax, %ecx, %edi
4531+
; X64-BMI2-NEXT: movl $-1, %eax
4532+
; X64-BMI2-NEXT: bzhil %edx, %eax, %edi
45494533
; X64-BMI2-NEXT: callq use32@PLT
45504534
; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax
45514535
; X64-BMI2-NEXT: addq $8, %rsp
@@ -4616,10 +4600,8 @@ define i32 @bextr32_c4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits)
46164600
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx
46174601
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax
46184602
; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %esi
4619-
; X86-BMI2-NEXT: movl %ebx, %eax
4620-
; X86-BMI2-NEXT: negb %al
4621-
; X86-BMI2-NEXT: movl $-1, %ecx
4622-
; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax
4603+
; X86-BMI2-NEXT: movl $-1, %eax
4604+
; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax
46234605
; X86-BMI2-NEXT: movl %eax, (%esp)
46244606
; X86-BMI2-NEXT: calll use32@PLT
46254607
; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax
@@ -4679,10 +4661,8 @@ define i32 @bextr32_c4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits)
46794661
; X64-BMI2-NEXT: pushq %rax
46804662
; X64-BMI2-NEXT: movl %edx, %ebx
46814663
; X64-BMI2-NEXT: shrxl %esi, %edi, %ebp
4682-
; X64-BMI2-NEXT: movl %ebx, %eax
4683-
; X64-BMI2-NEXT: negb %al
4684-
; X64-BMI2-NEXT: movl $-1, %ecx
4685-
; X64-BMI2-NEXT: shrxl %eax, %ecx, %edi
4664+
; X64-BMI2-NEXT: movl $-1, %eax
4665+
; X64-BMI2-NEXT: bzhil %edx, %eax, %edi
46864666
; X64-BMI2-NEXT: callq use32@PLT
46874667
; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax
46884668
; X64-BMI2-NEXT: addq $8, %rsp
@@ -4761,10 +4741,8 @@ define i32 @bextr32_c5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits
47614741
; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx
47624742
; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edi
47634743
; X86-BMI2-NEXT: shrxl %edi, {{[0-9]+}}(%esp), %esi
4764-
; X86-BMI2-NEXT: movl %ebx, %eax
4765-
; X86-BMI2-NEXT: negb %al
4766-
; X86-BMI2-NEXT: movl $-1, %ecx
4767-
; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax
4744+
; X86-BMI2-NEXT: movl $-1, %eax
4745+
; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax
47684746
; X86-BMI2-NEXT: movl %eax, (%esp)
47694747
; X86-BMI2-NEXT: calll use32@PLT
47704748
; X86-BMI2-NEXT: bzhil %ebx, %esi, %esi
@@ -4833,10 +4811,8 @@ define i32 @bextr32_c5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits
48334811
; X64-BMI2-NEXT: movl %edx, %ebx
48344812
; X64-BMI2-NEXT: movl %esi, %ebp
48354813
; X64-BMI2-NEXT: shrxl %esi, %edi, %r14d
4836-
; X64-BMI2-NEXT: movl %ebx, %eax
4837-
; X64-BMI2-NEXT: negb %al
4838-
; X64-BMI2-NEXT: movl $-1, %ecx
4839-
; X64-BMI2-NEXT: shrxl %eax, %ecx, %edi
4814+
; X64-BMI2-NEXT: movl $-1, %eax
4815+
; X64-BMI2-NEXT: bzhil %edx, %eax, %edi
48404816
; X64-BMI2-NEXT: callq use32@PLT
48414817
; X64-BMI2-NEXT: bzhil %ebx, %r14d, %ebx
48424818
; X64-BMI2-NEXT: movl %ebp, %edi
@@ -5045,10 +5021,8 @@ define i64 @bextr64_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {
50455021
; X64-BMI2-NEXT: pushq %rax
50465022
; X64-BMI2-NEXT: movq %rdx, %rbx
50475023
; X64-BMI2-NEXT: shrxq %rsi, %rdi, %r14
5048-
; X64-BMI2-NEXT: movl %ebx, %eax
5049-
; X64-BMI2-NEXT: negb %al
5050-
; X64-BMI2-NEXT: movq $-1, %rcx
5051-
; X64-BMI2-NEXT: shrxq %rax, %rcx, %rdi
5024+
; X64-BMI2-NEXT: movq $-1, %rax
5025+
; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rdi
50525026
; X64-BMI2-NEXT: callq use64@PLT
50535027
; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax
50545028
; X64-BMI2-NEXT: addq $8, %rsp
@@ -5252,10 +5226,8 @@ define i64 @bextr64_c1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) noun
52525226
; X64-BMI2-NEXT: movl %edx, %ebx
52535227
; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi
52545228
; X64-BMI2-NEXT: shrxq %rsi, %rdi, %r14
5255-
; X64-BMI2-NEXT: movl %ebx, %eax
5256-
; X64-BMI2-NEXT: negb %al
5257-
; X64-BMI2-NEXT: movq $-1, %rcx
5258-
; X64-BMI2-NEXT: shrxq %rax, %rcx, %rdi
5229+
; X64-BMI2-NEXT: movq $-1, %rax
5230+
; X64-BMI2-NEXT: bzhiq %rbx, %rax, %rdi
52595231
; X64-BMI2-NEXT: callq use64@PLT
52605232
; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax
52615233
; X64-BMI2-NEXT: addq $8, %rsp
@@ -5463,10 +5435,8 @@ define i64 @bextr64_c2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind
54635435
; X64-BMI2-NEXT: pushq %rax
54645436
; X64-BMI2-NEXT: movq %rdx, %rbx
54655437
; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %r14
5466-
; X64-BMI2-NEXT: movl %ebx, %eax
5467-
; X64-BMI2-NEXT: negb %al
5468-
; X64-BMI2-NEXT: movq $-1, %rcx
5469-
; X64-BMI2-NEXT: shrxq %rax, %rcx, %rdi
5438+
; X64-BMI2-NEXT: movq $-1, %rax
5439+
; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rdi
54705440
; X64-BMI2-NEXT: callq use64@PLT
54715441
; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax
54725442
; X64-BMI2-NEXT: addq $8, %rsp
@@ -5674,10 +5644,8 @@ define i64 @bextr64_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) n
56745644
; X64-BMI2-NEXT: movl %edx, %ebx
56755645
; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi
56765646
; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %r14
5677-
; X64-BMI2-NEXT: movl %ebx, %eax
5678-
; X64-BMI2-NEXT: negb %al
5679-
; X64-BMI2-NEXT: movq $-1, %rcx
5680-
; X64-BMI2-NEXT: shrxq %rax, %rcx, %rdi
5647+
; X64-BMI2-NEXT: movq $-1, %rax
5648+
; X64-BMI2-NEXT: bzhiq %rbx, %rax, %rdi
56815649
; X64-BMI2-NEXT: callq use64@PLT
56825650
; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax
56835651
; X64-BMI2-NEXT: addq $8, %rsp
@@ -5883,10 +5851,8 @@ define i64 @bextr64_c4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits)
58835851
; X64-BMI2-NEXT: pushq %rax
58845852
; X64-BMI2-NEXT: movq %rdx, %rbx
58855853
; X64-BMI2-NEXT: shrxq %rsi, %rdi, %r14
5886-
; X64-BMI2-NEXT: movl %ebx, %eax
5887-
; X64-BMI2-NEXT: negb %al
5888-
; X64-BMI2-NEXT: movq $-1, %rcx
5889-
; X64-BMI2-NEXT: shrxq %rax, %rcx, %rdi
5854+
; X64-BMI2-NEXT: movq $-1, %rax
5855+
; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rdi
58905856
; X64-BMI2-NEXT: callq use64@PLT
58915857
; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax
58925858
; X64-BMI2-NEXT: addq $8, %rsp
@@ -6109,10 +6075,8 @@ define i64 @bextr64_c5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits
61096075
; X64-BMI2-NEXT: movq %rdx, %rbx
61106076
; X64-BMI2-NEXT: movq %rsi, %r14
61116077
; X64-BMI2-NEXT: shrxq %rsi, %rdi, %r15
6112-
; X64-BMI2-NEXT: movl %ebx, %eax
6113-
; X64-BMI2-NEXT: negb %al
6114-
; X64-BMI2-NEXT: movq $-1, %rcx
6115-
; X64-BMI2-NEXT: shrxq %rax, %rcx, %rdi
6078+
; X64-BMI2-NEXT: movq $-1, %rax
6079+
; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rdi
61166080
; X64-BMI2-NEXT: callq use64@PLT
61176081
; X64-BMI2-NEXT: bzhiq %rbx, %r15, %rbx
61186082
; X64-BMI2-NEXT: movq %r14, %rdi

0 commit comments

Comments
 (0)