Recommitting parts of r48130. These do not appear to cause the observed failures.
authorChristopher Lamb <christopher.lamb@gmail.com>
Tue, 11 Mar 2008 10:09:17 +0000 (10:09 +0000)
committerChristopher Lamb <christopher.lamb@gmail.com>
Tue, 11 Mar 2008 10:09:17 +0000 (10:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48223 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/LowerSubregs.cpp
lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
lib/Target/Target.td
lib/Target/X86/X86ISelDAGToDAG.cpp
lib/Target/X86/X86InstrInfo.h
lib/Target/X86/X86InstrInfo.td
lib/Target/X86/X86RegisterInfo.h
lib/Target/X86/X86RegisterInfo.td

index 61601d50d0581bd99316d9073ba5f26bd7190225..531713e47fbceb17bff4f8cf7827daae95a30e7f 100644 (file)
@@ -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);
index c042acb4dd9034e39ed02068781afd6f48173df5..5b0d48df4671ed82ff640156e2d85c16443458e8 100644 (file)
@@ -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<ConstantSDNode>(Node->getOperand(1))->getValue();
-    } else {
-      SubReg = getVR(Node->getOperand(1), VRBaseMap);
-      SubIdx = cast<ConstantSDNode>(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<ConstantSDNode>(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<ConstantSDNode>(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");
index cebac7a263650b8b01f7ea5043b73025fe7a3c74..ea8f6ec3a15a7a89b1027b3489971c860925b465 100644 (file)
@@ -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;
index ea1bed19ce825307dc2e554601aae6d40f26fecf..d5601b74eab3673d10fa0f4b72dc45c9819ee954 100644 (file)
@@ -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, ' ') << "=> ";
index 839a0f248b6bffaecc1bfe311fa143c238e4f2a0..e0d0342ae6ddf20db03d435e3474725ee0a52bdc 100644 (file)
@@ -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);
   
index e32fb9c4b53b9e3a84dc610cc572f7c301727a10..4d03dba32dce9ca7fb10f02d21ed7989d6f01c0c 100644 (file)
@@ -161,6 +161,10 @@ def i32i8imm  : Operand<i32>;
 // Branch targets have OtherVT type.
 def brtarget : Operand<OtherVT>;
 
+// 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.
 //
index 8b010a924044f38da1bcf16b802dc552ca2c6feb..1c8f5e28b99f5349f30ca1f4018ec4e27eb0243c 100644 (file)
@@ -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 {
index 24402386c8e297963cf4ac39b95f3ff54fecdfdd..b713c892ba1a65fa770410f055ed5c121b27dd2b 100644 (file)
@@ -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,