[llvm-commits] [llvm] r55358 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll

Chris Lattner sabre at nondot.org
Mon Aug 25 23:19:02 PDT 2008


Author: lattner
Date: Tue Aug 26 01:19:02 2008
New Revision: 55358

URL: http://llvm.org/viewvc/llvm-project?rev=55358&view=rev
Log:
If an xmm register is referenced explicitly in an inline asm, make sure to 
assign it to a version of the xmm register with the regclass that matches its
type.  This fixes PR2715, a bug handling some crazy xpcom case in mozilla.

Added:
    llvm/trunk/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll
Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=55358&r1=55357&r2=55358&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Aug 26 01:19:02 2008
@@ -7221,56 +7221,68 @@
   // 16-bit register pieces "ax","dx","cx","bx","si","di","bp","sp".  If we
   // really want an 8-bit or 32-bit register, map to the appropriate register
   // class and return the appropriate register.
-  if (Res.second != X86::GR16RegisterClass)
-    return Res;
-
-  if (VT == MVT::i8) {
-    unsigned DestReg = 0;
-    switch (Res.first) {
-    default: break;
-    case X86::AX: DestReg = X86::AL; break;
-    case X86::DX: DestReg = X86::DL; break;
-    case X86::CX: DestReg = X86::CL; break;
-    case X86::BX: DestReg = X86::BL; break;
-    }
-    if (DestReg) {
-      Res.first = DestReg;
-      Res.second = Res.second = X86::GR8RegisterClass;
-    }
-  } else if (VT == MVT::i32) {
-    unsigned DestReg = 0;
-    switch (Res.first) {
-    default: break;
-    case X86::AX: DestReg = X86::EAX; break;
-    case X86::DX: DestReg = X86::EDX; break;
-    case X86::CX: DestReg = X86::ECX; break;
-    case X86::BX: DestReg = X86::EBX; break;
-    case X86::SI: DestReg = X86::ESI; break;
-    case X86::DI: DestReg = X86::EDI; break;
-    case X86::BP: DestReg = X86::EBP; break;
-    case X86::SP: DestReg = X86::ESP; break;
-    }
-    if (DestReg) {
-      Res.first = DestReg;
-      Res.second = Res.second = X86::GR32RegisterClass;
-    }
-  } else if (VT == MVT::i64) {
-    unsigned DestReg = 0;
-    switch (Res.first) {
-    default: break;
-    case X86::AX: DestReg = X86::RAX; break;
-    case X86::DX: DestReg = X86::RDX; break;
-    case X86::CX: DestReg = X86::RCX; break;
-    case X86::BX: DestReg = X86::RBX; break;
-    case X86::SI: DestReg = X86::RSI; break;
-    case X86::DI: DestReg = X86::RDI; break;
-    case X86::BP: DestReg = X86::RBP; break;
-    case X86::SP: DestReg = X86::RSP; break;
-    }
-    if (DestReg) {
-      Res.first = DestReg;
-      Res.second = Res.second = X86::GR64RegisterClass;
-    }
+  if (Res.second == X86::GR16RegisterClass) {
+    if (VT == MVT::i8) {
+      unsigned DestReg = 0;
+      switch (Res.first) {
+      default: break;
+      case X86::AX: DestReg = X86::AL; break;
+      case X86::DX: DestReg = X86::DL; break;
+      case X86::CX: DestReg = X86::CL; break;
+      case X86::BX: DestReg = X86::BL; break;
+      }
+      if (DestReg) {
+        Res.first = DestReg;
+        Res.second = Res.second = X86::GR8RegisterClass;
+      }
+    } else if (VT == MVT::i32) {
+      unsigned DestReg = 0;
+      switch (Res.first) {
+      default: break;
+      case X86::AX: DestReg = X86::EAX; break;
+      case X86::DX: DestReg = X86::EDX; break;
+      case X86::CX: DestReg = X86::ECX; break;
+      case X86::BX: DestReg = X86::EBX; break;
+      case X86::SI: DestReg = X86::ESI; break;
+      case X86::DI: DestReg = X86::EDI; break;
+      case X86::BP: DestReg = X86::EBP; break;
+      case X86::SP: DestReg = X86::ESP; break;
+      }
+      if (DestReg) {
+        Res.first = DestReg;
+        Res.second = Res.second = X86::GR32RegisterClass;
+      }
+    } else if (VT == MVT::i64) {
+      unsigned DestReg = 0;
+      switch (Res.first) {
+      default: break;
+      case X86::AX: DestReg = X86::RAX; break;
+      case X86::DX: DestReg = X86::RDX; break;
+      case X86::CX: DestReg = X86::RCX; break;
+      case X86::BX: DestReg = X86::RBX; break;
+      case X86::SI: DestReg = X86::RSI; break;
+      case X86::DI: DestReg = X86::RDI; break;
+      case X86::BP: DestReg = X86::RBP; break;
+      case X86::SP: DestReg = X86::RSP; break;
+      }
+      if (DestReg) {
+        Res.first = DestReg;
+        Res.second = Res.second = X86::GR64RegisterClass;
+      }
+    }
+  } else if (Res.second == X86::FR32RegisterClass ||
+             Res.second == X86::FR64RegisterClass ||
+             Res.second == X86::VR128RegisterClass) {
+    // Handle references to XMM physical registers that got mapped into the
+    // wrong class.  This can happen with constraints like {xmm0} where the
+    // target independent register mapper will just pick the first match it can
+    // find, ignoring the required type.
+    if (VT == MVT::f32)
+      Res.second = X86::FR32RegisterClass;
+    else if (VT == MVT::f64)
+      Res.second = X86::FR64RegisterClass;
+    else if (X86::VR128RegisterClass->hasType(VT))
+      Res.second = X86::VR128RegisterClass;
   }
 
   return Res;

Added: llvm/trunk/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll?rev=55358&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll Tue Aug 26 01:19:02 2008
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | llc -mcpu=yonah
+; PR2715
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+	%struct.XPTTypeDescriptorPrefix = type { i8 }
+	%struct.nsISupports = type { i32 (...)** }
+	%struct.nsXPTCMiniVariant = type { %"struct.nsXPTCMiniVariant::._39" }
+	%"struct.nsXPTCMiniVariant::._39" = type { i64 }
+	%struct.nsXPTCVariant = type { %struct.nsXPTCMiniVariant, i8*, %struct.nsXPTType, i8 }
+	%struct.nsXPTType = type { %struct.XPTTypeDescriptorPrefix }
+
+define i32 @XPTC_InvokeByIndex(%struct.nsISupports* %that, i32 %methodIndex, i32 %paramCount, %struct.nsXPTCVariant* %params) nounwind {
+entry:
+	call void asm sideeffect "", "{xmm0},{xmm1},{xmm2},{xmm3},{xmm4},{xmm5},{xmm6},{xmm7},~{dirflag},~{fpsr},~{flags}"( double undef, double undef, double undef, double 1.0, double undef, double 0.0, double undef, double 0.0 ) nounwind
+	ret i32 0
+}





More information about the llvm-commits mailing list