From: Christopher Lamb Date: Tue, 11 Mar 2008 10:09:17 +0000 (+0000) Subject: Recommitting parts of r48130. These do not appear to cause the observed failures. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=1fab4a6bbb6eb5d44d35c8aade2493143b44d288;p=oota-llvm.git Recommitting parts of r48130. These do not appear to cause the observed failures. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48223 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/LowerSubregs.cpp index 61601d50d05..531713e47fb 100644 --- a/lib/CodeGen/LowerSubregs.cpp +++ b/lib/CodeGen/LowerSubregs.cpp @@ -90,32 +90,21 @@ bool LowerSubregsInstructionPass::LowerInsert(MachineInstr *MI) { MachineFunction &MF = *MBB->getParent(); const TargetRegisterInfo &TRI = *MF.getTarget().getRegisterInfo(); const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); - unsigned DstReg = 0; + assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) && + ((MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) || + MI->getOperand(1).isImmediate()) && + (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) && + MI->getOperand(3).isImmediate() && "Invalid insert_subreg"); + + unsigned DstReg = MI->getOperand(0).getReg(); unsigned SrcReg = 0; - unsigned InsReg = 0; - unsigned SubIdx = 0; - - // If only have 3 operands, then the source superreg is undef - // and we can supress the copy from the undef value - if (MI->getNumOperands() == 3) { - assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) && - (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) && - MI->getOperand(2).isImmediate() && "Invalid extract_subreg"); - DstReg = MI->getOperand(0).getReg(); + // Check if we're inserting into an implicit value. + if (MI->getOperand(1).isImmediate()) SrcReg = DstReg; - InsReg = MI->getOperand(1).getReg(); - SubIdx = MI->getOperand(2).getImm(); - } else if (MI->getNumOperands() == 4) { - assert((MI->getOperand(0).isRegister() && MI->getOperand(0).isDef()) && - (MI->getOperand(1).isRegister() && MI->getOperand(1).isUse()) && - (MI->getOperand(2).isRegister() && MI->getOperand(2).isUse()) && - MI->getOperand(3).isImmediate() && "Invalid extract_subreg"); - DstReg = MI->getOperand(0).getReg(); + else SrcReg = MI->getOperand(1).getReg(); - InsReg = MI->getOperand(2).getReg(); - SubIdx = MI->getOperand(3).getImm(); - } else - assert(0 && "Malformed extract_subreg"); + unsigned InsReg = MI->getOperand(2).getReg(); + unsigned SubIdx = MI->getOperand(3).getImm(); assert(SubIdx != 0 && "Invalid index for extract_subreg"); unsigned DstSubReg = TRI.getSubReg(DstReg, SubIdx); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index c042acb4dd9..5b0d48df467 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -695,19 +695,11 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node, MI->addOperand(MachineOperand::CreateImm(SubIdx)); } else if (Opc == TargetInstrInfo::INSERT_SUBREG) { - assert((Node->getNumOperands() == 2 || Node->getNumOperands() == 3) && - "Malformed insert_subreg node"); - bool isUndefInput = (Node->getNumOperands() == 2); - unsigned SubReg = 0; - unsigned SubIdx = 0; - - if (isUndefInput) { - SubReg = getVR(Node->getOperand(0), VRBaseMap); - SubIdx = cast(Node->getOperand(1))->getValue(); - } else { - SubReg = getVR(Node->getOperand(1), VRBaseMap); - SubIdx = cast(Node->getOperand(2))->getValue(); - } + SDOperand N0 = Node->getOperand(0); + SDOperand N1 = Node->getOperand(1); + SDOperand N2 = Node->getOperand(2); + unsigned SubReg = getVR(N1, VRBaseMap); + unsigned SubIdx = cast(N2)->getValue(); // TODO: Add tracking info to MachineRegisterInfo of which vregs are subregs // to allow coalescing in the allocator @@ -745,9 +737,15 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node, } MI->addOperand(MachineOperand::CreateReg(VRBase, true)); - AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap); - if (!isUndefInput) - AddOperand(MI, Node->getOperand(1), 0, 0, VRBaseMap); + + // If N0 is a constant then it indicates the insert is being done + // into a target specific constant value, not a register. + if (const ConstantSDNode *SD = dyn_cast(N0)) + MI->addOperand(MachineOperand::CreateImm(SD->getValue())); + else + AddOperand(MI, N0, 0, 0, VRBaseMap); + // Add the subregster being inserted + AddOperand(MI, N1, 0, 0, VRBaseMap); MI->addOperand(MachineOperand::CreateImm(SubIdx)); } else assert(0 && "Node is not a subreg insert or extract"); diff --git a/lib/Target/Target.td b/lib/Target/Target.td index cebac7a2636..ea8f6ec3a15 100644 --- a/lib/Target/Target.td +++ b/lib/Target/Target.td @@ -263,6 +263,10 @@ def variable_ops; /// flags. But currently we have but one flag. def ptr_rc; +/// unknown definition - Mark this operand as being of unknown type, causing +/// it to be resolved by inference in the context it is used. +def unknown; + /// Operand Types - These provide the built-in operand types that may be used /// by a target. Targets can optionally provide their own operand types as /// needed, though this should not be needed for RISC targets. @@ -351,15 +355,15 @@ def DECLARE : Instruction { let hasCtrlDep = 1; } def EXTRACT_SUBREG : Instruction { - let OutOperandList = (ops variable_ops); - let InOperandList = (ops variable_ops); + let OutOperandList = (ops unknown:$dst); + let InOperandList = (ops unknown:$supersrc, i32imm:$subidx); let AsmString = ""; let Namespace = "TargetInstrInfo"; let neverHasSideEffects = 1; } def INSERT_SUBREG : Instruction { - let OutOperandList = (ops variable_ops); - let InOperandList = (ops variable_ops); + let OutOperandList = (ops unknown:$dst); + let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx); let AsmString = ""; let Namespace = "TargetInstrInfo"; let neverHasSideEffects = 1; diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index ea1bed19ce8..d5601b74eab 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -1533,22 +1533,27 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) { AddToISelQueue(N0); if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) { SDOperand SRIdx; + SDOperand ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_UNDEF, + MVT::i32); switch(N0.getValueType()) { case MVT::i32: - SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3 + SRIdx = CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32); + // x86-64 zero extends 32-bit inserts int 64-bit registers + if (Subtarget->is64Bit()) + ImplVal = CurDAG->getTargetConstant(X86::IMPL_VAL_ZERO, MVT::i32); break; case MVT::i16: - SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2 + SRIdx = CurDAG->getTargetConstant(X86::SUBREG_16BIT, MVT::i32); break; case MVT::i8: if (Subtarget->is64Bit()) - SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1 + SRIdx = CurDAG->getTargetConstant(X86::SUBREG_8BIT, MVT::i32); break; default: assert(0 && "Unknown any_extend!"); } if (SRIdx.Val) { SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG, - NVT, N0, SRIdx); + NVT, ImplVal, N0, SRIdx); #ifndef NDEBUG DOUT << std::string(Indent-2, ' ') << "=> "; diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 839a0f248b6..e0d0342ae6d 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -46,6 +46,14 @@ namespace X86 { COND_INVALID }; + // X86 specific implict values used for subregister inserts. + // This can be used to model the fact that x86-64 by default + // inserts 32-bit values into 64-bit registers implicitly containing zeros. + enum ImplicitVal { + IMPL_VAL_UNDEF = 0, + IMPL_VAL_ZERO = 1 + }; + // Turn condition code into conditional branch opcode. unsigned GetCondBranchFromCond(CondCode CC); diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index e32fb9c4b53..4d03dba32dc 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -161,6 +161,10 @@ def i32i8imm : Operand; // Branch targets have OtherVT type. def brtarget : Operand; +// These should match the enum X86::ImplicitVal +def x86_impl_val_undef : PatLeaf<(i32 0)>; +def x86_impl_val_zero : PatLeaf<(i32 1)>; + //===----------------------------------------------------------------------===// // X86 Complex Pattern Definitions. // diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h index 8b010a92404..1c8f5e28b99 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -32,6 +32,15 @@ namespace N86 { }; } +namespace X86 { + /// SubregIndex - The index of various sized subregister classes. Note that + /// these indices must be kept in sync with the class indices in the + /// X86RegisterInfo.td file. + enum SubregIndex { + SUBREG_8BIT = 1, SUBREG_16BIT = 2, SUBREG_32BIT = 3 + }; +} + /// DWARFFlavour - Flavour of dwarf regnumbers /// namespace DWARFFlavour { diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index 24402386c8e..b713c892ba1 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -176,6 +176,10 @@ let Namespace = "X86" in { // sub registers for each register. // +def x86_subreg_8bit : PatLeaf<(i32 1)>; +def x86_subreg_16bit : PatLeaf<(i32 2)>; +def x86_subreg_32bit : PatLeaf<(i32 3)>; + def : SubRegSet<1, [AX, CX, DX, BX, SP, BP, SI, DI, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W], [AL, CL, DL, BL, SPL, BPL, SIL, DIL,