forked from OSchip/llvm-project
[X86][XOP] Added VPERMIL2PD/VPERMIL2PS shuffle mask comment decoding
llvm-svn: 271809
This commit is contained in:
parent
8e63999bee
commit
2ead861d07
|
@ -1422,6 +1422,40 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case X86::VPERMIL2PDrm:
|
||||
case X86::VPERMIL2PSrm:
|
||||
case X86::VPERMIL2PDrmY:
|
||||
case X86::VPERMIL2PSrmY: {
|
||||
if (!OutStreamer->isVerboseAsm())
|
||||
break;
|
||||
assert(MI->getNumOperands() > 7 &&
|
||||
"We should always have at least 7 operands!");
|
||||
const MachineOperand &DstOp = MI->getOperand(0);
|
||||
const MachineOperand &SrcOp1 = MI->getOperand(1);
|
||||
const MachineOperand &SrcOp2 = MI->getOperand(2);
|
||||
const MachineOperand &MaskOp = MI->getOperand(6);
|
||||
const MachineOperand &CtrlOp = MI->getOperand(MI->getNumOperands() - 1);
|
||||
|
||||
if (!CtrlOp.isImm())
|
||||
break;
|
||||
|
||||
unsigned ElSize;
|
||||
switch (MI->getOpcode()) {
|
||||
default: llvm_unreachable("Invalid opcode");
|
||||
case X86::VPERMIL2PSrm: case X86::VPERMIL2PSrmY: ElSize = 32; break;
|
||||
case X86::VPERMIL2PDrm: case X86::VPERMIL2PDrmY: ElSize = 64; break;
|
||||
}
|
||||
|
||||
if (auto *C = getConstantFromPool(*MI, MaskOp)) {
|
||||
SmallVector<int, 16> Mask;
|
||||
DecodeVPERMIL2PMask(C, (unsigned)CtrlOp.getImm(), ElSize, Mask);
|
||||
if (!Mask.empty())
|
||||
OutStreamer->AddComment(getShuffleComment(DstOp, SrcOp1, SrcOp2, Mask));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case X86::VPPERMrrm: {
|
||||
if (!OutStreamer->isVerboseAsm())
|
||||
break;
|
||||
|
|
|
@ -153,6 +153,77 @@ void DecodeVPERMILPMask(const Constant *C, unsigned ElSize,
|
|||
// TODO: Handle funny-looking vectors too.
|
||||
}
|
||||
|
||||
void DecodeVPERMIL2PMask(const Constant *C, unsigned M2Z, unsigned ElSize,
|
||||
SmallVectorImpl<int> &ShuffleMask) {
|
||||
Type *MaskTy = C->getType();
|
||||
|
||||
unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits();
|
||||
if (MaskTySize != 128 && MaskTySize != 256)
|
||||
return;
|
||||
|
||||
// Only support vector types.
|
||||
if (!MaskTy->isVectorTy())
|
||||
return;
|
||||
|
||||
// Make sure its an integer type.
|
||||
Type *VecEltTy = MaskTy->getVectorElementType();
|
||||
if (!VecEltTy->isIntegerTy())
|
||||
return;
|
||||
|
||||
// Support any element type from byte up to element size.
|
||||
// This is necessary primarily because 64-bit elements get split to 32-bit
|
||||
// in the constant pool on 32-bit target.
|
||||
unsigned EltTySize = VecEltTy->getIntegerBitWidth();
|
||||
if (EltTySize < 8 || EltTySize > ElSize)
|
||||
return;
|
||||
|
||||
unsigned NumElements = MaskTySize / ElSize;
|
||||
assert((NumElements == 2 || NumElements == 4 || NumElements == 8) &&
|
||||
"Unexpected number of vector elements.");
|
||||
ShuffleMask.reserve(NumElements);
|
||||
unsigned NumElementsPerLane = 128 / ElSize;
|
||||
unsigned Factor = ElSize / EltTySize;
|
||||
|
||||
for (unsigned i = 0; i < NumElements; ++i) {
|
||||
Constant *COp = C->getAggregateElement(i * Factor);
|
||||
if (!COp) {
|
||||
ShuffleMask.clear();
|
||||
return;
|
||||
} else if (isa<UndefValue>(COp)) {
|
||||
ShuffleMask.push_back(SM_SentinelUndef);
|
||||
continue;
|
||||
}
|
||||
|
||||
// VPERMIL2 Operation.
|
||||
// Bits[3] - Match Bit.
|
||||
// Bits[2:1] - (Per Lane) PD Shuffle Mask.
|
||||
// Bits[2:0] - (Per Lane) PS Shuffle Mask.
|
||||
uint64_t Selector = cast<ConstantInt>(COp)->getZExtValue();
|
||||
int MatchBit = (Selector >> 3) & 0x1;
|
||||
|
||||
// M2Z[0:1] MatchBit
|
||||
// 0Xb X Source selected by Selector index.
|
||||
// 10b 0 Source selected by Selector index.
|
||||
// 10b 1 Zero.
|
||||
// 11b 0 Zero.
|
||||
// 11b 1 Source selected by Selector index.
|
||||
if ((M2Z & 0x2) != 0 && MatchBit != (M2Z & 0x1)) {
|
||||
ShuffleMask.push_back(SM_SentinelZero);
|
||||
continue;
|
||||
}
|
||||
|
||||
int Index = Selector & 0x3;
|
||||
Index >>= (ElSize == 64 ? 1 : 0);
|
||||
Index += (i / NumElementsPerLane) * NumElementsPerLane;
|
||||
|
||||
int Src = (Selector >> 2) & 0x1;
|
||||
Index += Src * NumElements;
|
||||
ShuffleMask.push_back(Index);
|
||||
}
|
||||
|
||||
// TODO: Handle funny-looking vectors too.
|
||||
}
|
||||
|
||||
void DecodeVPPERMMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) {
|
||||
Type *MaskTy = C->getType();
|
||||
assert(MaskTy->getPrimitiveSizeInBits() == 128);
|
||||
|
|
|
@ -32,6 +32,10 @@ void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask);
|
|||
void DecodeVPERMILPMask(const Constant *C, unsigned ElSize,
|
||||
SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
/// Decode a VPERMILP2 variable mask from an IR-level vector constant.
|
||||
void DecodeVPERMIL2PMask(const Constant *C, unsigned MatchImm, unsigned ElSize,
|
||||
SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
/// Decode a VPPERM variable mask from an IR-level vector constant.
|
||||
void DecodeVPPERMMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ define <8 x float> @combine_vpermil2ps256_identity(<8 x float> %a0, <8 x float>
|
|||
define <4 x float> @combine_vpermil2ps_blend_with_zero(<4 x float> %a0, <4 x float> %a1) {
|
||||
; CHECK-LABEL: combine_vpermil2ps_blend_with_zero:
|
||||
; CHECK: # BB#0:
|
||||
; CHECK-NEXT: vpermil2ps $2, {{.*}}(%rip), %xmm1, %xmm0, %xmm0
|
||||
; CHECK-NEXT: vpermil2ps {{.*#+}} xmm0 = zero,xmm0[1,2,3]
|
||||
; CHECK-NEXT: retq
|
||||
%res0 = call <4 x float> @llvm.x86.xop.vpermil2ps(<4 x float> %a0, <4 x float> %a1, <4 x i32> <i32 8, i32 1, i32 2, i32 3>, i8 2)
|
||||
ret <4 x float> %res0
|
||||
|
|
|
@ -95,10 +95,94 @@ define <16 x i8> @vpperm_shuffle_general(<16 x i8> %a0, <16 x i8> %a1) {
|
|||
; VPERMIL2
|
||||
;
|
||||
|
||||
declare <2 x double> @llvm.x86.xop.vpermil2pd(<2 x double>, <2 x double>, <2 x double>, i8) nounwind readnone
|
||||
declare <4 x double> @llvm.x86.xop.vpermil2pd.256(<4 x double>, <4 x double>, <4 x double>, i8) nounwind readnone
|
||||
define <2 x double> @vpermil2pd_21(<2 x double> %a0, <2 x double> %a1) {
|
||||
; X32-LABEL: vpermil2pd_21:
|
||||
; X32: # BB#0:
|
||||
; X32-NEXT: vpermil2pd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
; X64-LABEL: vpermil2pd_21:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: vpermil2pd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
|
||||
; X64-NEXT: retq
|
||||
%1 = call <2 x double> @llvm.x86.xop.vpermil2pd(<2 x double> %a0, <2 x double> %a1, <2 x i64> <i64 4, i64 2>, i8 0)
|
||||
ret <2 x double> %1
|
||||
}
|
||||
|
||||
declare <4 x float> @llvm.x86.xop.vpermil2ps(<4 x float>, <4 x float>, <4 x float>, i8) nounwind readnone
|
||||
declare <8 x float> @llvm.x86.xop.vpermil2ps.256(<8 x float>, <8 x float>, <8 x float>, i8) nounwind readnone
|
||||
define <4 x double> @vpermil2pd256_0062(<4 x double> %a0, <4 x double> %a1) {
|
||||
; X32-LABEL: vpermil2pd256_0062:
|
||||
; X32: # BB#0:
|
||||
; X32-NEXT: vpermil2pd {{.*#+}} ymm0 = ymm0[0,0],ymm1[2],ymm0[2]
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
; X64-LABEL: vpermil2pd256_0062:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: vpermil2pd {{.*#+}} ymm0 = ymm0[0,0],ymm1[2],ymm0[2]
|
||||
; X64-NEXT: retq
|
||||
%1 = call <4 x double> @llvm.x86.xop.vpermil2pd.256(<4 x double> %a0, <4 x double> %a1, <4 x i64> <i64 0, i64 0, i64 4, i64 0>, i8 0)
|
||||
ret <4 x double> %1
|
||||
}
|
||||
|
||||
define <4 x double> @vpermil2pd256_zz73(<4 x double> %a0, <4 x double> %a1) {
|
||||
; X32-LABEL: vpermil2pd256_zz73:
|
||||
; X32: # BB#0:
|
||||
; X32-NEXT: vpermil2pd {{.*#+}} ymm0 = zero,zero,ymm1[3],ymm0[3]
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
; X64-LABEL: vpermil2pd256_zz73:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: vpermil2pd {{.*#+}} ymm0 = zero,zero,ymm1[3],ymm0[3]
|
||||
; X64-NEXT: retq
|
||||
%1 = call <4 x double> @llvm.x86.xop.vpermil2pd.256(<4 x double> %a0, <4 x double> %a1, <4 x i64> <i64 0, i64 0, i64 14, i64 10>, i8 3)
|
||||
ret <4 x double> %1
|
||||
}
|
||||
|
||||
define <4 x float> @vpermil2ps_0561(<4 x float> %a0, <4 x float> %a1) {
|
||||
; X32-LABEL: vpermil2ps_0561:
|
||||
; X32: # BB#0:
|
||||
; X32-NEXT: vpermil2ps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2],xmm0[1]
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
; X64-LABEL: vpermil2ps_0561:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: vpermil2ps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2],xmm0[1]
|
||||
; X64-NEXT: retq
|
||||
%1 = call <4 x float> @llvm.x86.xop.vpermil2ps(<4 x float> %a0, <4 x float> %a1, <4 x i32> <i32 0, i32 5, i32 6, i32 1>, i8 0)
|
||||
ret <4 x float> %1
|
||||
}
|
||||
|
||||
define <8 x float> @vpermil2ps256_098144FE(<8 x float> %a0, <8 x float> %a1) {
|
||||
; X32-LABEL: vpermil2ps256_098144FE:
|
||||
; X32: # BB#0:
|
||||
; X32-NEXT: vpermil2ps {{.*#+}} ymm0 = ymm0[0],ymm1[1,0],ymm0[1,4,4],ymm1[7,6]
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
; X64-LABEL: vpermil2ps256_098144FE:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: vpermil2ps {{.*#+}} ymm0 = ymm0[0],ymm1[1,0],ymm0[1,4,4],ymm1[7,6]
|
||||
; X64-NEXT: retq
|
||||
%1 = call <8 x float> @llvm.x86.xop.vpermil2ps.256(<8 x float> %a0, <8 x float> %a1, <8 x i32> <i32 0, i32 5, i32 4, i32 1, i32 0, i32 0, i32 7, i32 6>, i8 0)
|
||||
ret <8 x float> %1
|
||||
}
|
||||
|
||||
define <8 x float> @vpermil2ps256_0zz8BzzA(<8 x float> %a0, <8 x float> %a1) {
|
||||
; X32-LABEL: vpermil2ps256_0zz8BzzA:
|
||||
; X32: # BB#0:
|
||||
; X32-NEXT: vpermil2ps {{.*#+}} ymm0 = ymm0[0],zero,zero,ymm1[0,7],zero,zero,ymm1[6]
|
||||
; X32-NEXT: retl
|
||||
;
|
||||
; X64-LABEL: vpermil2ps256_0zz8BzzA:
|
||||
; X64: # BB#0:
|
||||
; X64-NEXT: vpermil2ps {{.*#+}} ymm0 = ymm0[0],zero,zero,ymm1[0,7],zero,zero,ymm1[6]
|
||||
; X64-NEXT: retq
|
||||
%1 = call <8 x float> @llvm.x86.xop.vpermil2ps.256(<8 x float> %a0, <8 x float> %a1, <8 x i32> <i32 0, i32 8, i32 8, i32 4, i32 7, i32 8, i32 8, i32 6>, i8 2)
|
||||
ret <8 x float> %1
|
||||
}
|
||||
|
||||
declare <2 x double> @llvm.x86.xop.vpermil2pd(<2 x double>, <2 x double>, <2 x i64>, i8) nounwind readnone
|
||||
declare <4 x double> @llvm.x86.xop.vpermil2pd.256(<4 x double>, <4 x double>, <4 x i64>, i8) nounwind readnone
|
||||
|
||||
declare <4 x float> @llvm.x86.xop.vpermil2ps(<4 x float>, <4 x float>, <4 x i32>, i8) nounwind readnone
|
||||
declare <8 x float> @llvm.x86.xop.vpermil2ps.256(<8 x float>, <8 x float>, <8 x i32>, i8) nounwind readnone
|
||||
|
||||
declare <16 x i8> @llvm.x86.xop.vpperm(<16 x i8>, <16 x i8>, <16 x i8>) nounwind readnone
|
||||
|
|
Loading…
Reference in New Issue