mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-01 08:28:19 +00:00
Fixed a bug in SelectionDAG.cpp.
The failure seen on win32, when i64 type is illegal. It happens on stage of conversion VECTOR_SHUFFLE to BUILD_VECTOR. The failure message is: llc: SelectionDAG.cpp:784: void VerifyNodeCommon(llvm::SDNode*): Assertion `(I->getValueType() == EltVT || (EltVT.isInteger() && I->getValueType().isInteger() && EltVT.bitsLE(I->getValueType()))) && "Wrong operand type!"' failed. I added a special test that checks vector shuffle on win32. llvm-svn: 147445
This commit is contained in:
parent
6839d66ab3
commit
40f2c3077f
@ -2795,15 +2795,58 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
|||||||
Node->getOperand(2), dl));
|
Node->getOperand(2), dl));
|
||||||
break;
|
break;
|
||||||
case ISD::VECTOR_SHUFFLE: {
|
case ISD::VECTOR_SHUFFLE: {
|
||||||
SmallVector<int, 8> Mask;
|
SmallVector<int, 32> Mask;
|
||||||
cast<ShuffleVectorSDNode>(Node)->getMask(Mask);
|
cast<ShuffleVectorSDNode>(Node)->getMask(Mask);
|
||||||
|
|
||||||
EVT VT = Node->getValueType(0);
|
EVT VT = Node->getValueType(0);
|
||||||
EVT EltVT = VT.getVectorElementType();
|
EVT EltVT = VT.getVectorElementType();
|
||||||
if (!TLI.isTypeLegal(EltVT))
|
SDValue Op0 = Node->getOperand(0);
|
||||||
EltVT = TLI.getTypeToTransformTo(*DAG.getContext(), EltVT);
|
SDValue Op1 = Node->getOperand(1);
|
||||||
|
if (!TLI.isTypeLegal(EltVT)) {
|
||||||
|
|
||||||
|
EVT NewEltVT = TLI.getTypeToTransformTo(*DAG.getContext(), EltVT);
|
||||||
|
|
||||||
|
// BUILD_VECTOR operands are allowed to be wider than the element type.
|
||||||
|
// But if NewEltVT is smaller that EltVT the BUILD_VECTOR does not accept it
|
||||||
|
if (NewEltVT.bitsLT(EltVT)) {
|
||||||
|
|
||||||
|
// Convert shuffle node.
|
||||||
|
// If original node was v4i64 and the new EltVT is i32,
|
||||||
|
// cast operands to v8i32 and re-build the mask.
|
||||||
|
|
||||||
|
// Calculate new VT, the size of the new VT should be equal to original.
|
||||||
|
EVT NewVT = EVT::getVectorVT(*DAG.getContext(), NewEltVT,
|
||||||
|
VT.getSizeInBits()/NewEltVT.getSizeInBits());
|
||||||
|
assert(NewVT.bitsEq(VT));
|
||||||
|
|
||||||
|
// cast operands to new VT
|
||||||
|
Op0 = DAG.getNode(ISD::BITCAST, dl, NewVT, Op0);
|
||||||
|
Op1 = DAG.getNode(ISD::BITCAST, dl, NewVT, Op1);
|
||||||
|
|
||||||
|
// Convert the shuffle mask
|
||||||
|
unsigned int factor = NewVT.getVectorNumElements()/VT.getVectorNumElements();
|
||||||
|
|
||||||
|
// EltVT gets smaller
|
||||||
|
assert(factor > 0);
|
||||||
|
SmallVector<int, 32> NewMask;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < VT.getVectorNumElements(); ++i) {
|
||||||
|
if (Mask[i] < 0) {
|
||||||
|
for (unsigned fi = 0; fi < factor; ++fi)
|
||||||
|
NewMask.push_back(Mask[i]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (unsigned fi = 0; fi < factor; ++fi)
|
||||||
|
NewMask.push_back(Mask[i]*factor+fi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mask = NewMask;
|
||||||
|
VT = NewVT;
|
||||||
|
}
|
||||||
|
EltVT = NewEltVT;
|
||||||
|
}
|
||||||
unsigned NumElems = VT.getVectorNumElements();
|
unsigned NumElems = VT.getVectorNumElements();
|
||||||
SmallVector<SDValue, 8> Ops;
|
SmallVector<SDValue, 16> Ops;
|
||||||
for (unsigned i = 0; i != NumElems; ++i) {
|
for (unsigned i = 0; i != NumElems; ++i) {
|
||||||
if (Mask[i] < 0) {
|
if (Mask[i] < 0) {
|
||||||
Ops.push_back(DAG.getUNDEF(EltVT));
|
Ops.push_back(DAG.getUNDEF(EltVT));
|
||||||
@ -2812,13 +2855,14 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
|||||||
unsigned Idx = Mask[i];
|
unsigned Idx = Mask[i];
|
||||||
if (Idx < NumElems)
|
if (Idx < NumElems)
|
||||||
Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
|
Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
|
||||||
Node->getOperand(0),
|
Op0,
|
||||||
DAG.getIntPtrConstant(Idx)));
|
DAG.getIntPtrConstant(Idx)));
|
||||||
else
|
else
|
||||||
Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
|
Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
|
||||||
Node->getOperand(1),
|
Op1,
|
||||||
DAG.getIntPtrConstant(Idx - NumElems)));
|
DAG.getIntPtrConstant(Idx - NumElems)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Tmp1 = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size());
|
Tmp1 = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size());
|
||||||
Results.push_back(Tmp1);
|
Results.push_back(Tmp1);
|
||||||
break;
|
break;
|
||||||
|
8
test/CodeGen/X86/avx-shuffle-x86_32.ll
Executable file
8
test/CodeGen/X86/avx-shuffle-x86_32.ll
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
; RUN: llc < %s -mtriple=i686-pc-win32 -mcpu=corei7-avx -mattr=+avx | FileCheck %s
|
||||||
|
|
||||||
|
define <4 x i64> @test1(<4 x i64> %a) nounwind {
|
||||||
|
%b = shufflevector <4 x i64> %a, <4 x i64> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
|
||||||
|
ret <4 x i64>%b
|
||||||
|
; CHECK test1:
|
||||||
|
; CHECK: vinsertf128
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user