summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/X86/X86RegisterInfo.cpp10
-rw-r--r--llvm/lib/Target/X86/X86RegisterInfo.td11
-rw-r--r--llvm/test/CodeGen/X86/musttail-varargs.ll10
3 files changed, 24 insertions, 7 deletions
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 1ea9533eaf9..c1da3db7cec 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -162,18 +162,24 @@ X86RegisterInfo::getPointerRegClass(const MachineFunction &MF,
case 0: // Normal GPRs.
if (Subtarget.isTarget64BitLP64())
return &X86::GR64RegClass;
- return &X86::GR32RegClass;
+ // If the target is 64bit but we have been told to use 32bit addresses,
+ // we can still use RIP-relative addresses.
+ // Reflect that in the returned register class.
+ return Is64Bit ? &X86::X32_ADDR_ACCESSRegClass : &X86::GR32RegClass;
case 1: // Normal GPRs except the stack pointer (for encoding reasons).
if (Subtarget.isTarget64BitLP64())
return &X86::GR64_NOSPRegClass;
+ // NOSP does not contain RIP, so no special case here.
return &X86::GR32_NOSPRegClass;
case 2: // NOREX GPRs.
if (Subtarget.isTarget64BitLP64())
return &X86::GR64_NOREXRegClass;
- return &X86::GR32_NOREXRegClass;
+ return Is64Bit ? &X86::X32_NOREX_ADDR_ACCESSRegClass
+ : &X86::GR32_NOREXRegClass;
case 3: // NOREX GPRs except the stack pointer (for encoding reasons).
if (Subtarget.isTarget64BitLP64())
return &X86::GR64_NOREX_NOSPRegClass;
+ // NOSP does not contain RIP, so no special case here.
return &X86::GR32_NOREX_NOSPRegClass;
case 4: // Available for tailcall (not callee-saved GPRs).
return getGPRsForTailCall(MF);
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.td b/llvm/lib/Target/X86/X86RegisterInfo.td
index dfbca49adae..ef02914ae27 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.td
+++ b/llvm/lib/Target/X86/X86RegisterInfo.td
@@ -415,6 +415,17 @@ def GR32_NOREX_NOSP : RegisterClass<"X86", [i32], 32,
def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64,
(and GR64_NOREX, GR64_NOSP)>;
+// Register classes used for X32 address accesses.
+// In X32 mode it is fine to use RIP as we are sure the 32 high bits
+// are not set.
+// We do not need variants for NOSP as RIP is not allowed there.
+// Alignment is 64 because we have RIP.
+// FIXME: We could allow all 64bit registers, but we would need
+// something to check that the 32 high bits are not set.
+def X32_ADDR_ACCESS : RegisterClass<"X86", [i32], 64, (add GR32, RIP)>;
+def X32_NOREX_ADDR_ACCESS : RegisterClass<"X86", [i32], 64,
+ (add GR32_NOREX, RIP)>;
+
// A class to support the 'A' assembler constraint: EAX then EDX.
def GR32_AD : RegisterClass<"X86", [i32], 32, (add EAX, EDX)>;
diff --git a/llvm/test/CodeGen/X86/musttail-varargs.ll b/llvm/test/CodeGen/X86/musttail-varargs.ll
index db4a6f75d83..b3f73aaf890 100644
--- a/llvm/test/CodeGen/X86/musttail-varargs.ll
+++ b/llvm/test/CodeGen/X86/musttail-varargs.ll
@@ -1,8 +1,8 @@
-; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-linux | FileCheck %s --check-prefix=LINUX
-; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-linux-gnux32 | FileCheck %s --check-prefix=LINUX-X32
-; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-windows | FileCheck %s --check-prefix=WINDOWS
-; RUN: llc < %s -enable-tail-merge=0 -mtriple=i686-windows | FileCheck %s --check-prefix=X86
-; RUN: llc < %s -enable-tail-merge=0 -mtriple=i686-windows -mattr=+sse2 | FileCheck %s --check-prefix=X86
+; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=x86_64-linux | FileCheck %s --check-prefix=LINUX
+; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=x86_64-linux-gnux32 | FileCheck %s --check-prefix=LINUX-X32
+; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=x86_64-windows | FileCheck %s --check-prefix=WINDOWS
+; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=i686-windows | FileCheck %s --check-prefix=X86
+; RUN: llc -verify-machineinstrs < %s -enable-tail-merge=0 -mtriple=i686-windows -mattr=+sse2 | FileCheck %s --check-prefix=X86
; Test that we actually spill and reload all arguments in the variadic argument
; pack. Doing a normal call will clobber all argument registers, and we will
OpenPOWER on IntegriCloud