mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-01 07:11:45 +00:00
[X86] X86DAGToDAGISel::matchBitExtract(): pattern b: truncation awareness
Summary: (Not so) boringly identical to pattern a (D62786) Not yet sure how do deal with the last pattern c. Reviewers: RKSimon, craig.topper, spatel Reviewed By: RKSimon Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62793 llvm-svn: 364418
This commit is contained in:
parent
4bde02a2aa
commit
3a16dbe1da
@ -1468,6 +1468,11 @@ public:
|
||||
bool MaskedValueIsZero(SDValue Op, const APInt &Mask,
|
||||
const APInt &DemandedElts, unsigned Depth = 0) const;
|
||||
|
||||
/// Return true if '(Op & Mask) == Mask'.
|
||||
/// Op and Mask are known to be the same type.
|
||||
bool MaskedValueIsAllOnes(SDValue Op, const APInt &Mask,
|
||||
unsigned Depth = 0) const;
|
||||
|
||||
/// Determine which bits of Op are known to be either zero or one and return
|
||||
/// them in Known. For vectors, the known bits are those that are shared by
|
||||
/// every vector element.
|
||||
|
@ -2244,6 +2244,12 @@ bool SelectionDAG::MaskedValueIsZero(SDValue V, const APInt &Mask,
|
||||
return Mask.isSubsetOf(computeKnownBits(V, DemandedElts, Depth).Zero);
|
||||
}
|
||||
|
||||
/// MaskedValueIsAllOnes - Return true if '(Op & Mask) == Mask'.
|
||||
bool SelectionDAG::MaskedValueIsAllOnes(SDValue V, const APInt &Mask,
|
||||
unsigned Depth) const {
|
||||
return Mask.isSubsetOf(computeKnownBits(V, Depth).One);
|
||||
}
|
||||
|
||||
/// isSplatValue - Return true if the vector V has the same value
|
||||
/// across all DemandedElts.
|
||||
bool SelectionDAG::isSplatValue(SDValue V, const APInt &DemandedElts,
|
||||
|
@ -3179,16 +3179,28 @@ bool X86DAGToDAGISel::matchBitExtract(SDNode *Node) {
|
||||
return true;
|
||||
};
|
||||
|
||||
auto isAllOnes = [this, peekThroughOneUseTruncation, NVT](SDValue V) {
|
||||
V = peekThroughOneUseTruncation(V);
|
||||
return CurDAG->MaskedValueIsAllOnes(
|
||||
V, APInt::getLowBitsSet(V.getSimpleValueType().getSizeInBits(),
|
||||
NVT.getSizeInBits()));
|
||||
};
|
||||
|
||||
// b) x & ~(-1 << nbits)
|
||||
auto matchPatternB = [&checkOneUse, &NBits](SDValue Mask) -> bool {
|
||||
auto matchPatternB = [&checkOneUse, isAllOnes, &peekThroughOneUseTruncation,
|
||||
&NBits](SDValue Mask) -> bool {
|
||||
// Match `~()`. Must only have one use!
|
||||
if (!isBitwiseNot(Mask) || !checkOneUse(Mask))
|
||||
if (Mask.getOpcode() != ISD::XOR || !checkOneUse(Mask))
|
||||
return false;
|
||||
// Match `-1 << nbits`. Must only have one use!
|
||||
SDValue M0 = Mask->getOperand(0);
|
||||
// The -1 only has to be all-ones for the final Node's NVT.
|
||||
if (!isAllOnes(Mask->getOperand(1)))
|
||||
return false;
|
||||
// Match `-1 << nbits`. Might be truncated. Must only have one use!
|
||||
SDValue M0 = peekThroughOneUseTruncation(Mask->getOperand(0));
|
||||
if (M0->getOpcode() != ISD::SHL || !checkOneUse(M0))
|
||||
return false;
|
||||
if (!isAllOnesConstant(M0->getOperand(0)))
|
||||
// The -1 only has to be all-ones for the final Node's NVT.
|
||||
if (!isAllOnes(M0->getOperand(0)))
|
||||
return false;
|
||||
NBits = M0->getOperand(1);
|
||||
return true;
|
||||
|
@ -3667,22 +3667,17 @@ define i32 @bextr64_32_b0(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {
|
||||
;
|
||||
; X64-BMI1NOTBM-LABEL: bextr64_32_b0:
|
||||
; X64-BMI1NOTBM: # %bb.0:
|
||||
; X64-BMI1NOTBM-NEXT: movq %rsi, %rcx
|
||||
; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $rcx
|
||||
; X64-BMI1NOTBM-NEXT: shrq %cl, %rdi
|
||||
; X64-BMI1NOTBM-NEXT: movq $-1, %rax
|
||||
; X64-BMI1NOTBM-NEXT: movl %edx, %ecx
|
||||
; X64-BMI1NOTBM-NEXT: shlq %cl, %rax
|
||||
; X64-BMI1NOTBM-NEXT: andnl %edi, %eax, %eax
|
||||
; X64-BMI1NOTBM-NEXT: shll $8, %edx
|
||||
; X64-BMI1NOTBM-NEXT: movzbl %sil, %eax
|
||||
; X64-BMI1NOTBM-NEXT: orl %edx, %eax
|
||||
; X64-BMI1NOTBM-NEXT: bextrq %rax, %rdi, %rax
|
||||
; X64-BMI1NOTBM-NEXT: # kill: def $eax killed $eax killed $rax
|
||||
; X64-BMI1NOTBM-NEXT: retq
|
||||
;
|
||||
; X64-BMI1BMI2-LABEL: bextr64_32_b0:
|
||||
; X64-BMI1BMI2: # %bb.0:
|
||||
; X64-BMI1BMI2-NEXT: # kill: def $edx killed $edx def $rdx
|
||||
; X64-BMI1BMI2-NEXT: shrxq %rsi, %rdi, %rax
|
||||
; X64-BMI1BMI2-NEXT: movq $-1, %rcx
|
||||
; X64-BMI1BMI2-NEXT: shlxq %rdx, %rcx, %rcx
|
||||
; X64-BMI1BMI2-NEXT: andnl %eax, %ecx, %eax
|
||||
; X64-BMI1BMI2-NEXT: bzhil %edx, %eax, %eax
|
||||
; X64-BMI1BMI2-NEXT: retq
|
||||
%shiftedval = lshr i64 %val, %numskipbits
|
||||
%widenumlowbits = zext i8 %numlowbits to i64
|
||||
@ -4001,27 +3996,17 @@ define i32 @bextr64_32_b3(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {
|
||||
;
|
||||
; X64-BMI1NOTBM-LABEL: bextr64_32_b3:
|
||||
; X64-BMI1NOTBM: # %bb.0:
|
||||
; X64-BMI1NOTBM-NEXT: movq %rsi, %rcx
|
||||
; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $rcx
|
||||
; X64-BMI1NOTBM-NEXT: shrq %cl, %rdi
|
||||
; X64-BMI1NOTBM-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF
|
||||
; X64-BMI1NOTBM-NEXT: movl $4294967295, %esi # imm = 0xFFFFFFFF
|
||||
; X64-BMI1NOTBM-NEXT: movl %edx, %ecx
|
||||
; X64-BMI1NOTBM-NEXT: shlq %cl, %rsi
|
||||
; X64-BMI1NOTBM-NEXT: xorl %esi, %eax
|
||||
; X64-BMI1NOTBM-NEXT: andl %edi, %eax
|
||||
; X64-BMI1NOTBM-NEXT: shll $8, %edx
|
||||
; X64-BMI1NOTBM-NEXT: movzbl %sil, %eax
|
||||
; X64-BMI1NOTBM-NEXT: orl %edx, %eax
|
||||
; X64-BMI1NOTBM-NEXT: bextrq %rax, %rdi, %rax
|
||||
; X64-BMI1NOTBM-NEXT: # kill: def $eax killed $eax killed $rax
|
||||
; X64-BMI1NOTBM-NEXT: retq
|
||||
;
|
||||
; X64-BMI1BMI2-LABEL: bextr64_32_b3:
|
||||
; X64-BMI1BMI2: # %bb.0:
|
||||
; X64-BMI1BMI2-NEXT: # kill: def $edx killed $edx def $rdx
|
||||
; X64-BMI1BMI2-NEXT: shrxq %rsi, %rdi, %rax
|
||||
; X64-BMI1BMI2-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF
|
||||
; X64-BMI1BMI2-NEXT: shlxq %rdx, %rcx, %rdx
|
||||
; X64-BMI1BMI2-NEXT: xorl %edx, %ecx
|
||||
; X64-BMI1BMI2-NEXT: andl %ecx, %eax
|
||||
; X64-BMI1BMI2-NEXT: # kill: def $eax killed $eax killed $rax
|
||||
; X64-BMI1BMI2-NEXT: bzhil %edx, %eax, %eax
|
||||
; X64-BMI1BMI2-NEXT: retq
|
||||
%shiftedval = lshr i64 %val, %numskipbits
|
||||
%widenumlowbits = zext i8 %numlowbits to i64
|
||||
|
@ -1845,19 +1845,13 @@ define i32 @bzhi64_32_b0(i64 %val, i8 %numlowbits) nounwind {
|
||||
;
|
||||
; X64-BMI1NOTBM-LABEL: bzhi64_32_b0:
|
||||
; X64-BMI1NOTBM: # %bb.0:
|
||||
; X64-BMI1NOTBM-NEXT: movl %esi, %ecx
|
||||
; X64-BMI1NOTBM-NEXT: movq $-1, %rax
|
||||
; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx
|
||||
; X64-BMI1NOTBM-NEXT: shlq %cl, %rax
|
||||
; X64-BMI1NOTBM-NEXT: andnl %edi, %eax, %eax
|
||||
; X64-BMI1NOTBM-NEXT: shll $8, %esi
|
||||
; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax
|
||||
; X64-BMI1NOTBM-NEXT: retq
|
||||
;
|
||||
; X64-BMI1BMI2-LABEL: bzhi64_32_b0:
|
||||
; X64-BMI1BMI2: # %bb.0:
|
||||
; X64-BMI1BMI2-NEXT: # kill: def $esi killed $esi def $rsi
|
||||
; X64-BMI1BMI2-NEXT: movq $-1, %rax
|
||||
; X64-BMI1BMI2-NEXT: shlxq %rsi, %rax, %rax
|
||||
; X64-BMI1BMI2-NEXT: andnl %edi, %eax, %eax
|
||||
; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax
|
||||
; X64-BMI1BMI2-NEXT: retq
|
||||
%widenumlowbits = zext i8 %numlowbits to i64
|
||||
%notmask = shl nsw i64 -1, %widenumlowbits
|
||||
@ -2032,24 +2026,13 @@ define i32 @bzhi64_32_b3(i64 %val, i8 %numlowbits) nounwind {
|
||||
;
|
||||
; X64-BMI1NOTBM-LABEL: bzhi64_32_b3:
|
||||
; X64-BMI1NOTBM: # %bb.0:
|
||||
; X64-BMI1NOTBM-NEXT: movl %esi, %ecx
|
||||
; X64-BMI1NOTBM-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF
|
||||
; X64-BMI1NOTBM-NEXT: movl $4294967295, %edx # imm = 0xFFFFFFFF
|
||||
; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx
|
||||
; X64-BMI1NOTBM-NEXT: shlq %cl, %rdx
|
||||
; X64-BMI1NOTBM-NEXT: xorl %edx, %eax
|
||||
; X64-BMI1NOTBM-NEXT: andl %edi, %eax
|
||||
; X64-BMI1NOTBM-NEXT: # kill: def $eax killed $eax killed $rax
|
||||
; X64-BMI1NOTBM-NEXT: shll $8, %esi
|
||||
; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax
|
||||
; X64-BMI1NOTBM-NEXT: retq
|
||||
;
|
||||
; X64-BMI1BMI2-LABEL: bzhi64_32_b3:
|
||||
; X64-BMI1BMI2: # %bb.0:
|
||||
; X64-BMI1BMI2-NEXT: # kill: def $esi killed $esi def $rsi
|
||||
; X64-BMI1BMI2-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF
|
||||
; X64-BMI1BMI2-NEXT: shlxq %rsi, %rax, %rcx
|
||||
; X64-BMI1BMI2-NEXT: xorl %ecx, %eax
|
||||
; X64-BMI1BMI2-NEXT: andl %edi, %eax
|
||||
; X64-BMI1BMI2-NEXT: # kill: def $eax killed $eax killed $rax
|
||||
; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax
|
||||
; X64-BMI1BMI2-NEXT: retq
|
||||
%widenumlowbits = zext i8 %numlowbits to i64
|
||||
%notmask = shl nsw i64 4294967295, %widenumlowbits
|
||||
|
Loading…
x
Reference in New Issue
Block a user