summaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorNadav Rotem <nadav.rotem@intel.com>2011-10-11 10:04:25 +0000
committerNadav Rotem <nadav.rotem@intel.com>2011-10-11 10:04:25 +0000
commitc2b2e1333d66e37c657e25fc09dc79e4ea1d79d9 (patch)
tree0f9c31c32aac2da2083a6e05ea064bd35aecb859 /lib/CodeGen
parenteb13b61d3d047e98f4c33c5ca0545aecd8f551d1 (diff)
downloadllvm-c2b2e1333d66e37c657e25fc09dc79e4ea1d79d9.tar.gz
llvm-c2b2e1333d66e37c657e25fc09dc79e4ea1d79d9.tar.bz2
llvm-c2b2e1333d66e37c657e25fc09dc79e4ea1d79d9.tar.xz
Cleanup the trunc-store legalization code and add asserts.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141659 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp155
1 files changed, 87 insertions, 68 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 1292297d51..8c961479bc 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1607,82 +1607,101 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
EVT WideScalarVT = Tmp3.getValueType().getScalarType();
EVT NarrowScalarVT = StVT.getScalarType();
- // The Store type is illegal, must scalarize the vector store.
- SmallVector<SDValue, 8> Stores;
- bool ScalarLegal = TLI.isTypeLegal(WideScalarVT);
- if (!TLI.isTypeLegal(StVT) && StVT.isVector() && ScalarLegal) {
+ if (StVT.isVector()) {
unsigned NumElem = StVT.getVectorNumElements();
+ // The type of the data we want to save
+ EVT RegVT = Tmp3.getValueType();
+ EVT RegSclVT = RegVT.getScalarType();
+ // The type of data as saved in memory.
+ EVT MemSclVT = StVT.getScalarType();
+
+ bool RegScalarLegal = TLI.isTypeLegal(RegSclVT);
+ bool MemScalarLegal = TLI.isTypeLegal(MemSclVT);
+
+ // We need to expand this store. If both the reg-scalar and the
+ // memory-scalar are of legal types, then scalarize the vector.
+ if (RegScalarLegal && MemScalarLegal) {
+ // Cast floats into integers
+ unsigned ScalarSize = MemSclVT.getSizeInBits();
+ EVT EltVT = EVT::getIntegerVT(*DAG.getContext(), ScalarSize);
+ assert(TLI.isTypeLegal(EltVT) && "Saved scalars must be legal");
+
+ // Round odd types to the next pow of two.
+ if (!isPowerOf2_32(ScalarSize))
+ ScalarSize = NextPowerOf2(ScalarSize);
+
+ // Store Stride in bytes
+ unsigned Stride = ScalarSize/8;
+ // Extract each of the elements from the original vector
+ // and save them into memory individually.
+ SmallVector<SDValue, 8> Stores;
+ for (unsigned Idx = 0; Idx < NumElem; Idx++) {
+ SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
+ RegSclVT, Tmp3, DAG.getIntPtrConstant(Idx));
+
+ Ex = DAG.getNode(ISD::TRUNCATE, dl, EltVT, Ex);
+ Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
+ DAG.getIntPtrConstant(Stride));
- unsigned ScalarSize = StVT.getScalarType().getSizeInBits();
- EVT EltVT = EVT::getIntegerVT(*DAG.getContext(), ScalarSize);
- assert(TLI.isTypeLegal(EltVT) && "Scalar store type must be legal");
-
- // Round odd types to the next pow of two.
- if (!isPowerOf2_32(ScalarSize))
- ScalarSize = NextPowerOf2(ScalarSize);
- // Types smaller than 8 bits are promoted to 8 bits.
- ScalarSize = std::max<unsigned>(ScalarSize, 8);
- // Store stride
- unsigned Stride = ScalarSize/8;
- assert(isPowerOf2_32(Stride) && "Stride must be a power of two");
-
- for (unsigned Idx=0; Idx<NumElem; Idx++) {
- SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
- WideScalarVT, Tmp3, DAG.getIntPtrConstant(Idx));
-
- Ex = DAG.getNode(ISD::TRUNCATE, dl, EltVT, Ex);
- Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
- DAG.getIntPtrConstant(Stride));
- SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2,
- ST->getPointerInfo().getWithOffset(Idx*Stride),
- isVolatile, isNonTemporal, Alignment);
- Stores.push_back(Store);
- }
- Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
- &Stores[0], Stores.size());
- break;
- }
-
- // The Store type is illegal, must scalarize the vector store.
- // However, the scalar type is illegal. Must bitcast the result
- // and store it in smaller parts.
- if (!TLI.isTypeLegal(StVT) && StVT.isVector()) {
- unsigned WideNumElem = StVT.getVectorNumElements();
- unsigned Stride = NarrowScalarVT.getSizeInBits()/8;
-
- unsigned SizeRatio =
- (WideScalarVT.getSizeInBits() / NarrowScalarVT.getSizeInBits());
-
- EVT CastValueVT = EVT::getVectorVT(*DAG.getContext(), NarrowScalarVT,
- SizeRatio*WideNumElem);
-
- // Cast the wide elem vector to wider vec with smaller elem type.
- // Example <2 x i64> -> <4 x i32>
- Tmp3 = DAG.getNode(ISD::BITCAST, dl, CastValueVT, Tmp3);
-
- for (unsigned Idx=0; Idx<WideNumElem*SizeRatio; Idx++) {
- // Extract elment i
- SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
- NarrowScalarVT, Tmp3, DAG.getIntPtrConstant(Idx));
- // bump pointer.
- Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
- DAG.getIntPtrConstant(Stride));
-
- // Store if, this element is:
- // - First element on big endian, or
- // - Last element on little endian
- if (( TLI.isBigEndian() && (Idx%SizeRatio == 0)) ||
- ((!TLI.isBigEndian() && (Idx%SizeRatio == SizeRatio-1)))) {
SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2,
ST->getPointerInfo().getWithOffset(Idx*Stride),
isVolatile, isNonTemporal, Alignment);
Stores.push_back(Store);
}
+
+ Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ &Stores[0], Stores.size());
+ break;
}
- Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
- &Stores[0], Stores.size());
- break;
- }
+
+
+ // The scalar register type is illegal.
+ // For example saving <2 x i64> -> <2 x i32> on a x86.
+ // In here we bitcast the value into a vector of smaller parts and
+ // save it using smaller scalars.
+ if (!RegScalarLegal && MemScalarLegal) {
+ // Store Stride in bytes
+ unsigned Stride = MemSclVT.getSizeInBits()/8;
+
+ unsigned SizeRatio =
+ (RegSclVT.getSizeInBits() / MemSclVT.getSizeInBits());
+
+ EVT CastValueVT = EVT::getVectorVT(*DAG.getContext(),
+ MemSclVT,
+ SizeRatio * NumElem);
+
+ // Cast the wide elem vector to wider vec with smaller elem type.
+ // Example <2 x i64> -> <4 x i32>
+ Tmp3 = DAG.getNode(ISD::BITCAST, dl, CastValueVT, Tmp3);
+
+ SmallVector<SDValue, 8> Stores;
+ for (unsigned Idx=0; Idx < NumElem * SizeRatio; Idx++) {
+ // Extract the Ith element.
+ SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
+ NarrowScalarVT, Tmp3, DAG.getIntPtrConstant(Idx));
+ // Bump pointer.
+ Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2,
+ DAG.getIntPtrConstant(Stride));
+
+ // Store if, this element is:
+ // - First element on big endian, or
+ // - Last element on little endian
+ if (( TLI.isBigEndian() && (Idx % SizeRatio == 0)) ||
+ ((!TLI.isBigEndian() && (Idx % SizeRatio == SizeRatio-1)))) {
+ SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2,
+ ST->getPointerInfo().getWithOffset(Idx*Stride),
+ isVolatile, isNonTemporal, Alignment);
+ Stores.push_back(Store);
+ }
+ }
+ Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
+ &Stores[0], Stores.size());
+ break;
+ }
+
+
+ assert(false && "Unable to legalize the vector trunc store!");
+ }// is vector
// TRUNCSTORE:i16 i32 -> STORE i16