summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2008-02-27 22:36:00 +0000
committerDale Johannesen <dalej@apple.com>2008-02-27 22:36:00 +0000
commitbf76a08e7c1a4a61c67a49e70dcfa4bb754d12ef (patch)
tree39870b06e5b7f89df6ade0043a2b119e994cfed9 /llvm/lib/CodeGen
parent91a6dcff327f11bb8ceaed28d4595a98eabdfd6a (diff)
downloadbcm5719-llvm-bf76a08e7c1a4a61c67a49e70dcfa4bb754d12ef.tar.gz
bcm5719-llvm-bf76a08e7c1a4a61c67a49e70dcfa4bb754d12ef.zip
Handle load/store of misaligned vectors that are the
same size as an int type by doing a bitconvert of load/store of the int type (same algorithm as floating point). This makes them work for ppc Altivec. There was some code that purported to handle loads of (some) vectors by splitting them into two smaller vectors, but getExtLoad rejects subvector loads, so this could never have worked; the patch removes it. llvm-svn: 47696
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp49
1 files changed, 30 insertions, 19 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 7df4c3f2acc..ff4ddf373f1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -569,22 +569,32 @@ SDOperand ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
MVT::ValueType VT = Val.getValueType();
int Alignment = ST->getAlignment();
int SVOffset = ST->getSrcValueOffset();
- if (MVT::isFloatingPoint(ST->getMemoryVT())) {
+ if (MVT::isFloatingPoint(ST->getMemoryVT()) ||
+ MVT::isVector(ST->getMemoryVT())) {
// Expand to a bitconvert of the value to the integer type of the
// same size, then a (misaligned) int store.
MVT::ValueType intVT;
- if (VT==MVT::f64)
+ if (VT == MVT::v8i16 || VT == MVT::v4i32 ||
+ VT == MVT::v2i64 || VT == MVT::v2f64 ||
+ VT == MVT::v4f32 || VT == MVT::v16i8 ||
+ VT == MVT::ppcf128)
+ intVT = MVT::i128;
+ else if (VT==MVT::f64 ||
+ VT == MVT::v8i8 || VT == MVT::v4i16 ||
+ VT == MVT::v2i32 || VT == MVT::v1i64 ||
+ VT == MVT::v2f32)
intVT = MVT::i64;
else if (VT==MVT::f32)
intVT = MVT::i32;
else
- assert(0 && "Unaligned load of unsupported floating point type");
+ assert(0 && "Unaligned load of unsupported type");
SDOperand Result = DAG.getNode(ISD::BIT_CONVERT, intVT, Val);
return DAG.getStore(Chain, Result, Ptr, ST->getSrcValue(),
SVOffset, ST->isVolatile(), Alignment);
}
assert(MVT::isInteger(ST->getMemoryVT()) &&
+ !MVT::isVector(ST->getMemoryVT()) &&
"Unaligned store of unknown type.");
// Get the half-size VT
MVT::ValueType NewStoredVT = ST->getMemoryVT() - 1;
@@ -620,43 +630,44 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
SDOperand Ptr = LD->getBasePtr();
MVT::ValueType VT = LD->getValueType(0);
MVT::ValueType LoadedVT = LD->getMemoryVT();
- if (MVT::isFloatingPoint(VT) && !MVT::isVector(VT)) {
+ if (MVT::isFloatingPoint(VT) || MVT::isVector(VT)) {
// Expand to a (misaligned) integer load of the same size,
- // then bitconvert to floating point.
+ // then bitconvert to floating point or vector.
MVT::ValueType intVT;
- if (LoadedVT == MVT::f64)
+ if (LoadedVT == MVT::v8i16 || LoadedVT == MVT::v4i32 ||
+ LoadedVT == MVT::v2i64 || LoadedVT == MVT::v2f64 ||
+ LoadedVT == MVT::v4f32 || LoadedVT == MVT::v16i8 ||
+ LoadedVT == MVT::ppcf128)
+ intVT = MVT::i128;
+ else if (LoadedVT == MVT::f64 ||
+ LoadedVT == MVT::v8i8 || LoadedVT == MVT::v4i16 ||
+ LoadedVT == MVT::v2i32 || LoadedVT == MVT::v1i64 ||
+ LoadedVT == MVT::v2f32)
intVT = MVT::i64;
else if (LoadedVT == MVT::f32)
intVT = MVT::i32;
else
- assert(0 && "Unaligned load of unsupported floating point type");
+ assert(0 && "Unaligned load of unsupported type");
SDOperand newLoad = DAG.getLoad(intVT, Chain, Ptr, LD->getSrcValue(),
SVOffset, LD->isVolatile(),
LD->getAlignment());
SDOperand Result = DAG.getNode(ISD::BIT_CONVERT, LoadedVT, newLoad);
- if (LoadedVT != VT)
+ if (MVT::isFloatingPoint(VT) && LoadedVT != VT)
Result = DAG.getNode(ISD::FP_EXTEND, VT, Result);
SDOperand Ops[] = { Result, Chain };
return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other),
Ops, 2);
}
- assert((MVT::isInteger(LoadedVT) || MVT::isVector(LoadedVT)) &&
+ assert(MVT::isInteger(LoadedVT) && !MVT::isVector(LoadedVT) &&
"Unaligned load of unsupported type.");
- // Compute the new VT that is half the size of the old one. We either have an
- // integer MVT or we have a vector MVT.
+ // Compute the new VT that is half the size of the old one. This is an
+ // integer MVT.
unsigned NumBits = MVT::getSizeInBits(LoadedVT);
MVT::ValueType NewLoadedVT;
- if (!MVT::isVector(LoadedVT)) {
- NewLoadedVT = MVT::getIntegerType(NumBits/2);
- } else {
- // FIXME: This is not right for <1 x anything> it is also not right for
- // non-power-of-two vectors.
- NewLoadedVT = MVT::getVectorType(MVT::getVectorElementType(LoadedVT),
- MVT::getVectorNumElements(LoadedVT)/2);
- }
+ NewLoadedVT = MVT::getIntegerType(NumBits/2);
NumBits >>= 1;
unsigned Alignment = LD->getAlignment();
OpenPOWER on IntegriCloud