diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -779,14 +779,14 @@ if (TLI.getPointerTy(DL) == MVT::i64) { Opc = X86::MOV64rm; RC = &X86::GR64RegClass; - - if (Subtarget->isPICStyleRIPRel()) - StubAM.Base.Reg = X86::RIP; } else { Opc = X86::MOV32rm; RC = &X86::GR32RegClass; } + if (Subtarget->isPICStyleRIPRel()) + StubAM.Base.Reg = X86::RIP; + LoadReg = createResultReg(RC); MachineInstrBuilder LoadMI = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), LoadReg); diff --git a/llvm/test/CodeGen/X86/pic.ll b/llvm/test/CodeGen/X86/pic.ll --- a/llvm/test/CodeGen/X86/pic.ll +++ b/llvm/test/CodeGen/X86/pic.ll @@ -1,4 +1,6 @@ -; RUN: llc < %s -mcpu=generic -mtriple=i686-pc-linux-gnu -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false | FileCheck %s -check-prefix=LINUX +; RUN: llc < %s -mcpu=generic -mtriple=i686-pc-linux-gnu -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false | FileCheck %s -check-prefixes=CHECK,CHECK-I686 +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-pc-linux-gnux32 -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false | FileCheck %s -check-prefixes=CHECK,CHECK-X32 +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-pc-linux-gnux32 -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false -fast-isel | FileCheck %s -check-prefixes=CHECK,CHECK-X32 @ptr = external global i32* @dst = external global i32 @@ -11,15 +13,19 @@ store i32 %tmp.s, i32* @dst ret void -; LINUX-LABEL: test0: -; LINUX: calll .L0$pb -; LINUX-NEXT: .L0$pb: -; LINUX-NEXT: popl -; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L0$pb), -; LINUX: movl dst@GOT(%eax), -; LINUX: movl ptr@GOT(%eax), -; LINUX: movl src@GOT(%eax), -; LINUX: ret +; CHECK-LABEL: test0: +; CHECK-I686: calll .L0$pb +; CHECK-I686-NEXT: .L0$pb: +; CHECK-I686-NEXT: popl +; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L0$pb), +; CHECK-I686: movl dst@GOT(%eax), +; CHECK-I686: movl ptr@GOT(%eax), +; CHECK-I686: movl src@GOT(%eax), +; CHECK-I686: ret +; CHECK-DAG-X32: movl dst@GOTPCREL(%rip), +; CHECK-DAG-X32: movl ptr@GOTPCREL(%rip), +; CHECK-DAG-X32: movl src@GOTPCREL(%rip), +; CHECK-X32: retq } @ptr2 = global i32* null @@ -33,15 +39,19 @@ store i32 %tmp.s, i32* @dst2 ret void -; LINUX-LABEL: test1: -; LINUX: calll .L1$pb -; LINUX-NEXT: .L1$pb: -; LINUX-NEXT: popl -; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L1$pb), %eax -; LINUX: movl dst2@GOT(%eax), -; LINUX: movl ptr2@GOT(%eax), -; LINUX: movl src2@GOT(%eax), -; LINUX: ret +; CHECK-LABEL: test1: +; CHECK-I686: calll .L1$pb +; CHECK-I686-NEXT: .L1$pb: +; CHECK-I686-NEXT: popl +; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L1$pb), %eax +; CHECK-I686: movl dst2@GOT(%eax), +; CHECK-I686: movl ptr2@GOT(%eax), +; CHECK-I686: movl src2@GOT(%eax), +; CHECK-I686: ret +; CHECK-DAG-X32: movl dst2@GOTPCREL(%rip), +; CHECK-DAG-X32: movl ptr2@GOTPCREL(%rip), +; CHECK-DAG-X32: movl src2@GOTPCREL(%rip), +; CHECK-X32: retq } @@ -51,18 +61,24 @@ entry: %ptr = call i8* @malloc(i32 40) ret void -; LINUX-LABEL: test2: -; LINUX: pushl %ebx -; LINUX-NEXT: subl $8, %esp -; LINUX-NEXT: calll .L2$pb -; LINUX-NEXT: .L2$pb: -; LINUX-NEXT: popl %ebx -; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L2$pb), %ebx -; LINUX: movl $40, (%esp) -; LINUX: calll malloc@PLT -; LINUX: addl $8, %esp -; LINUX: popl %ebx -; LINUX: ret +; CHECK-LABEL: test2: +; CHECK-I686: pushl %ebx +; CHECK-I686-NEXT: subl $8, %esp +; CHECK-I686-NEXT: calll .L2$pb +; CHECK-I686-NEXT: .L2$pb: +; CHECK-I686-NEXT: popl %ebx +; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L2$pb), %ebx +; CHECK-I686: movl $40, (%esp) +; CHECK-I686: calll malloc@PLT +; CHECK-I686: addl $8, %esp +; CHECK-I686: popl %ebx +; CHECK-I686: ret +; CHECK-X32: pushq %rax +; CHECK-X32: movl $40, %edi +; CHECK-X32: callq malloc@PLT +; CHECK-X32: popq %rax +; CHECK-X32: retq + } @pfoo = external global void(...)* @@ -74,14 +90,17 @@ %tmp1 = load void(...)*, void(...)** @pfoo call void(...) %tmp1() ret void -; LINUX-LABEL: test3: -; LINUX: calll .L3$pb -; LINUX-NEXT: .L3$pb: -; LINUX: popl -; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L3$pb), %[[REG3:e..]] -; LINUX: calll afoo@PLT -; LINUX: movl pfoo@GOT(%[[REG3]]), -; LINUX: calll * +; CHECK-LABEL: test3: +; CHECK-I686: calll .L3$pb +; CHECK-I686-NEXT: .L3$pb: +; CHECK-I686: popl +; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L3$pb), %[[REG3:e..]] +; CHECK-I686: calll afoo@PLT +; CHECK-I686: movl pfoo@GOT(%[[REG3]]), +; CHECK-I686: calll * +; CHECK-X32: callq afoo@PLT +; CHECK-X32: movl pfoo@GOTPCREL(%rip), +; CHECK-X32: callq * } declare void(...)* @afoo(...) @@ -90,11 +109,13 @@ entry: call void(...) @foo() ret void -; LINUX-LABEL: test4: -; LINUX: calll .L4$pb -; LINUX: popl %ebx -; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L4$pb), %ebx -; LINUX: calll foo@PLT +; CHECK-LABEL: test4: +; CHECK-I686: calll .L4$pb +; CHECK-I686: popl %ebx +; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L4$pb), %ebx +; CHECK-I686: calll foo@PLT +; CHECK-X32: callq foo@PLT + } declare void @foo(...) @@ -111,16 +132,21 @@ store i32 %tmp.s, i32* @dst6 ret void -; LINUX-LABEL: test5: -; LINUX: calll .L5$pb -; LINUX-NEXT: .L5$pb: -; LINUX-NEXT: popl %eax -; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L5$pb), %eax -; LINUX: leal dst6@GOTOFF(%eax), %ecx -; LINUX: movl %ecx, ptr6@GOTOFF(%eax) -; LINUX: movl src6@GOTOFF(%eax), %ecx -; LINUX: movl %ecx, dst6@GOTOFF(%eax) -; LINUX: ret +; CHECK-LABEL: test5: +; CHECK-I686: calll .L5$pb +; CHECK-I686-NEXT: .L5$pb: +; CHECK-I686-NEXT: popl %eax +; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L5$pb), %eax +; CHECK-I686: leal dst6@GOTOFF(%eax), %ecx +; CHECK-I686: movl %ecx, ptr6@GOTOFF(%eax) +; CHECK-I686: movl src6@GOTOFF(%eax), %ecx +; CHECK-I686: movl %ecx, dst6@GOTOFF(%eax) +; CHECK-I686: ret +; CHECK-X32: leal dst6(%rip), %eax +; CHECK-X32: movl %eax, ptr6(%rip) +; CHECK-X32: movl src6(%rip), %eax +; CHECK-X32: movl %eax, dst6(%rip) +; CHECK-X32: retq } @@ -131,13 +157,14 @@ %retval = select i1 %tmp, double 4.561230e+02, double 1.234560e+02 ret double %retval -; LINUX: .LCPI6_0: +; CHECK: .LCPI6_0: -; LINUX-LABEL: test6: -; LINUX: calll .L6$pb -; LINUX: .L6$pb: -; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L6$pb), -; LINUX: fldl .LCPI6_0@GOTOFF( +; CHECK-LABEL: test6: +; CHECK-I686: calll .L6$pb +; CHECK-I686: .L6$pb: +; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L6$pb), +; CHECK-I686: fldl .LCPI6_0@GOTOFF( +; CHECK-X32: .LCPI6_0(%rip), } @@ -185,22 +212,38 @@ tail call void(...) @foo6() ret void -; LINUX-LABEL: test7: -; LINUX: calll .L7$pb -; LINUX: .L7$pb: -; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L7$pb), -; LINUX: .LJTI7_0@GOTOFF( -; LINUX: jmpl * - -; LINUX: .p2align 2 -; LINUX-NEXT: .LJTI7_0: -; LINUX: .long .LBB7_2@GOTOFF -; LINUX: .long .LBB7_8@GOTOFF -; LINUX: .long .LBB7_4@GOTOFF -; LINUX: .long .LBB7_6@GOTOFF -; LINUX: .long .LBB7_5@GOTOFF -; LINUX: .long .LBB7_8@GOTOFF -; LINUX: .long .LBB7_7@GOTOFF +; CHECK-LABEL: test7: +; CHECK-I686: calll .L7$pb +; CHECK-I686: .L7$pb: +; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L7$pb), +; CHECK-I686: .LJTI7_0@GOTOFF( +; CHECK-I686: jmpl * +; CHECK-X32: leal .LJTI7_0(%rip), %eax +; CHECK-X32: addl (%eax,%edi,4), %eax +; CHECK-X32: jmpq *%rax + +; CHECK: .p2align 2 +; CHECK-NEXT: .LJTI7_0: +; CHECK-I686: .long .LBB7_2@GOTOFF +; CHECK-I686: .long .LBB7_8@GOTOFF +; CHECK-I686: .long .LBB7_4@GOTOFF +; CHECK-I686: .long .LBB7_6@GOTOFF +; CHECK-I686: .long .LBB7_5@GOTOFF +; CHECK-I686: .long .LBB7_8@GOTOFF +; CHECK-I686: .long .LBB7_7@GOTOFF +; CHECK-X32: .long .LBB7_3-.LJTI7_0 +; CHECK-X32: .long .LBB7_3-.LJTI7_0 +; CHECK-X32: .long .LBB7_12-.LJTI7_0 +; CHECK-X32: .long .LBB7_8-.LJTI7_0 +; CHECK-X32: .long .LBB7_12-.LJTI7_0 +; CHECK-X32: .long .LBB7_10-.LJTI7_0 +; CHECK-X32: .long .LBB7_8-.LJTI7_0 +; CHECK-X32: .long .LBB7_9-.LJTI7_0 +; CHECK-X32: .long .LBB7_10-.LJTI7_0 +; CHECK-X32: .long .LBB7_9-.LJTI7_0 +; CHECK-X32: .long .LBB7_12-.LJTI7_0 +; CHECK-X32: .long .LBB7_14-.LJTI7_0 +; CHECK-X32: .long .LBB7_14-.LJTI7_0 } declare void @foo1(...)