diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 75480930311..39f380acfae 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -219,6 +219,11 @@ static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) { // and mask opcode and mask operation. static bool isRotateAndMask(SDNode *N, unsigned Mask, bool IsShiftMask, unsigned &SH, unsigned &MB, unsigned &ME) { + // Don't even go down this path for i64, since different logic will be + // necessary for rldicl/rldicr/rldimi. + if (N->getValueType(0) != MVT::i32) + return false; + unsigned Shift = 32; unsigned Indeterminant = ~0; // bit mask marking indeterminant results unsigned Opcode = N->getOpcode(); @@ -1206,14 +1211,27 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) { // Other cases are autogenerated. break; + case ISD::TRUNCATE: { + assert(N->getValueType(0) == MVT::i32 && + N->getOperand(0).getValueType() == MVT::i64 && + "TRUNCATE only supported for i64 -> i32"); + // FIXME: this code breaks ScheduleDAG since Op0 is an i64 and OR4 + // takes i32s. + SDOperand Op0 = Select(N->getOperand(0)); + CurDAG->SelectNodeTo(N, PPC::OR4, MVT::i32, Op0, Op0); + break; + } case ISD::ANY_EXTEND: switch(N->getValueType(0)) { default: assert(0 && "Unhandled type in ANY_EXTEND"); - case MVT::i64: - CurDAG->SelectNodeTo(N, PPC::OR8, MVT::i64, Select(N->getOperand(0)), - Select(N->getOperand(0))); + case MVT::i64: { + // FIXME: this code breaks ScheduleDAG since Op0 is an i32 and OR8 + // takes i64s. + SDOperand Op0 = Select(N->getOperand(0)); + CurDAG->SelectNodeTo(N, PPC::OR8, MVT::i64, Op0, Op0); break; } + } return SDOperand(N, 0); case ISD::ZERO_EXTEND: assert(N->getValueType(0) == MVT::i64 && |

