summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/X86FastISel.cpp22
-rw-r--r--test/CodeGen/X86/x86-64-static-relo-movl.ll2
-rw-r--r--test/DebugInfo/X86/debug-loc-asan.ll8
3 files changed, 17 insertions, 15 deletions
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 37174a14b2..9557d96d53 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -2813,15 +2813,8 @@ unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
return 0;
}
- // Materialize addresses with LEA instructions.
+ // Materialize addresses with LEA/MOV instructions.
if (isa<GlobalValue>(C)) {
- // LEA can only handle 32 bit immediates. Currently this happens pretty
- // rarely, so rather than deal with it just bail out of fast isel. If any
- // architectures endis up needing to use this path a lot then fast isel
- // could get the address with a MOV64ri and use that to load the value.
- 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
@@ -2830,10 +2823,19 @@ unsigned X86FastISel::TargetMaterializeConstant(const Constant *C) {
AM.IndexReg == 0 && AM.Disp == 0 && AM.GV == nullptr)
return AM.Base.Reg;
- Opc = TLI.getPointerTy() == MVT::i32 ? X86::LEA32r : X86::LEA64r;
unsigned ResultReg = createResultReg(RC);
- addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+ if (TM.getRelocationModel() == Reloc::Static &&
+ TLI.getPointerTy() == MVT::i64) {
+ // The displacement code be more than 32 bits away so we need to use
+ // an instruction with a 64 bit immediate
+ Opc = X86::MOV64ri;
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+ TII.get(Opc), ResultReg).addGlobalAddress(cast<GlobalValue>(C));
+ } else {
+ Opc = TLI.getPointerTy() == MVT::i32 ? X86::LEA32r : X86::LEA64r;
+ addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(Opc), ResultReg), AM);
+ }
return ResultReg;
}
return 0;
diff --git a/test/CodeGen/X86/x86-64-static-relo-movl.ll b/test/CodeGen/X86/x86-64-static-relo-movl.ll
index b184df4619..71e52bb991 100644
--- a/test/CodeGen/X86/x86-64-static-relo-movl.ll
+++ b/test/CodeGen/X86/x86-64-static-relo-movl.ll
@@ -17,7 +17,7 @@ define void @setup() {
done:
ret void
- ; CHECK: movl $_NO_MATCH, {{.*}}
+ ; CHECK: movabsq $_NO_MATCH, {{.*}}
}
; Function Attrs: nounwind
diff --git a/test/DebugInfo/X86/debug-loc-asan.ll b/test/DebugInfo/X86/debug-loc-asan.ll
index 0e02c67871..746b1dcaa3 100644
--- a/test/DebugInfo/X86/debug-loc-asan.ll
+++ b/test/DebugInfo/X86/debug-loc-asan.ll
@@ -9,11 +9,11 @@
; }
; with "clang++ -S -emit-llvm -fsanitize=address -O0 -g test.cc"
-; First, argument variable "y" resides in %rdx:
-; CHECK: DEBUG_VALUE: bar:y <- RDX
+; First, argument variable "y" resides in %rdi:
+; CHECK: DEBUG_VALUE: bar:y <- RDI
; Then its address is stored in a location on a stack:
-; CHECK: movq %rdx, [[OFFSET:[0-9]+]](%rsp)
+; CHECK: movq %rdi, [[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_reg1
+; CHECK: DW_OP_reg5
; Then it's addressed via %rsp:
; CHECK: .Lset{{[0-9]+}} = [[START_LABEL]]-.Lfunc_begin0