178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===-------- LegalizeTypesGeneric.cpp - Generic type legalization --------===// 278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// 378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// The LLVM Compiler Infrastructure 478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// 578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// This file is distributed under the University of Illinois Open Source 678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// License. See LICENSE.TXT for details. 778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// 878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===----------------------------------------------------------------------===// 978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// 1078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// This file implements generic type expansion and splitting for LegalizeTypes. 1178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// The routines here perform legalization when the details of the type (such as 1278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// whether it is an integer or a float) do not matter. 1378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Expansion is the act of changing a computation in an illegal type to be a 14f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands// computation in two identical registers of a smaller type. The Lo/Hi part 15f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands// is required to be stored first in memory on little/big-endian machines. 1678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Splitting is the act of changing a computation in an illegal type to be a 1778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// computation in two not necessarily identical registers of a smaller type. 18f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands// There are no requirements on how the type is represented in memory. 1978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// 2078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===----------------------------------------------------------------------===// 2178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 2278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands#include "LegalizeTypes.h" 230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 2478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sandsusing namespace llvm; 2578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "legalize-types" 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===----------------------------------------------------------------------===// 2978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Generic Result Expansion. 3078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===----------------------------------------------------------------------===// 3178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 3278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// These routines assume that the Lo/Hi part is stored first in memory on 3378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// little/big-endian machines, followed by the Hi/Lo part. This means that 3478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// they cannot be used as is on vectors, for which Lo is always stored first. 354c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sandsvoid DAGTypeLegalizer::ExpandRes_MERGE_VALUES(SDNode *N, unsigned ResNo, 3662bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman SDValue &Lo, SDValue &Hi) { 374c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sands SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); 3862bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman GetExpandedOp(Op, Lo, Hi); 3962bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman} 4078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 41bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peckvoid DAGTypeLegalizer::ExpandRes_BITCAST(SDNode *N, SDValue &Lo, SDValue &Hi) { 42e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OutVT = N->getValueType(0); 4323b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); 44475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue InOp = N->getOperand(0); 45e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT InVT = InOp.getValueType(); 46ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 4778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 4878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Handle some special cases efficiently. 4978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands switch (getTypeAction(InVT)) { 5096e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem case TargetLowering::TypeLegal: 5196e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem case TargetLowering::TypePromoteInteger: 5278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands break; 53a18e6af1712fd41c4a705a19ad71f6e9ac7a4e68Pirama Arumuga Nainar case TargetLowering::TypePromoteFloat: 54a18e6af1712fd41c4a705a19ad71f6e9ac7a4e68Pirama Arumuga Nainar llvm_unreachable("Bitcast of a promotion-needing float should never need" 55a18e6af1712fd41c4a705a19ad71f6e9ac7a4e68Pirama Arumuga Nainar "expansion"); 56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case TargetLowering::TypeSoftenFloat: { 57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Expand the floating point operand only if it was converted to integers. 58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Otherwise, it is a legal type like f128 that can be saved in a register. 59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto SoftenedOp = GetSoftenedFloat(InOp); 60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (SoftenedOp == InOp) 61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar break; 62f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar SplitInteger(SoftenedOp, Lo, Hi); 63bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo); 64bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi); 6578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands return; 66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 6796e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem case TargetLowering::TypeExpandInteger: 68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar case TargetLowering::TypeExpandFloat: { 69f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &DL = DAG.getDataLayout(); 7078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Convert the expanded pieces of the input. 7178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands GetExpandedOp(InOp, Lo, Hi); 72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TLI.hasBigEndianPartOrdering(InVT, DL) != 73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar TLI.hasBigEndianPartOrdering(OutVT, DL)) 74c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::swap(Lo, Hi); 75bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo); 76bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi); 7778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands return; 78f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar } 7996e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem case TargetLowering::TypeSplitVector: 8078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands GetSplitVector(InOp, Lo, Hi); 81f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout())) 82f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands std::swap(Lo, Hi); 83bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo); 84bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi); 85f2d754bb382cba0bad2774144ddac84be5354d16Duncan Sands return; 8696e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem case TargetLowering::TypeScalarizeVector: 8778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Convert the element instead. 8878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi); 89bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo); 90bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi); 9178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands return; 9296e0c5477c41b316263e894bbb5821c7cdeb25efNadav Rotem case TargetLowering::TypeWidenVector: { 93bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck assert(!(InVT.getVectorNumElements() & 1) && "Unsupported BITCAST"); 94aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang InOp = GetWidenedVector(InOp); 95ee287ca22abcce9f769618c107ff3f46aa2d0cbaBill Wendling EVT LoVT, HiVT; 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(InVT); 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::tie(Lo, Hi) = DAG.SplitVector(InOp, dl, LoVT, HiVT); 98f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout())) 99aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang std::swap(Lo, Hi); 100bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo); 101bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi); 102aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang return; 103aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang } 10478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands } 10578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 106f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman if (InVT.isVector() && OutVT.isInteger()) { 107bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck // Handle cases like i64 = BITCAST v1i64 on x86, where the operand 108f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman // is legal but the result is not. 109092122f124b6589a3a432473c1047bf5834df3c1Michael Liao unsigned NumElems = 2; 110bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao EVT ElemVT = NOutVT; 111bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao EVT NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems); 112092122f124b6589a3a432473c1047bf5834df3c1Michael Liao 113bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao // If <ElemVT * N> is not a legal type, try <ElemVT/2 * (N*2)>. 114092122f124b6589a3a432473c1047bf5834df3c1Michael Liao while (!isTypeLegal(NVT)) { 115bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao unsigned NewSizeInBits = ElemVT.getSizeInBits() / 2; 116092122f124b6589a3a432473c1047bf5834df3c1Michael Liao // If the element size is smaller than byte, bail. 117092122f124b6589a3a432473c1047bf5834df3c1Michael Liao if (NewSizeInBits < 8) 118092122f124b6589a3a432473c1047bf5834df3c1Michael Liao break; 119092122f124b6589a3a432473c1047bf5834df3c1Michael Liao NumElems *= 2; 120bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao ElemVT = EVT::getIntegerVT(*DAG.getContext(), NewSizeInBits); 121bb7300224738e65f9a9945dc7df2f360b1d4feb6Michael Liao NVT = EVT::getVectorVT(*DAG.getContext(), ElemVT, NumElems); 122092122f124b6589a3a432473c1047bf5834df3c1Michael Liao } 123f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman 124f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman if (isTypeLegal(NVT)) { 125bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue CastInOp = DAG.getNode(ISD::BITCAST, dl, NVT, InOp); 126092122f124b6589a3a432473c1047bf5834df3c1Michael Liao 127092122f124b6589a3a432473c1047bf5834df3c1Michael Liao SmallVector<SDValue, 8> Vals; 128092122f124b6589a3a432473c1047bf5834df3c1Michael Liao for (unsigned i = 0; i < NumElems; ++i) 129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Vals.push_back(DAG.getNode( 130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ISD::EXTRACT_VECTOR_ELT, dl, ElemVT, CastInOp, 131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout())))); 132092122f124b6589a3a432473c1047bf5834df3c1Michael Liao 133092122f124b6589a3a432473c1047bf5834df3c1Michael Liao // Build Lo, Hi pair by pairing extracted elements if needed. 134092122f124b6589a3a432473c1047bf5834df3c1Michael Liao unsigned Slot = 0; 135092122f124b6589a3a432473c1047bf5834df3c1Michael Liao for (unsigned e = Vals.size(); e - Slot > 2; Slot += 2, e += 1) { 136092122f124b6589a3a432473c1047bf5834df3c1Michael Liao // Each iteration will BUILD_PAIR two nodes and append the result until 137092122f124b6589a3a432473c1047bf5834df3c1Michael Liao // there are only two nodes left, i.e. Lo and Hi. 138092122f124b6589a3a432473c1047bf5834df3c1Michael Liao SDValue LHS = Vals[Slot]; 139092122f124b6589a3a432473c1047bf5834df3c1Michael Liao SDValue RHS = Vals[Slot + 1]; 1407bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand 141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (DAG.getDataLayout().isBigEndian()) 1427bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand std::swap(LHS, RHS); 1437bbb9c7b4a21364c5b92e60520babf326beff3d8Ulrich Weigand 144092122f124b6589a3a432473c1047bf5834df3c1Michael Liao Vals.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, 145092122f124b6589a3a432473c1047bf5834df3c1Michael Liao EVT::getIntegerVT( 146092122f124b6589a3a432473c1047bf5834df3c1Michael Liao *DAG.getContext(), 147092122f124b6589a3a432473c1047bf5834df3c1Michael Liao LHS.getValueType().getSizeInBits() << 1), 148092122f124b6589a3a432473c1047bf5834df3c1Michael Liao LHS, RHS)); 149092122f124b6589a3a432473c1047bf5834df3c1Michael Liao } 150092122f124b6589a3a432473c1047bf5834df3c1Michael Liao Lo = Vals[Slot++]; 151092122f124b6589a3a432473c1047bf5834df3c1Michael Liao Hi = Vals[Slot++]; 152f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman 153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (DAG.getDataLayout().isBigEndian()) 154f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman std::swap(Lo, Hi); 1558c899ee031481dbece5f111379a274c848cb5902Duncan Sands 156f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman return; 157f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman } 158f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman } 159f10d3a7bcda97d28f9d325cb58cec7e17d7ed101Eli Friedman 16047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands // Lower the bit-convert to a store/load from the stack. 16147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands assert(NOutVT.isByteSized() && "Expanded type not byte sized!"); 16247d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands 16347d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands // Create the stack frame object. Make sure it is aligned for both 16447d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands // the source and expanded destination types. 165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Alignment = DAG.getDataLayout().getPrefTypeAlignment( 166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar NOutVT.getTypeForEVT(*DAG.getContext())); 16747d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands SDValue StackPtr = DAG.CreateStackTemporary(InVT, Alignment); 168ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex(); 169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachinePointerInfo PtrInfo = 170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI); 17147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands 17247d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands // Emit a store to the stack slot. 173ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, PtrInfo, 1741e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 17547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands 17647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands // Load the first half from the stack slot. 177155615d7dc4e4fbfd3b7273720a76356468edf46Stephen Lin Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, PtrInfo, 178d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 17947d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands 18047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands // Increment the pointer to the other half. 18147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands unsigned IncrementSize = NOutVT.getSizeInBits() / 8; 18235ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 1836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DAG.getConstant(IncrementSize, dl, 184edd08f74289c6ba3b3f8e730e4ab825ef9bd6492Tom Stellard StackPtr.getValueType())); 18547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands 18647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands // Load the second half from the stack slot. 187ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr, 188ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner PtrInfo.getWithOffset(IncrementSize), false, 189d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, MinAlign(Alignment, IncrementSize)); 19047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands 19147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands // Handle endianness of the load. 192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TLI.hasBigEndianPartOrdering(OutVT, DAG.getDataLayout())) 19347d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands std::swap(Lo, Hi); 19478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 19578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 196475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_BUILD_PAIR(SDNode *N, SDValue &Lo, 197475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Hi) { 19878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Return the operands. 19978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands Lo = N->getOperand(0); 20078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands Hi = N->getOperand(1); 20178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 20278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 203475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_EXTRACT_ELEMENT(SDNode *N, SDValue &Lo, 204475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Hi) { 2054a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands GetExpandedOp(N->getOperand(0), Lo, Hi); 206f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman SDValue Part = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() ? 207f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman Hi : Lo; 2084a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands 2094a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands assert(Part.getValueType() == N->getValueType(0) && 2104a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands "Type twice as big as expanded type not itself expanded!"); 2114a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands 2122bee0afb7d023e029975abf7d3157759fa797d37Dan Gohman GetPairElements(Part, Lo, Hi); 2134a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands} 2144a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands 215475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo, 216475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Hi) { 217475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue OldVec = N->getOperand(0); 21878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands unsigned OldElts = OldVec.getValueType().getVectorNumElements(); 2194e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands EVT OldEltVT = OldVec.getValueType().getVectorElementType(); 220ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 22178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 22278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Convert to a vector of the expanded element type, for example 22378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // <3 x i64> -> <6 x i32>. 224e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OldVT = N->getValueType(0); 22523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT); 22678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 2274e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands if (OldVT != OldEltVT) { 2284e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands // The result of EXTRACT_VECTOR_ELT may be larger than the element type of 2294e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands // the input vector. If so, extend the elements of the input vector to the 2304e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands // same bitwidth as the result before expanding. 2314e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands assert(OldEltVT.bitsLT(OldVT) && "Result type smaller then element type!"); 2324e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands EVT NVecVT = EVT::getVectorVT(*DAG.getContext(), OldVT, OldElts); 2334e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands OldVec = DAG.getNode(ISD::ANY_EXTEND, dl, NVecVT, N->getOperand(0)); 2344e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands } 2354e8982a34da69effe23ce9c553680b19d7d57551Duncan Sands 236bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue NewVec = DAG.getNode(ISD::BITCAST, dl, 237adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng EVT::getVectorVT(*DAG.getContext(), 238adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng NewVT, 2*OldElts), 239adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng OldVec); 24078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 24178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector. 242475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Idx = N->getOperand(1); 24378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 244de06470330260f5937e7ca558f5f5b3e171f2ee5Dale Johannesen Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx); 24535ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx); 24678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 24735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, 2486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DAG.getConstant(1, dl, Idx.getValueType())); 24935ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx); 25078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (DAG.getDataLayout().isBigEndian()) 25278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands std::swap(Lo, Hi); 25378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 25478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 255475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo, 256475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Hi) { 257ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands assert(ISD::isNormalLoad(N) && "This routine only for normal loads!"); 258ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 25978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 26078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands LoadSDNode *LD = cast<LoadSDNode>(N); 261c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EVT ValueVT = LD->getValueType(0); 262c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT); 263475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = LD->getChain(); 264475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ptr = LD->getBasePtr(); 26578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands unsigned Alignment = LD->getAlignment(); 26678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands bool isVolatile = LD->isVolatile(); 2671e559443a17d1b335f697551c6263ba60d5dd827David Greene bool isNonTemporal = LD->isNonTemporal(); 268d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper bool isInvariant = LD->isInvariant(); 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AAMDNodes AAInfo = LD->getAAInfo(); 27078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 27178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands assert(NVT.isByteSized() && "Expanded type not byte sized!"); 27278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 273ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getPointerInfo(), 27466589dcc8fb5dcf0894a9a80a8dee890a4f3a379Richard Sandiford isVolatile, isNonTemporal, isInvariant, Alignment, 27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AAInfo); 27678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 27778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Increment the pointer to the other half. 27878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands unsigned IncrementSize = NVT.getSizeInBits() / 8; 27935ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 2806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DAG.getConstant(IncrementSize, dl, Ptr.getValueType())); 281ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Hi = DAG.getLoad(NVT, dl, Chain, Ptr, 282ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->getPointerInfo().getWithOffset(IncrementSize), 283d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper isVolatile, isNonTemporal, isInvariant, 28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MinAlign(Alignment, IncrementSize), AAInfo); 28578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 28678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Build a factor node to remember that this load is independent of the 28778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // other one. 288825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 28978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands Hi.getValue(1)); 29078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 29178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Handle endianness of the load. 292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout())) 29378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands std::swap(Lo, Hi); 29478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 29578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Modified the chain - switch anything that used the old chain to use 29678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // the new one. 297475871a144eb604ddaf37503397ba0941442e5fbDan Gohman ReplaceValueWith(SDValue(N, 1), Chain); 29878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 29978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 30021c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sandsvoid DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) { 30172d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola EVT OVT = N->getValueType(0); 30272d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT); 30321c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands SDValue Chain = N->getOperand(0); 30421c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands SDValue Ptr = N->getOperand(1); 305ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 306cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola const unsigned Align = N->getConstantOperandVal(3); 30721c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands 30872d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2), Align); 309cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, N->getOperand(2), 0); 31021c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands 31121c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands // Handle endianness of the load. 312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TLI.hasBigEndianPartOrdering(OVT, DAG.getDataLayout())) 31321c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands std::swap(Lo, Hi); 31421c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands 31521c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands // Modified the chain - switch anything that used the old chain to use 31621c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands // the new one. 31721c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands ReplaceValueWith(SDValue(N, 1), Hi.getValue(1)); 31821c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands} 31921c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands 320ae099d54428f4113f8a71c53314975fb8a8e8bbcDuncan Sands 32178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===// 32278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Generic Operand Expansion. 32378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===// 32478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 325f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendlingvoid DAGTypeLegalizer::IntegerToVector(SDValue Op, unsigned NumElements, 326f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling SmallVectorImpl<SDValue> &Ops, 327f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling EVT EltVT) { 328f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling assert(Op.getValueType().isInteger()); 329f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling SDLoc DL(Op); 330f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling SDValue Parts[2]; 331f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling 332f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling if (NumElements > 1) { 333f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling NumElements >>= 1; 334f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling SplitInteger(Op, Parts[0], Parts[1]); 335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (DAG.getDataLayout().isBigEndian()) 336f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling std::swap(Parts[0], Parts[1]); 337f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling IntegerToVector(Parts[0], NumElements, Ops, EltVT); 338f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling IntegerToVector(Parts[1], NumElements, Ops, EltVT); 339f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling } else { 340f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling Ops.push_back(DAG.getNode(ISD::BITCAST, DL, EltVT, Op)); 341f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling } 342f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling} 343f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling 344bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley PeckSDValue DAGTypeLegalizer::ExpandOp_BITCAST(SDNode *N) { 345ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 34678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands if (N->getValueType(0).isVector()) { 34778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // An illegal expanding type is being converted to a legal vector type. 34878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Make a two element vector out of the expanded parts and convert that 34978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // instead, but only if the new vector type is legal (otherwise there 35078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // is no point, and it might create expansion loops). For example, on 351bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck // x86 this turns v1i64 = BITCAST i64 into v1i64 = BITCAST v2i32. 352f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling // 353f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling // FIXME: I'm not sure why we are first trying to split the input into 354f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling // a 2 element vector, so I'm leaving it here to maintain the current 355f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling // behavior. 356f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling unsigned NumElts = 2; 357e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OVT = N->getOperand(0).getValueType(); 358adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng EVT NVT = EVT::getVectorVT(*DAG.getContext(), 359adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng TLI.getTypeToTransformTo(*DAG.getContext(), OVT), 360f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling NumElts); 361f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling if (!isTypeLegal(NVT)) { 362f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling // If we can't find a legal type by splitting the integer in half, 363f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling // then we can use the node's value type. 364f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling NumElts = N->getValueType(0).getVectorNumElements(); 365f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling NVT = N->getValueType(0); 366f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling } 36778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 368f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling SmallVector<SDValue, 8> Ops; 369f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling IntegerToVector(N->getOperand(0), NumElts, Ops, NVT.getVectorElementType()); 37078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 371dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, 372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines makeArrayRef(Ops.data(), NumElts)); 373f0061998dd1256df1ba933e80fdad2f594ea3f50Bill Wendling return DAG.getNode(ISD::BITCAST, dl, N->getValueType(0), Vec); 37478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands } 37578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 37678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Otherwise, store to a temporary and load out again as the new type. 37778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); 37878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 37978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 380475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) { 38178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // The vector type is legal but the element type needs expansion. 382e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VecVT = N->getValueType(0); 38378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands unsigned NumElts = VecVT.getVectorNumElements(); 384e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OldVT = N->getOperand(0).getValueType(); 38523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT NewVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldVT); 386ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 38778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 388b1303d05a89972195de023fda432cc621375a27cBob Wilson assert(OldVT == VecVT.getVectorElementType() && 389b1303d05a89972195de023fda432cc621375a27cBob Wilson "BUILD_VECTOR operand type doesn't match vector element type!"); 390b1303d05a89972195de023fda432cc621375a27cBob Wilson 39178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Build a vector of twice the length out of the expanded elements. 39278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // For example <3 x i64> -> <6 x i32>. 393475871a144eb604ddaf37503397ba0941442e5fbDan Gohman std::vector<SDValue> NewElts; 39478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands NewElts.reserve(NumElts*2); 39578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 39678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands for (unsigned i = 0; i < NumElts; ++i) { 397475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi; 39878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands GetExpandedOp(N->getOperand(i), Lo, Hi); 399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (DAG.getDataLayout().isBigEndian()) 40078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands std::swap(Lo, Hi); 40178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands NewElts.push_back(Lo); 40278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands NewElts.push_back(Hi); 40378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands } 40478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 405a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, 406adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng EVT::getVectorVT(*DAG.getContext(), 407adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng NewVT, NewElts.size()), 408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines NewElts); 40978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 41078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands // Convert the new vector to the old vector type. 411bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec); 41278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 41378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 414475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) { 415475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi; 41678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands GetExpandedOp(N->getOperand(0), Lo, Hi); 417f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman return cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() ? Hi : Lo; 41878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 41978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 420d17c0302763cfd0b3f6657d2493147552762ac07Mon P WangSDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) { 421d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang // The vector type is legal but the element type needs expansion. 422e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VecVT = N->getValueType(0); 423d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang unsigned NumElts = VecVT.getVectorNumElements(); 424ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 425d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang 426d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang SDValue Val = N->getOperand(1); 427e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OldEVT = Val.getValueType(); 42823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT NewEVT = TLI.getTypeToTransformTo(*DAG.getContext(), OldEVT); 429d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang 430d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang assert(OldEVT == VecVT.getVectorElementType() && 431d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang "Inserted element type doesn't match vector element type!"); 432d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang 433d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang // Bitconvert to a vector of twice the length with elements of the expanded 434d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang // type, insert the expanded vector elements, and then convert back. 43523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewEVT, NumElts*2); 436bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue NewVec = DAG.getNode(ISD::BITCAST, dl, 43735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen NewVecVT, N->getOperand(0)); 438d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang 439d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang SDValue Lo, Hi; 440d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang GetExpandedOp(Val, Lo, Hi); 441f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (DAG.getDataLayout().isBigEndian()) 442d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang std::swap(Lo, Hi); 443d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang 444d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang SDValue Idx = N->getOperand(2); 44535ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx); 44635ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Lo, Idx); 44735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen Idx = DAG.getNode(ISD::ADD, dl, 448425b76c2314ff7ee7ad507011bdda1988ae481efTom Stellard Idx.getValueType(), Idx, 4496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DAG.getConstant(1, dl, Idx.getValueType())); 45035ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Hi, Idx); 451d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang 452d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang // Convert the new vector to the old vector type. 453bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck return DAG.getNode(ISD::BITCAST, dl, VecVT, NewVec); 454d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang} 455d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang 456d17c0302763cfd0b3f6657d2493147552762ac07Mon P WangSDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) { 457ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 458e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = N->getValueType(0); 459b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands assert(VT.getVectorElementType() == N->getOperand(0).getValueType() && 460b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands "SCALAR_TO_VECTOR operand type doesn't match vector element type!"); 461d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang unsigned NumElts = VT.getVectorNumElements(); 462d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang SmallVector<SDValue, 16> Ops(NumElts); 463d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang Ops[0] = N->getOperand(0); 464e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen SDValue UndefVal = DAG.getUNDEF(Ops[0].getValueType()); 465d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang for (unsigned i = 1; i < NumElts; ++i) 466d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang Ops[i] = UndefVal; 467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops); 468d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang} 469d17c0302763cfd0b3f6657d2493147552762ac07Mon P Wang 470475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) { 471ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands assert(ISD::isNormalStore(N) && "This routine only for normal stores!"); 47278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands assert(OpNo == 1 && "Can only expand the stored value so far"); 473ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 47478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 47578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands StoreSDNode *St = cast<StoreSDNode>(N); 476c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EVT ValueVT = St->getValue().getValueType(); 477c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ValueVT); 478475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = St->getChain(); 479475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ptr = St->getBasePtr(); 48078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands unsigned Alignment = St->getAlignment(); 48178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands bool isVolatile = St->isVolatile(); 4821e559443a17d1b335f697551c6263ba60d5dd827David Greene bool isNonTemporal = St->isNonTemporal(); 48337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines AAMDNodes AAInfo = St->getAAInfo(); 48478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 48578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands assert(NVT.isByteSized() && "Expanded type not byte sized!"); 48678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands unsigned IncrementSize = NVT.getSizeInBits() / 8; 48778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 488475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi; 48978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands GetExpandedOp(St->getValue(), Lo, Hi); 49078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TLI.hasBigEndianPartOrdering(ValueVT, DAG.getDataLayout())) 49278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands std::swap(Lo, Hi); 49378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 4946229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner Lo = DAG.getStore(Chain, dl, Lo, Ptr, St->getPointerInfo(), 49537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines isVolatile, isNonTemporal, Alignment, AAInfo); 49678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 49735ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 4986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DAG.getConstant(IncrementSize, dl, Ptr.getValueType())); 4996229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner Hi = DAG.getStore(Chain, dl, Hi, Ptr, 5006229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner St->getPointerInfo().getWithOffset(IncrementSize), 5011e559443a17d1b335f697551c6263ba60d5dd827David Greene isVolatile, isNonTemporal, 50237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MinAlign(Alignment, IncrementSize), AAInfo); 50378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 504825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 50578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 50678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 50778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 50878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===// 50978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Generic Result Splitting. 51078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands//===--------------------------------------------------------------------===// 51178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 51278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// Be careful to make no assumptions about which of Lo/Hi is stored first in 51378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// memory (for vectors it is always Lo first followed by Hi in the following 51478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// bytes; for integers and floats it is Lo first if and only if the machine is 51578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// little-endian). 51678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 5174c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sandsvoid DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo, 518475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Lo, SDValue &Hi) { 5194c19e12d28749c717d3b384962c9ec92796af1c9Duncan Sands SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); 52062bb16cfd10dd271eab6c31d982bca4d79138602Eli Friedman GetSplitOp(Op, Lo, Hi); 52178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 52278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 523475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo, 524475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Hi) { 52528b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands SDValue LL, LH, RL, RH, CL, CH; 526ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 52778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands GetSplitOp(N->getOperand(1), LL, LH); 52878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands GetSplitOp(N->getOperand(2), RL, RH); 52978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 530475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Cond = N->getOperand(0); 53128b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands CL = CH = Cond; 53228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands if (Cond.getValueType().isVector()) { 533f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling // Check if there are already splitted versions of the vector available and 534f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling // use those instead of splitting the mask operand again. 535f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling if (getTypeAction(Cond.getValueType()) == TargetLowering::TypeSplitVector) 536c7e77f91fecd662b198939a9a8ee0a0cc3828fc4Juergen Ributzka GetSplitVector(Cond, CL, CH); 537f62b274a93d4014d56fa3a656f4fac6e7d827358Bill Wendling else 53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::tie(CL, CH) = DAG.SplitVector(Cond, dl); 53928b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands } 54028b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands 54128b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), CL, LL, RL); 54228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands Hi = DAG.getNode(N->getOpcode(), dl, LH.getValueType(), CH, LH, RH); 54378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 54478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 545475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo, 546475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Hi) { 547475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LL, LH, RL, RH; 548ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 54978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands GetSplitOp(N->getOperand(2), LL, LH); 55078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands GetSplitOp(N->getOperand(3), RL, RH); 55178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 55235ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen Lo = DAG.getNode(ISD::SELECT_CC, dl, LL.getValueType(), N->getOperand(0), 55378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands N->getOperand(1), LL, RL, N->getOperand(4)); 55435ba3d463834f83e2bf8e8ad631ffc4d73a0203cDale Johannesen Hi = DAG.getNode(ISD::SELECT_CC, dl, LH.getValueType(), N->getOperand(0), 55578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands N->getOperand(1), LH, RH, N->getOperand(4)); 55678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 55778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands 558475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) { 559e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT LoVT, HiVT; 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 561e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen Lo = DAG.getUNDEF(LoVT); 562e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen Hi = DAG.getUNDEF(HiVT); 56378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands} 564