[llvm-commits] [llvm] r50273 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Nate Begeman
natebegeman at mac.com
Fri Apr 25 11:07:40 PDT 2008
Author: sampo
Date: Fri Apr 25 13:07:40 2008
New Revision: 50273
URL: http://llvm.org/viewvc/llvm-project?rev=50273&view=rev
Log:
Pull the code to perform an INSERT_VECTOR_ELT in memory out into its own
function, and then use it to fix a bug in SplitVectorOp that expected inserts
to always have constant insertion indices.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=50273&r1=50272&r2=50273&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Apr 25 13:07:40 2008
@@ -155,6 +155,13 @@
/// no way of lowering. "Unroll" the vector, splitting out the scalars and
/// operating on each element individually.
SDOperand UnrollVectorOp(SDOperand O);
+
+ /// PerformInsertVectorEltInMemory - Some target cannot handle a variable
+ /// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it
+ /// is necessary to spill the vector being inserted into to memory, perform
+ /// the insert there, and then read the result back.
+ SDOperand PerformInsertVectorEltInMemory(SDOperand Vec, SDOperand Val,
+ SDOperand Idx);
/// PromoteOp - Given an operation that produces a value in an invalid type,
/// promote it to compute the value into a larger type. The produced value
@@ -757,6 +764,50 @@
RTLIB::UNKNOWN_LIBCALL;
}
+/// PerformInsertVectorEltInMemory - Some target cannot handle a variable
+/// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it
+/// is necessary to spill the vector being inserted into to memory, perform
+/// the insert there, and then read the result back.
+SDOperand SelectionDAGLegalize::
+PerformInsertVectorEltInMemory(SDOperand Vec, SDOperand Val, SDOperand Idx) {
+ SDOperand Tmp1 = Vec;
+ SDOperand Tmp2 = Val;
+ SDOperand Tmp3 = Idx;
+
+ // If the target doesn't support this, we have to spill the input vector
+ // to a temporary stack slot, update the element, then reload it. This is
+ // badness. We could also load the value into a vector register (either
+ // with a "move to register" or "extload into register" instruction, then
+ // permute it into place, if the idx is a constant and if the idx is
+ // supported by the target.
+ MVT::ValueType VT = Tmp1.getValueType();
+ MVT::ValueType EltVT = MVT::getVectorElementType(VT);
+ MVT::ValueType IdxVT = Tmp3.getValueType();
+ MVT::ValueType PtrVT = TLI.getPointerTy();
+ SDOperand StackPtr = DAG.CreateStackTemporary(VT);
+
+ FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(StackPtr.Val);
+ int SPFI = StackPtrFI->getIndex();
+
+ // Store the vector.
+ SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr,
+ PseudoSourceValue::getFixedStack(),
+ SPFI);
+
+ // Truncate or zero extend offset to target pointer type.
+ unsigned CastOpc = (IdxVT > PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
+ Tmp3 = DAG.getNode(CastOpc, PtrVT, Tmp3);
+ // Add the offset to the index.
+ unsigned EltSize = MVT::getSizeInBits(EltVT)/8;
+ Tmp3 = DAG.getNode(ISD::MUL, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT));
+ SDOperand StackPtr2 = DAG.getNode(ISD::ADD, IdxVT, Tmp3, StackPtr);
+ // Store the scalar value.
+ Ch = DAG.getTruncStore(Ch, Tmp2, StackPtr2,
+ PseudoSourceValue::getFixedStack(), SPFI, EltVT);
+ // Load the updated vector.
+ return DAG.getLoad(VT, Ch, StackPtr, PseudoSourceValue::getFixedStack(),SPFI);
+}
+
/// LegalizeOp - We know that the specified value has a legal type, and
/// that its operands are legal. Now ensure that the operation itself
/// is legal, recursively ensuring that the operands' operations remain
@@ -1404,40 +1455,7 @@
break;
}
}
-
- // If the target doesn't support this, we have to spill the input vector
- // to a temporary stack slot, update the element, then reload it. This is
- // badness. We could also load the value into a vector register (either
- // with a "move to register" or "extload into register" instruction, then
- // permute it into place, if the idx is a constant and if the idx is
- // supported by the target.
- MVT::ValueType VT = Tmp1.getValueType();
- MVT::ValueType EltVT = MVT::getVectorElementType(VT);
- MVT::ValueType IdxVT = Tmp3.getValueType();
- MVT::ValueType PtrVT = TLI.getPointerTy();
- SDOperand StackPtr = DAG.CreateStackTemporary(VT);
-
- FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(StackPtr.Val);
- int SPFI = StackPtrFI->getIndex();
-
- // Store the vector.
- SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr,
- PseudoSourceValue::getFixedStack(),
- SPFI);
-
- // Truncate or zero extend offset to target pointer type.
- unsigned CastOpc = (IdxVT > PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
- Tmp3 = DAG.getNode(CastOpc, PtrVT, Tmp3);
- // Add the offset to the index.
- unsigned EltSize = MVT::getSizeInBits(EltVT)/8;
- Tmp3 = DAG.getNode(ISD::MUL, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT));
- SDOperand StackPtr2 = DAG.getNode(ISD::ADD, IdxVT, Tmp3, StackPtr);
- // Store the scalar value.
- Ch = DAG.getTruncStore(Ch, Tmp2, StackPtr2,
- PseudoSourceValue::getFixedStack(), SPFI, EltVT);
- // Load the updated vector.
- Result = DAG.getLoad(VT, Ch, StackPtr,
- PseudoSourceValue::getFixedStack(), SPFI);
+ Result = PerformInsertVectorEltInMemory(Tmp1, Tmp2, Tmp3);
break;
}
}
@@ -6714,15 +6732,22 @@
Hi = Node->getOperand(1);
break;
case ISD::INSERT_VECTOR_ELT: {
- SplitVectorOp(Node->getOperand(0), Lo, Hi);
- unsigned Index = cast<ConstantSDNode>(Node->getOperand(2))->getValue();
- SDOperand ScalarOp = Node->getOperand(1);
- if (Index < NewNumElts_Lo)
- Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Lo, Lo, ScalarOp,
- DAG.getIntPtrConstant(Index));
- else
- Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Hi, Hi, ScalarOp,
- DAG.getIntPtrConstant(Index - NewNumElts_Lo));
+ if (ConstantSDNode *Idx = dyn_cast<ConstantSDNode>(Node->getOperand(2))) {
+ SplitVectorOp(Node->getOperand(0), Lo, Hi);
+ unsigned Index = Idx->getValue();
+ SDOperand ScalarOp = Node->getOperand(1);
+ if (Index < NewNumElts_Lo)
+ Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Lo, Lo, ScalarOp,
+ DAG.getIntPtrConstant(Index));
+ else
+ Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Hi, Hi, ScalarOp,
+ DAG.getIntPtrConstant(Index - NewNumElts_Lo));
+ break;
+ }
+ SDOperand Tmp = PerformInsertVectorEltInMemory(Node->getOperand(0),
+ Node->getOperand(1),
+ Node->getOperand(2));
+ SplitVectorOp(Tmp, Lo, Hi);
break;
}
case ISD::VECTOR_SHUFFLE: {
More information about the llvm-commits
mailing list