Index: llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h =================================================================== --- llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -762,6 +762,7 @@ void SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N, SDValue &Lo, SDValue &Hi); + void SplitVecRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi); // Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>. bool SplitVectorOperand(SDNode *N, unsigned OpNo); Index: llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -848,6 +848,9 @@ case ISD::VECTOR_SHUFFLE: SplitVecRes_VECTOR_SHUFFLE(cast(N), Lo, Hi); break; + case ISD::VAARG: + SplitVecRes_VAARG(N, Lo, Hi); + break; case ISD::ANY_EXTEND_VECTOR_INREG: case ISD::SIGN_EXTEND_VECTOR_INREG: @@ -1840,6 +1843,27 @@ } } +void DAGTypeLegalizer::SplitVecRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) { + EVT OVT = N->getValueType(0); + EVT NVT = OVT.getHalfNumVectorElementsVT(*DAG.getContext()); + SDValue Chain = N->getOperand(0); + SDValue Ptr = N->getOperand(1); + SDValue SV = N->getOperand(2); + SDLoc dl(N); + const unsigned Align = N->getConstantOperandVal(3); + + Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Align); + Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, SV, 0); + Chain = Hi.getValue(1); + + if (DAG.getDataLayout().isBigEndian()) + std::swap(Lo, Hi); + + // Modified the chain - switch anything that used the old chain to use + // the new one. + ReplaceValueWith(SDValue(N, 1), Chain); +} + //===----------------------------------------------------------------------===// // Operand Vector Splitting Index: llvm/test/CodeGen/X86/legalize-vaarg.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/legalize-vaarg.ll @@ -0,0 +1,11 @@ +;RUN: llc < %s -mtriple=x86_64-- -mattr=avx | FileCheck %s + +define <32 x i32> @test_large_vec_vaarg(i32 %n, ...) { + %args = alloca i8*, align 4 +;CHECK: vmovaps {{.*}} %ymm0 +;CHECK: vmovaps {{.*}} %ymm1 +;CHECK: vmovaps {{.*}} %ymm2 +;CHECK: vmovaps {{.*}} %ymm3 + %x = va_arg i8** %args, <32 x i32> + ret <32 x i32> %x +}