Major bug fix though it happened rarely (only on a compare after an
authorVikram S. Adve <vadve@cs.uiuc.edu>
Sun, 6 Jul 2003 20:13:59 +0000 (20:13 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Sun, 6 Jul 2003 20:13:59 +0000 (20:13 +0000)
integer overflow):
We need to use %icc and not %xcc for comparisons on 32-bit or smaller
integer values.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7111 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SparcV9/SparcV9AsmPrinter.cpp
lib/Target/SparcV9/SparcV9InstrSelection.cpp
lib/Target/SparcV9/SparcV9RegClassInfo.cpp
lib/Target/SparcV9/SparcV9RegClassInfo.h
lib/Target/SparcV9/SparcV9RegInfo.cpp

index f66b36f9be4a613812bb6ebc626a499ccd6adfff..829a3b8bb3120f32c53eb59107e7a473b35b0c45 100644 (file)
@@ -393,12 +393,27 @@ SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop,
   
   switch (mop.getType())
     {
-    case MachineOperand::MO_VirtualRegister:
     case MachineOperand::MO_CCRegister:
+      {
+        // We need to print %icc or %xcc as %ccr for certain opcodes.
+        int regNum = (int)mop.getAllocatedRegNum();
+        if (regNum != Target.getRegInfo().getInvalidRegNum() &&
+            Target.getRegInfo().getRegClassIDOfReg(regNum)
+            == UltraSparcRegInfo::IntCCRegClassID)
+          {
+            if (opCode == V9::RDCCR || opCode == V9::WRCCRi || opCode == V9::WRCCRr)
+              {
+                toAsm << "%" << Target.getRegInfo().getMachineRegClass(UltraSparcRegInfo::IntCCRegClassID)->getRegName(SparcIntCCRegClass::ccr);
+                break;
+              }
+          }
+        // all other cases can be handled like any other register
+      }
+
+    case MachineOperand::MO_VirtualRegister:
     case MachineOperand::MO_MachineRegister:
       {
         int regNum = (int)mop.getAllocatedRegNum();
-        
         if (regNum == Target.getRegInfo().getInvalidRegNum()) {
           // better to print code with NULL registers than to die
           toAsm << "<NULL VALUE>";
index 58c15edc29f239ac39de865caf7c02781f253b59..abb7fbecc8d240a173afbeba5120a156ea010fef 100644 (file)
@@ -386,16 +386,14 @@ GetTmpForCC(Value* boolVal, const Function *F, const Type* ccType,
 
 static inline MachineOpCode 
 ChooseBccInstruction(const InstructionNode* instrNode,
-                     bool& isFPBranch)
+                     const Type*& setCCType)
 {
   InstructionNode* setCCNode = (InstructionNode*) instrNode->leftChild();
   assert(setCCNode->getOpLabel() == SetCCOp);
   BinaryOperator* setCCInstr =cast<BinaryOperator>(setCCNode->getInstruction());
-  const Type* setCCType = setCCInstr->getOperand(0)->getType();
+  setCCType = setCCInstr->getOperand(0)->getType();
   
-  isFPBranch = setCCType->isFloatingPoint(); // Return value: don't delete!
-  
-  if (isFPBranch)
+  if (setCCType->isFloatingPoint())
     return ChooseBFpccInstruction(instrNode, setCCInstr);
   else
     return ChooseBpccInstruction(instrNode, setCCInstr);
@@ -1604,11 +1602,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         // TmpInstruction representing that CC.
         // 
         BranchInst* brInst = cast<BranchInst>(subtreeRoot->getInstruction());
-        bool isFPBranch;
-        unsigned Opcode = ChooseBccInstruction(subtreeRoot, isFPBranch);
+        const Type* setCCType;
+        unsigned Opcode = ChooseBccInstruction(subtreeRoot, setCCType);
         Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(),
                                      brInst->getParent()->getParent(),
-                                     isFPBranch? Type::FloatTy : Type::IntTy,
+                                     setCCType,
                                      MachineCodeForInstruction::get(brInst));
         M = BuildMI(Opcode, 2).addCCReg(ccValue)
                               .addPCDisp(brInst->getSuccessor(0));
@@ -2058,7 +2056,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         // 
         TmpInstruction* tmpForCC = GetTmpForCC(setCCInstr,
                                     setCCInstr->getParent()->getParent(),
-                                    isFPCompare ? Type::FloatTy : Type::IntTy,
+                                    leftVal->getType(),
                                     MachineCodeForInstruction::get(setCCInstr));
         if (! isFPCompare) {
           // Integer condition: set CC and discard result.
index 63b39c162499c21c4b9c1550a3bed88c78bfadb1..1640dcab6c68d3c405e136dc6d388093878ad81a 100644 (file)
@@ -112,6 +112,47 @@ void SparcIntRegClass::colorIGNode(IGNode * Node,
     LR->markForSpill();               // no color found - must spill
 }
 
+//-----------------------------------------------------------------------------
+// Int CC Register Class - method for coloring a node in the interference graph.
+//
+// Algorithm:
+//
+//     If the single int CC register is used (either as icc or xcc)
+//         mark the LR for spilling
+//     else {
+//         if (the LR is a 64-bit comparison) use %xcc
+//         else /*32-bit or smaller*/ use %icc
+//     }
+// 
+// Note: The third name (%ccr) is essentially an assembly mnemonic and
+// depends solely on the opcode, so the name can be chosen in EmitAssembly.
+//-----------------------------------------------------------------------------
+void SparcIntCCRegClass::colorIGNode(IGNode *Node,
+                                     std::vector<bool> &IsColorUsedArr) const
+{
+  if (IsColorUsedArr[xcc] && IsColorUsedArr[icc])
+    Node->getParentLR()->markForSpill();
+  else {
+    // Choose whether to use %xcc or %icc based on type of value compared
+    const LiveRange* ccLR = Node->getParentLR();
+    const Type* setCCType = (* ccLR->begin())->getType(); // any Value in LR
+    assert(setCCType->isIntegral());
+    int ccReg = (setCCType == Type::LongTy)? xcc : icc;
+
+#ifndef NDEBUG
+    // Let's just make sure values of two different types have not been
+    // coalesced into this LR.
+    for (ValueSet::const_iterator I=ccLR->begin(), E=ccLR->end(); I != E; ++I)
+      assert(setCCType->isIntegral() &&
+             ((ccReg == xcc && (*I)->getType() == Type::LongTy) ||
+              (ccReg == icc && (*I)->getType() != Type::LongTy))
+             && "Comparisons needing different intCC regs coalesced in LR!");
+#endif
+
+    Node->setColor(ccReg);                // only one int cc reg is available
+  }
+}
+
 
 //-----------------------------------------------------------------------------
 // Float Register Class - method for coloring a node in the interference graph.
index bc9b445d5d02d652a5b4cfe7055a6849e4ae1997..50cccb662146d1aaeeaadfd71496bf3dcbbd6b57 100644 (file)
@@ -113,29 +113,24 @@ public:
 //-----------------------------------------------------------------------------
 // Int CC Register Class
 // Only one integer cc register is available. However, this register is
-// referred to as %xcc when instructions like subcc are executed but 
-// referred to as %ccr (i.e., %xcc + %icc") when this register is moved
-// into an integer register using RD or WR instrcutions. So, two ids are
-// allocated for two names.
+// referred to as %xcc or %icc when instructions like subcc are executed but 
+// referred to as %ccr (i.e., %xcc . %icc") when this register is moved
+// into an integer register using RD or WR instrcutions. So, three ids are
+// allocated for the three names.
 //-----------------------------------------------------------------------------
 
 struct SparcIntCCRegClass : public TargetRegClassInfo {
   SparcIntCCRegClass(unsigned ID) 
-    : TargetRegClassInfo(ID, 1, 2) {  }
-  
-  void colorIGNode(IGNode *Node, std::vector<bool> &IsColorUsedArr) const {
-    if (IsColorUsedArr[0])
-      Node->getParentLR()->markForSpill();
-    else
-      Node->setColor(0);    // only one int cc reg is available
-  }
+    : TargetRegClassInfo(ID, 1, 3) {  }
   
+  void colorIGNode(IGNode *Node, std::vector<bool> &IsColorUsedArr) const;
+
   // according to  Sparc 64 ABI,  %ccr is volatile
   //
   inline bool isRegVolatile(int Reg) const { return true; }
 
   enum {
-    xcc, ccr   // only one is available - see the note above
+    xcc, icc, ccr   // only one is available - see the note above
   };
 
   const char * const getRegName(unsigned reg) const;
index 95bd87f9505012fbff2f23728cd5987a8f5f043d..962b9f68d1c6156562ca2e931919d5d0086b894a 100644 (file)
@@ -98,11 +98,11 @@ const char * const SparcFloatRegClass::getRegName(unsigned reg) const {
 
 
 static const char * const IntCCRegNames[] = {    
-  "xcc",  "ccr"
+  "xcc",  "icc",  "ccr"
 };
 
 const char * const SparcIntCCRegClass::getRegName(unsigned reg) const {
-  assert(reg < 2);
+  assert(reg < 3);
   return IntCCRegNames[reg];
 }
 
@@ -1088,15 +1088,14 @@ UltraSparcRegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
   case IntCCRegType:
     if (getRegType(DestReg) == IntRegType) {
       // copy intCC reg to int reg
-      // Use SrcReg+1 to get the name "%ccr" instead of "%xcc" for RDCCR
-      MI = BuildMI(V9::RDCCR, 2).addMReg(SrcReg+1).addMReg(DestReg,MOTy::Def);
+      MI = (BuildMI(V9::RDCCR, 2).addMReg(SparcIntCCRegClass::ccr).
+            addMReg(DestReg,MOTy::Def));
     } else {
       // copy int reg to intCC reg
-      // Use DestReg+1 to get the name "%ccr" instead of "%xcc" for WRCCR
       assert(getRegType(SrcReg) == IntRegType
              && "Can only copy CC reg to/from integer reg");
-      MI = BuildMI(V9::WRCCRr, 3).addMReg(SrcReg)
-        .addMReg(SparcIntRegClass::g0).addMReg(DestReg+1, MOTy::Def);
+      MI = (BuildMI(V9::WRCCRr, 3).addMReg(SrcReg).addMReg(SparcIntRegClass::g0)
+            .addMReg(SparcIntCCRegClass::ccr, MOTy::Def));
     }
     break;
     
@@ -1161,9 +1160,8 @@ UltraSparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
   case IntCCRegType:
     assert(scratchReg >= 0 && "Need scratch reg to store %ccr to memory");
     assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
-    
-    // Use SrcReg+1 to get the name "%ccr" instead of "%xcc" for RDCCR
-    MI = BuildMI(V9::RDCCR, 2).addMReg(SrcReg+1).addMReg(scratchReg, MOTy::Def);
+    MI = (BuildMI(V9::RDCCR, 2).addMReg(SparcIntCCRegClass::ccr)
+          .addMReg(scratchReg, MOTy::Def));
     mvec.push_back(MI);
     
     cpReg2MemMI(mvec, scratchReg, DestPtrReg, Offset, IntRegType);
@@ -1221,10 +1219,8 @@ UltraSparcRegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
     assert(scratchReg >= 0 && "Need scratch reg to load %ccr from memory");
     assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
     cpMem2RegMI(mvec, SrcPtrReg, Offset, scratchReg, IntRegType);
-    
-    // Use DestReg+1 to get the name "%ccr" instead of "%xcc" for WRCCR
     MI = BuildMI(V9::WRCCRr, 3).addMReg(scratchReg)
-      .addMReg(SparcIntRegClass::g0).addMReg(DestReg+1,MOTy::Def);
+      .addMReg(SparcIntRegClass::g0).addMReg(SparcIntCCRegClass::ccr,MOTy::Def);
     break;
     
   case FloatCCRegType: {