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: {
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 730f393..59d7afc 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -1202,43 +1202,43 @@
// Zero-extension
-def : Pat<(i64 (zext GR32:$src)), (INSERT_SUBREG tii_impl_val_zero,
- GR32:$src, x86_subreg_32bit)>;
+def : Pat<(i64 (zext GR32:$src)),
+ (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>;
// zextload bool -> zextload byte
def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
-def : Pat<(zextloadi64i32 addr:$src), (INSERT_SUBREG tii_impl_val_zero,
- (MOV32rm addr:$src), x86_subreg_32bit)>;
+def : Pat<(zextloadi64i32 addr:$src),
+ (SUBREG_TO_REG (i64 0), (MOV32rm addr:$src), x86_subreg_32bit)>;
// extload
def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>;
def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
-def : Pat<(extloadi64i32 addr:$src), (INSERT_SUBREG tii_impl_val_undef,
- (MOV32rm addr:$src), x86_subreg_32bit)>;
+def : Pat<(extloadi64i32 addr:$src),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
+ x86_subreg_32bit)>;
// anyext -> zext
def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8 GR8 :$src)>;
def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16:$src)>;
-def : Pat<(i64 (anyext GR32:$src)), (INSERT_SUBREG tii_impl_val_undef,
- GR32:$src, x86_subreg_32bit)>;
+def : Pat<(i64 (anyext GR32:$src)),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>;
def : Pat<(i64 (anyext (loadi8 addr:$src))), (MOVZX64rm8 addr:$src)>;
def : Pat<(i64 (anyext (loadi16 addr:$src))), (MOVZX64rm16 addr:$src)>;
-def : Pat<(i64 (anyext (loadi32 addr:$src))), (INSERT_SUBREG tii_impl_val_undef,
- (MOV32rm addr:$src),
- x86_subreg_32bit)>;
+def : Pat<(i64 (anyext (loadi32 addr:$src))),
+ (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
+ x86_subreg_32bit)>;
//===----------------------------------------------------------------------===//
// Some peepholes
//===----------------------------------------------------------------------===//
-
// r & (2^32-1) ==> mov32 + implicit zext
def : Pat<(and GR64:$src, i64immFFFFFFFF),
- (INSERT_SUBREG tii_impl_val_zero,
- (MOV32rr (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)),
+ (SUBREG_TO_REG (i64 0),
+ (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)),
x86_subreg_32bit)>;
// (shl x, 1) ==> (add x, x)
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index ff666ff..650ab41 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -920,10 +920,11 @@
// Build and insert into an implicit UNDEF value. This is OK because
// well be shifting and then extracting the lower 16-bits.
+ MachineInstr *Undef = BuildMI(get(X86::IMPLICIT_DEF), leaInReg);
+
MachineInstr *Ins =
BuildMI(get(X86::INSERT_SUBREG),leaInReg)
- .addImm(X86InstrInfo::IMPL_VAL_UNDEF)
- .addReg(Src).addImm(X86::SUBREG_16BIT);
+ .addReg(leaInReg).addReg(Src).addImm(X86::SUBREG_16BIT);
NewMI = BuildMI(get(Opc), leaOutReg)
.addReg(0).addImm(1 << ShAmt).addReg(leaInReg).addImm(0);
@@ -933,6 +934,7 @@
.addReg(leaOutReg).addImm(X86::SUBREG_16BIT);
Ext->copyKillDeadInfo(MI);
+ MFI->insert(MBBI, Undef);
MFI->insert(MBBI, Ins); // Insert the insert_subreg
LV.instructionChanged(MI, NewMI); // Update live variables
LV.addVirtualRegisterKilled(leaInReg, NewMI);