mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-16 16:37:42 +00:00
Fix illegal relocations in X86FastISel
On x86_86 the lea instruction can only use a 32 bit immediate value. When the code is compiled statically the RIP register is not used, meaning the immediate is all that can be used for the relocation, which is not sufficient in the case of targets more than +/- 2GB away. This patch bails out of fast isel in those cases and reverts to DAG which does the right thing. Test case included. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211040 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dc2dc390f6
commit
a564159d85
@ -2709,6 +2709,10 @@ unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
|
||||
|
||||
// Materialize addresses with LEA instructions.
|
||||
if (isa<GlobalValue>(C)) {
|
||||
//LEA can only handle 32 bit immediates
|
||||
if (TM.getRelocationModel() == Reloc::Static && Subtarget->is64Bit())
|
||||
return false;
|
||||
|
||||
X86AddressMode AM;
|
||||
if (X86SelectAddress(C, AM)) {
|
||||
// If the expression is just a basereg, then we're done, otherwise we need
|
||||
|
24
test/CodeGen/X86/x86-64-static-relo-movl.ll
Normal file
24
test/CodeGen/X86/x86-64-static-relo-movl.ll
Normal file
@ -0,0 +1,24 @@
|
||||
; RUN: llc -mtriple=x86_64-pc-win32-macho -relocation-model=static -O0 < %s | FileCheck %s
|
||||
|
||||
; Ensure that we don't generate a movl and not a lea for a static relocation
|
||||
; when compiling for 64 bit.
|
||||
|
||||
%struct.MatchInfo = type [64 x i64]
|
||||
|
||||
@NO_MATCH = internal constant %struct.MatchInfo zeroinitializer, align 8
|
||||
|
||||
define void @setup() {
|
||||
%pending = alloca %struct.MatchInfo, align 8
|
||||
%t = bitcast %struct.MatchInfo* %pending to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %t, i8* bitcast (%struct.MatchInfo* @NO_MATCH to i8*), i64 512, i32 8, i1 false)
|
||||
%u = getelementptr inbounds %struct.MatchInfo* %pending, i32 0, i32 2
|
||||
%v = load i64* %u, align 8
|
||||
br label %done
|
||||
done:
|
||||
ret void
|
||||
|
||||
; CHECK: movl $_NO_MATCH, {{.*}}
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1)
|
@ -10,10 +10,10 @@
|
||||
; with "clang++ -S -emit-llvm -fsanitize=address -O0 -g test.cc"
|
||||
|
||||
; First, argument variable "y" resides in %rdi:
|
||||
; CHECK: DEBUG_VALUE: bar:y <- RDI
|
||||
; CHECK: DEBUG_VALUE: bar:y <- RDX
|
||||
|
||||
; Then its address is stored in a location on a stack:
|
||||
; CHECK: movq %rdi, [[OFFSET:[0-9]+]](%rsp)
|
||||
; CHECK: movq %rdx, [[OFFSET:[0-9]+]](%rsp)
|
||||
; CHECK-NEXT: [[START_LABEL:.Ltmp[0-9]+]]
|
||||
; CHECK-NEXT: DEBUG_VALUE: bar:y <- [RSP+[[OFFSET]]]
|
||||
; This location should be valid until the end of the function.
|
||||
@ -26,7 +26,7 @@
|
||||
; CHECK-NEXT: .quad .Lset{{[0-9]+}}
|
||||
; CHECK-NEXT: .Lset{{[0-9]+}} = [[START_LABEL]]-.Lfunc_begin0
|
||||
; CHECK-NEXT: .quad .Lset{{[0-9]+}}
|
||||
; CHECK: DW_OP_reg5
|
||||
; CHECK: DW_OP_reg1
|
||||
|
||||
; Then it's addressed via %rsp:
|
||||
; CHECK: .Lset{{[0-9]+}} = [[START_LABEL]]-.Lfunc_begin0
|
||||
|
Loading…
Reference in New Issue
Block a user