aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h8
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp8
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp26
3 files changed, 26 insertions, 16 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 49012b4..4f2574e 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -217,10 +217,10 @@ namespace ISD {
/// alignment '1' in other argument pieces.
CALL,
- // EXTRACT_ELEMENT - This is used to get the first or second (determined by
- // a Constant, which is required to be operand #1), element of the aggregate
- // value specified as operand #0. This is only for use before legalization,
- // for values that will be broken into multiple registers.
+ // EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
+ // a Constant, which is required to be operand #1) half of the integer value
+ // specified as operand #0. This is only for use before legalization, for
+ // values that will be broken into multiple registers.
EXTRACT_ELEMENT,
// BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. Given
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 6e15318..03ca532 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2090,13 +2090,17 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
break;
case ISD::EXTRACT_ELEMENT:
assert(N2C && (unsigned)N2C->getValue() < 2 && "Bad EXTRACT_ELEMENT!");
-
+ assert(!MVT::isVector(N1.getValueType()) &&
+ MVT::isInteger(N1.getValueType()) &&
+ !MVT::isVector(VT) && MVT::isInteger(VT) &&
+ "EXTRACT_ELEMENT only applies to integers!");
+
// EXTRACT_ELEMENT of BUILD_PAIR is often formed while legalize is expanding
// 64-bit integers into 32-bit parts. Instead of building the extract of
// the BUILD_PAIR, only to have legalize rip it apart, just do it now.
if (N1.getOpcode() == ISD::BUILD_PAIR)
return N1.getOperand(N2C->getValue());
-
+
// EXTRACT_ELEMENT of a constant int is also very common.
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N1)) {
unsigned Shift = MVT::getSizeInBits(VT) * N2C->getValue();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 34153e1..c3ae2a9 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -852,19 +852,25 @@ static void getCopyToParts(SelectionDAG &DAG,
// The number of parts is a power of 2. Repeatedly bisect the value using
// EXTRACT_ELEMENT.
- Parts[0] = Val;
+ Parts[0] = DAG.getNode(ISD::BIT_CONVERT,
+ MVT::getIntegerType(MVT::getSizeInBits(ValueVT)),
+ Val);
for (unsigned StepSize = NumParts; StepSize > 1; StepSize /= 2) {
for (unsigned i = 0; i < NumParts; i += StepSize) {
unsigned ThisBits = StepSize * PartBits / 2;
- MVT::ValueType ThisVT =
- ThisBits == PartBits ? PartVT : MVT::getIntegerType (ThisBits);
-
- Parts[i+StepSize/2] =
- DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Parts[i],
- DAG.getConstant(1, PtrVT));
- Parts[i] =
- DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Parts[i],
- DAG.getConstant(0, PtrVT));
+ MVT::ValueType ThisVT = MVT::getIntegerType (ThisBits);
+ SDOperand &Part0 = Parts[i];
+ SDOperand &Part1 = Parts[i+StepSize/2];
+
+ Part1 = DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Part0,
+ DAG.getConstant(1, PtrVT));
+ Part0 = DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Part0,
+ DAG.getConstant(0, PtrVT));
+
+ if (ThisBits == PartBits && ThisVT != PartVT) {
+ Part0 = DAG.getNode(ISD::BIT_CONVERT, PartVT, Part0);
+ Part1 = DAG.getNode(ISD::BIT_CONVERT, PartVT, Part1);
+ }
}
}