ARM: Handle physreg targets in RegPair hints gracefully
authorMatthias Braun <matze@braunis.de>
Fri, 3 Apr 2015 00:18:38 +0000 (00:18 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 3 Apr 2015 00:18:38 +0000 (00:18 +0000)
Register coalescing can change the target of a RegPair hint to a
physreg, we should not crash on this. This also slightly improved the
way ARMBaseRegisterInfo::updateRegAllocHint() works.

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

lib/Target/ARM/ARMBaseRegisterInfo.cpp
test/CodeGen/ARM/regpair_hint_phys.ll [new file with mode: 0644]

index a8c76573019ecfa791aa4766e8da3729e51e6197..3f79a9b53d704beff2874b6655f7039ee653aeec 100644 (file)
@@ -245,11 +245,15 @@ ARMBaseRegisterInfo::getRegAllocationHints(unsigned VirtReg,
   // This register should preferably be even (Odd == 0) or odd (Odd == 1).
   // Check if the other part of the pair has already been assigned, and provide
   // the paired register as the first hint.
+  unsigned Paired = Hint.second;
+  if (Paired == 0)
+    return;
+
   unsigned PairedPhys = 0;
-  if (VRM && VRM->hasPhys(Hint.second)) {
-    PairedPhys = getPairedGPR(VRM->getPhys(Hint.second), Odd, this);
-    if (PairedPhys && MRI.isReserved(PairedPhys))
-      PairedPhys = 0;
+  if (TargetRegisterInfo::isPhysicalRegister(Paired)) {
+    PairedPhys = Paired;
+  } else if (VRM && VRM->hasPhys(Paired)) {
+    PairedPhys = getPairedGPR(VRM->getPhys(Paired), Odd, this);
   }
 
   // First prefer the paired physreg.
@@ -284,9 +288,14 @@ ARMBaseRegisterInfo::updateRegAllocHint(unsigned Reg, unsigned NewReg,
     // change.
     unsigned OtherReg = Hint.second;
     Hint = MRI->getRegAllocationHint(OtherReg);
-    if (Hint.second == Reg)
-      // Make sure the pair has not already divorced.
+    // Make sure the pair has not already divorced.
+    if (Hint.second == Reg) {
       MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
+      if (TargetRegisterInfo::isVirtualRegister(NewReg))
+        MRI->setRegAllocationHint(NewReg,
+            Hint.first == (unsigned)ARMRI::RegPairOdd ? ARMRI::RegPairEven
+            : ARMRI::RegPairOdd, OtherReg);
+    }
   }
 }
 
diff --git a/test/CodeGen/ARM/regpair_hint_phys.ll b/test/CodeGen/ARM/regpair_hint_phys.ll
new file mode 100644 (file)
index 0000000..8585a4c
--- /dev/null
@@ -0,0 +1,22 @@
+; RUN: llc -o - %s
+; ARM target used to fail an assertion if RegPair{Odd|Even} hint pointed to a
+; physreg.
+target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+target triple = "thumbv7-apple-tvos8.3.0"
+
+declare i8* @llvm.frameaddress(i32) #1
+declare i8* @llvm.returnaddress(i32) #1
+
+@somevar = global [2 x i32] [i32 0, i32 0]
+
+define void @__ubsan_handle_shift_out_of_bounds() #0 {
+entry:
+  %0 = tail call i8* @llvm.frameaddress(i32 0)
+  %1 = ptrtoint i8* %0 to i32
+  %2 = tail call i8* @llvm.returnaddress(i32 0)
+  %3 = ptrtoint i8* %2 to i32
+  %val0 = insertvalue [2 x i32] [i32 undef, i32 undef], i32 %3, 0
+  %val1 = insertvalue [2 x i32] %val0, i32 %1, 1
+  store [2 x i32] %val1, [2 x i32]* @somevar, align 8
+  ret void
+}