diff options
author | Reid Kleckner <rnk@google.com> | 2018-10-24 22:57:28 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2018-10-24 22:57:28 +0000 |
commit | 49a24278bafa149e1f4327fdeb272c398fd86bd3 (patch) | |
tree | f30dd9084ef1254b6dd7ef887f4501763b5f6866 | |
parent | 30f1d69115e45229c9c9ccb4752a1e9a339a71e3 (diff) | |
download | bcm5719-llvm-49a24278bafa149e1f4327fdeb272c398fd86bd3.tar.gz bcm5719-llvm-49a24278bafa149e1f4327fdeb272c398fd86bd3.zip |
[ELF] Fix large code model MIR verifier errors
Instead of using the MOVGOT64r pseudo, use the existing
MO_PIC_BASE_OFFSET support on symbol operands. Now I don't have to
create a "scratch register operand" for the pseudo to use, and the
register allocator can make better decisions.
Fixes some X86 verifier errors tracked in PR27481.
llvm-svn: 345219
-rw-r--r-- | llvm/lib/Target/X86/X86InstrCompiler.td | 5 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.cpp | 28 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86MCInstLower.cpp | 35 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/code-model-elf-memset.ll | 12 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/code-model-elf.ll | 84 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/large-pic-string.ll | 16 |
6 files changed, 78 insertions, 102 deletions
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index 11d6edd55d4..2805517b747 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -37,11 +37,6 @@ let hasSideEffects = 0, isNotDuplicable = 1, Uses = [ESP, SSP], def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins i32imm:$label), "", []>; -// 64-bit large code model PIC base construction. -let hasSideEffects = 0, mayLoad = 1, isNotDuplicable = 1, SchedRW = [WriteJump] in - def MOVGOT64r : PseudoI<(outs GR64:$reg), - (ins GR64:$scratch, i64i32imm_pcrel:$got), []>; - // ADJCALLSTACKDOWN/UP implicitly use/def ESP because they may be expanded into // a stack adjustment and the codegen must know that they may modify the stack // pointer before prolog-epilog rewriting occurs. diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index e62c8403693..db0cb63ae69 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -7488,12 +7488,28 @@ namespace { .addExternalSymbol("_GLOBAL_OFFSET_TABLE_") .addReg(0); } else if (TM->getCodeModel() == CodeModel::Large) { - // Loading the GOT in the large code model requires math with labels, - // so we use a pseudo instruction and expand it during MC emission. - unsigned Scratch = RegInfo.createVirtualRegister(&X86::GR64RegClass); - BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOVGOT64r), PC) - .addReg(Scratch, RegState::Undef | RegState::Define) - .addExternalSymbol("_GLOBAL_OFFSET_TABLE_"); + // In the large code model, we are aiming for this code, though the + // register allocation may vary: + // leaq .LN$pb(%rip), %rax + // movq $_GLOBAL_OFFSET_TABLE_ - .LN$pb, %rcx + // addq %rcx, %rax + // RAX now holds address of _GLOBAL_OFFSET_TABLE_. + unsigned PBReg = RegInfo.createVirtualRegister(&X86::GR64RegClass); + unsigned GOTReg = + RegInfo.createVirtualRegister(&X86::GR64RegClass); + BuildMI(FirstMBB, MBBI, DL, TII->get(X86::LEA64r), PBReg) + .addReg(X86::RIP) + .addImm(0) + .addReg(0) + .addSym(MF.getPICBaseSymbol()) + .addReg(0); + std::prev(MBBI)->setPreInstrSymbol(MF, MF.getPICBaseSymbol()); + BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOV64ri), GOTReg) + .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", + X86II::MO_PIC_BASE_OFFSET); + BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD64rr), PC) + .addReg(PBReg, RegState::Kill) + .addReg(GOTReg, RegState::Kill); } else { llvm_unreachable("unexpected code model"); } diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 74fe85851cb..86495f16c3a 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -1709,41 +1709,6 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { return; } - case X86::MOVGOT64r: { - // Materializes the GOT for the 64-bit large code model. - MCSymbol *DotSym = OutContext.createTempSymbol(); - OutStreamer->EmitLabel(DotSym); - - unsigned DstReg = MI->getOperand(0).getReg(); - unsigned ScratchReg = MI->getOperand(1).getReg(); - MCSymbol *GOTSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2)); - - // .LtmpN: leaq .LtmpN(%rip), %dst - const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext); - EmitAndCountInstruction(MCInstBuilder(X86::LEA64r) - .addReg(DstReg) // dest - .addReg(X86::RIP) // base - .addImm(1) // scale - .addReg(0) // index - .addExpr(DotExpr) // disp - .addReg(0)); // seg - - // movq $_GLOBAL_OFFSET_TABLE_ - .LtmpN, %scratch - const MCExpr *GOTSymExpr = MCSymbolRefExpr::create(GOTSym, OutContext); - const MCExpr *GOTDiffExpr = - MCBinaryExpr::createSub(GOTSymExpr, DotExpr, OutContext); - EmitAndCountInstruction(MCInstBuilder(X86::MOV64ri) - .addReg(ScratchReg) // dest - .addExpr(GOTDiffExpr)); // disp - - // addq %scratch, %dst - EmitAndCountInstruction(MCInstBuilder(X86::ADD64rr) - .addReg(DstReg) // dest - .addReg(DstReg) // dest - .addReg(ScratchReg)); // src - return; - } - case X86::ADD32ri: { // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri. if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS) diff --git a/llvm/test/CodeGen/X86/code-model-elf-memset.ll b/llvm/test/CodeGen/X86/code-model-elf-memset.ll index ba34aaeddcb..2f429f32eab 100644 --- a/llvm/test/CodeGen/X86/code-model-elf-memset.ll +++ b/llvm/test/CodeGen/X86/code-model-elf-memset.ll @@ -56,16 +56,16 @@ define i32 @main() #0 { ; LARGE-PIC: # %bb.0: # %entry ; LARGE-PIC-NEXT: subq $424, %rsp # imm = 0x1A8 ; LARGE-PIC-NEXT: .cfi_def_cfa_offset 432 -; LARGE-PIC-NEXT: .Ltmp0: -; LARGE-PIC-NEXT: leaq {{.*}}(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp0, %rcx -; LARGE-PIC-NEXT: addq %rcx, %rax +; LARGE-PIC-NEXT: .L0$pb: +; LARGE-PIC-NEXT: leaq .L0$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L0$pb, %rcx +; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movl $0, {{[0-9]+}}(%rsp) ; LARGE-PIC-NEXT: leaq {{[0-9]+}}(%rsp), %rdi -; LARGE-PIC-NEXT: movabsq $memset@GOT, %rcx +; LARGE-PIC-NEXT: movabsq $memset@GOT, %rax ; LARGE-PIC-NEXT: xorl %esi, %esi ; LARGE-PIC-NEXT: movl $400, %edx # imm = 0x190 -; LARGE-PIC-NEXT: callq *(%rax,%rcx) +; LARGE-PIC-NEXT: callq *(%rcx,%rax) ; LARGE-PIC-NEXT: xorl %eax, %eax ; LARGE-PIC-NEXT: addq $424, %rsp # imm = 0x1A8 ; LARGE-PIC-NEXT: .cfi_def_cfa_offset 8 diff --git a/llvm/test/CodeGen/X86/code-model-elf.ll b/llvm/test/CodeGen/X86/code-model-elf.ll index 6d62f256179..56d3f4c102f 100644 --- a/llvm/test/CodeGen/X86/code-model-elf.ll +++ b/llvm/test/CodeGen/X86/code-model-elf.ll @@ -2,12 +2,12 @@ ; Run with --no_x86_scrub_rip because we care a lot about how globals are ; accessed in the code model. -; RUN: llc < %s -relocation-model=static -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-STATIC -; RUN: llc < %s -relocation-model=static -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-STATIC -; RUN: llc < %s -relocation-model=static -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-STATIC -; RUN: llc < %s -relocation-model=pic -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-PIC -; RUN: llc < %s -relocation-model=pic -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-PIC -; RUN: llc < %s -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-PIC +; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-STATIC +; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-STATIC +; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-STATIC +; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-PIC +; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-PIC +; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-PIC ; Generated from this C source: ; @@ -68,9 +68,9 @@ define dso_local i32* @lea_static_data() #0 { ; ; LARGE-PIC-LABEL: lea_static_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .Ltmp0: -; LARGE-PIC-NEXT: leaq .Ltmp0(%rip), %rcx -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp0, %rax +; LARGE-PIC-NEXT: .L0$pb: +; LARGE-PIC-NEXT: leaq .L0$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L0$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $static_data@GOTOFF, %rax ; LARGE-PIC-NEXT: addq %rcx, %rax @@ -108,9 +108,9 @@ define dso_local i32* @lea_global_data() #0 { ; ; LARGE-PIC-LABEL: lea_global_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .Ltmp1: -; LARGE-PIC-NEXT: leaq .Ltmp1(%rip), %rcx -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp1, %rax +; LARGE-PIC-NEXT: .L1$pb: +; LARGE-PIC-NEXT: leaq .L1$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax ; LARGE-PIC-NEXT: addq %rcx, %rax @@ -146,12 +146,12 @@ define dso_local i32* @lea_extern_data() #0 { ; ; LARGE-PIC-LABEL: lea_extern_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .Ltmp2: -; LARGE-PIC-NEXT: leaq .Ltmp2(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp2, %rcx -; LARGE-PIC-NEXT: addq %rcx, %rax -; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rcx -; LARGE-PIC-NEXT: movq (%rax,%rcx), %rax +; LARGE-PIC-NEXT: .L2$pb: +; LARGE-PIC-NEXT: leaq .L2$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx +; LARGE-PIC-NEXT: addq %rax, %rcx +; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax +; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax ; LARGE-PIC-NEXT: retq ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @extern_data, i64 0, i64 0) } @@ -188,12 +188,12 @@ define dso_local i32 @load_global_data() #0 { ; ; LARGE-PIC-LABEL: load_global_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .Ltmp3: -; LARGE-PIC-NEXT: leaq .Ltmp3(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp3, %rcx -; LARGE-PIC-NEXT: addq %rcx, %rax -; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rcx -; LARGE-PIC-NEXT: movl 8(%rax,%rcx), %eax +; LARGE-PIC-NEXT: .L3$pb: +; LARGE-PIC-NEXT: leaq .L3$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx +; LARGE-PIC-NEXT: addq %rax, %rcx +; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax +; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax ; LARGE-PIC-NEXT: retq %rv = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @global_data, i64 0, i64 2) ret i32 %rv @@ -231,12 +231,12 @@ define dso_local i32 @load_extern_data() #0 { ; ; LARGE-PIC-LABEL: load_extern_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .Ltmp4: -; LARGE-PIC-NEXT: leaq .Ltmp4(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp4, %rcx -; LARGE-PIC-NEXT: addq %rcx, %rax -; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rcx -; LARGE-PIC-NEXT: movq (%rax,%rcx), %rax +; LARGE-PIC-NEXT: .L4$pb: +; LARGE-PIC-NEXT: leaq .L4$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx +; LARGE-PIC-NEXT: addq %rax, %rcx +; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax +; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax ; LARGE-PIC-NEXT: movl 8(%rax), %eax ; LARGE-PIC-NEXT: retq %rv = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @extern_data, i64 0, i64 2) @@ -287,9 +287,9 @@ define dso_local void ()* @lea_static_fn() #0 { ; ; LARGE-PIC-LABEL: lea_static_fn: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .Ltmp5: -; LARGE-PIC-NEXT: leaq .Ltmp5(%rip), %rcx -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp5, %rax +; LARGE-PIC-NEXT: .L7$pb: +; LARGE-PIC-NEXT: leaq .L7$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L7$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $static_fn@GOTOFF, %rax ; LARGE-PIC-NEXT: addq %rcx, %rax @@ -325,9 +325,9 @@ define dso_local void ()* @lea_global_fn() #0 { ; ; LARGE-PIC-LABEL: lea_global_fn: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .Ltmp6: -; LARGE-PIC-NEXT: leaq .Ltmp6(%rip), %rcx -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp6, %rax +; LARGE-PIC-NEXT: .L8$pb: +; LARGE-PIC-NEXT: leaq .L8$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L8$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $global_fn@GOTOFF, %rax ; LARGE-PIC-NEXT: addq %rcx, %rax @@ -363,12 +363,12 @@ define dso_local void ()* @lea_extern_fn() #0 { ; ; LARGE-PIC-LABEL: lea_extern_fn: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .Ltmp7: -; LARGE-PIC-NEXT: leaq .Ltmp7(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp7, %rcx -; LARGE-PIC-NEXT: addq %rcx, %rax -; LARGE-PIC-NEXT: movabsq $extern_fn@GOT, %rcx -; LARGE-PIC-NEXT: movq (%rax,%rcx), %rax +; LARGE-PIC-NEXT: .L9$pb: +; LARGE-PIC-NEXT: leaq .L9$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L9$pb, %rcx +; LARGE-PIC-NEXT: addq %rax, %rcx +; LARGE-PIC-NEXT: movabsq $extern_fn@GOT, %rax +; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax ; LARGE-PIC-NEXT: retq ret void ()* @extern_fn } diff --git a/llvm/test/CodeGen/X86/large-pic-string.ll b/llvm/test/CodeGen/X86/large-pic-string.ll index be8a629c31c..e677ed85c66 100644 --- a/llvm/test/CodeGen/X86/large-pic-string.ll +++ b/llvm/test/CodeGen/X86/large-pic-string.ll @@ -1,19 +1,19 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc < %s -code-model=large -relocation-model=pic -mtriple=x86_64--linux | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -code-model=large -relocation-model=pic -mtriple=x86_64--linux | FileCheck %s @.str = private unnamed_addr constant [2 x i8] c"a\00", align 1 define void @pr38385() { ; CHECK-LABEL: pr38385: ; CHECK: # %bb.0: -; CHECK-NEXT: .Ltmp0: -; CHECK-NEXT: leaq {{.*}}(%rip), %rax -; CHECK-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.Ltmp0, %rcx -; CHECK-NEXT: addq %rcx, %rax -; CHECK-NEXT: movabsq $.L.str@GOTOFF, %rcx -; CHECK-NEXT: addl %ecx, %eax -; CHECK-NEXT: movb %al, -{{[0-9]+}}(%rsp) +; CHECK-NEXT: .L0$pb: +; CHECK-NEXT: leaq .L0${{.*}}(%rip), %rax +; CHECK-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L0$pb, %rcx +; CHECK-NEXT: addq %rax, %rcx +; CHECK-NEXT: movabsq $.L.str@GOTOFF, %rax +; CHECK-NEXT: addl %eax, %ecx +; CHECK-NEXT: movb %cl, -{{[0-9]+}}(%rsp) ; CHECK-NEXT: retq %p = alloca i8, align 1 store i8 ptrtoint ([2 x i8]* @.str to i8), i8* %p, align 1 |