mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-01 08:23:21 +01:00
bb1db0e66a
x86 addressing modes. This allows PIE-based TLS offsets to fit directly into an addressing mode immediate offset, which is the last remaining code quality issue from PR12380. With this patch, that PR is completely fixed. To understand why this patch is correct to match these offsets into addressing mode immediates, break it down by cases: 1) 32-bit is trivially correct, and unmodified here. 2) 64-bit non-small mode is unchanged and never matches. 3) 64-bit small PIC code which is RIP-relative is handled specially in the match to try to fit RIP into the base register. If it fails, it now early exits. This behavior is unchanged by the patch. 4) 64-bit small non-PIC code which is not RIP-relative continues to work as it did before. The reason these immediates are safe is because the ABI ensures they fit in small mode. This behavior is unchanged. 5) 64-bit small PIC code which is *not* using RIP-relative addressing. This is the only case changed by the patch, and the primary place you see it is in TLS, either the win64 section offset TLS or Linux local-exec TLS model in a PIC compilation. Here the ABI again ensures that the immediates fit because we are in small mode, and any other operations required due to the PIC relocation model have been handled externally to the Wrapper node (extra loads etc are made around the wrapper node in ISelLowering). I've tested this as much as I can comparing it with GCC's output, and everything appears safe. I discussed this with Anton and it made sense to him at least at face value. That said, if there are issues with PIC code after this patch, yell and we can revert it. llvm-svn: 154304
64 lines
1.2 KiB
LLVM
64 lines
1.2 KiB
LLVM
; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu -relocation-model=pic -enable-pie \
|
|
; RUN: | FileCheck -check-prefix=X32 %s
|
|
; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu -relocation-model=pic -enable-pie \
|
|
; RUN: | FileCheck -check-prefix=X64 %s
|
|
|
|
@i = thread_local global i32 15
|
|
@i2 = external thread_local global i32
|
|
|
|
define i32 @f1() {
|
|
; X32: f1:
|
|
; X32: movl %gs:i@NTPOFF, %eax
|
|
; X32-NEXT: ret
|
|
; X64: f1:
|
|
; X64: movl %fs:i@TPOFF, %eax
|
|
; X64-NEXT: ret
|
|
|
|
entry:
|
|
%tmp1 = load i32* @i
|
|
ret i32 %tmp1
|
|
}
|
|
|
|
define i32* @f2() {
|
|
; X32: f2:
|
|
; X32: movl %gs:0, %eax
|
|
; X32-NEXT: leal i@NTPOFF(%eax), %eax
|
|
; X32-NEXT: ret
|
|
; X64: f2:
|
|
; X64: movq %fs:0, %rax
|
|
; X64-NEXT: leaq i@TPOFF(%rax), %rax
|
|
; X64-NEXT: ret
|
|
|
|
entry:
|
|
ret i32* @i
|
|
}
|
|
|
|
define i32 @f3() {
|
|
; X32: f3:
|
|
; X32: movl i2@INDNTPOFF, %eax
|
|
; X32-NEXT: movl %gs:(%eax), %eax
|
|
; X32-NEXT: ret
|
|
; X64: f3:
|
|
; X64: movq i2@GOTTPOFF(%rip), %rax
|
|
; X64-NEXT: movl %fs:(%rax), %eax
|
|
; X64-NEXT: ret
|
|
|
|
entry:
|
|
%tmp1 = load i32* @i2
|
|
ret i32 %tmp1
|
|
}
|
|
|
|
define i32* @f4() {
|
|
; X32: f4:
|
|
; X32: movl %gs:0, %eax
|
|
; X32-NEXT: addl i2@INDNTPOFF, %eax
|
|
; X32-NEXT: ret
|
|
; X64: f4:
|
|
; X64: movq %fs:0, %rax
|
|
; X64-NEXT: addq i2@GOTTPOFF(%rip), %rax
|
|
; X64-NEXT: ret
|
|
|
|
entry:
|
|
ret i32* @i2
|
|
}
|