diff options
-rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.td | 11 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/musttail-varargs.ll | 10 |
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 |