Make insert_subreg a two-address instruction, vastly simplifying LowerSubregs pass. Add a new TII, subreg_to_reg, which is like insert_subreg except that it takes an immediate implicit value to insert into rather than a register.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48412 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index bf233bf..7a55d9d 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -1529,39 +1529,36 @@
}
case ISD::ANY_EXTEND: {
+ // Check if the type extended to supports subregs.
+ if (NVT == MVT::i8)
+ break;
+
SDOperand N0 = Node->getOperand(0);
+ // Get the subregsiter index for the type to extend.
+ MVT::ValueType N0VT = N0.getValueType();
+ unsigned Idx = (N0VT == MVT::i32) ? X86::SUBREG_32BIT :
+ (N0VT == MVT::i16) ? X86::SUBREG_16BIT :
+ (Subtarget->is64Bit()) ? X86::SUBREG_8BIT : 0;
+
+ // If we don't have a subreg Idx, let generated ISel have a try.
+ if (Idx == 0)
+ break;
+
+ // If we have an index, generate an insert_subreg into undef.
AddToISelQueue(N0);
- if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
- SDOperand SRIdx;
- switch(N0.getValueType()) {
- case MVT::i32:
- SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
- break;
- case MVT::i16:
- SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32);
- break;
- case MVT::i8:
- if (Subtarget->is64Bit())
- SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32);
- break;
- default: assert(0 && "Unknown any_extend!");
- }
- if (SRIdx.Val) {
- SDOperand ImplVal =
- CurDAG->getTargetConstant(X86InstrInfo::IMPL_VAL_UNDEF, MVT::i32);
- SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
- NVT, ImplVal, N0, SRIdx);
+ SDOperand Undef =
+ SDOperand(CurDAG->getTargetNode(X86::IMPLICIT_DEF, NVT), 0);
+ SDOperand SRIdx = CurDAG->getTargetConstant(Idx, MVT::i32);
+ SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
+ NVT, Undef, N0, SRIdx);
#ifndef NDEBUG
- DOUT << std::string(Indent-2, ' ') << "=> ";
- DEBUG(ResNode->dump(CurDAG));
- DOUT << "\n";
- Indent -= 2;
+ DOUT << std::string(Indent-2, ' ') << "=> ";
+ DEBUG(ResNode->dump(CurDAG));
+ DOUT << "\n";
+ Indent -= 2;
#endif
- return ResNode;
- } // Otherwise let generated ISel handle it.
- }
- break;
+ return ResNode;
}
case ISD::SIGN_EXTEND_INREG: {