R600/SI: Fix SIRegisterInfo::getPhysRegSubReg()
authorTom Stellard <thomas.stellard@amd.com>
Wed, 24 Sep 2014 01:33:22 +0000 (01:33 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Wed, 24 Sep 2014 01:33:22 +0000 (01:33 +0000)
Correctly handle special registers: EXEC, EXEC_LO, EXEC_HI, VCC_LO,
VCC_HI, and M0.  The previous implementation would assertion fail
when passed these registers.

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

lib/Target/R600/SIRegisterInfo.cpp

index 47e7024c8daef5daebca5236e93d1f3069696f0b..e443deb7ea95f3cd8a5be5084a64a11b918484e8 100644 (file)
@@ -343,7 +343,6 @@ unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg,
         case 1: return AMDGPU::VCC_HI;
         default: llvm_unreachable("Invalid SubIdx for VCC");
       }
-      break;
 
   case AMDGPU::FLAT_SCR:
     switch (Channel) {
@@ -368,6 +367,16 @@ unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg,
     break;
   }
 
+  const TargetRegisterClass *RC = getPhysRegClass(Reg);
+  // 32-bit registers don't have sub-registers, so we can just return the
+  // Reg.  We need to have this check here, because the calculation below
+  // using getHWRegIndex() will fail with special 32-bit registers like
+  // VCC_LO, VCC_HI, EXEC_LO, EXEC_HI and M0.
+  if (RC->getSize() == 4) {
+    assert(Channel == 0);
+    return Reg;
+  }
+
   unsigned Index = getHWRegIndex(Reg);
   return SubRC->getRegister(Index + Channel);
 }