summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-01-01 06:50:01 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-01-01 06:50:01 +0000
commit011980cd50d5ddc5112c8440ffe9161de60b40ae (patch)
treeb9c31e0645af28137517d9f789e3a7deb3c25cbc /llvm/test
parent88ddef7b174c82d0c9da5d0a21c0dcd6a181e828 (diff)
downloadbcm5719-llvm-011980cd50d5ddc5112c8440ffe9161de60b40ae.tar.gz
bcm5719-llvm-011980cd50d5ddc5112c8440ffe9161de60b40ae.zip
[X86] Add intrinsics for reading and writing to the flags register
LLVM's targets need to know if stack pointer adjustments occur after the prologue. This is needed to correctly determine if the red-zone is appropriate to use or if a frame pointer is required. Normally, LLVM can figure this out very precisely by reasoning about the contents of the MachineFunction. There is an interesting corner case: inline assembly. The vast majority of inline assembly which will perform a push or pop is done so to pair up with pushf or popf as appropriate. Unfortunately, this inline assembly doesn't mark the stack pointer as clobbered because, well, it isn't. The stack pointer is decremented and then immediately incremented. Because of this, LLVM was changed in r256456 to conservatively assume that inline assembly contain a sequence of stack operations. This is unfortunate because the vast majority of inline assembly will not end up manipulating the stack pointer in any way at all. Instead, let's provide a more principled solution: an intrinsic. FWIW, other compilers (MSVC and GCC among them) also provide this functionality as an intrinsic. llvm-svn: 256685
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll8
-rw-r--r--llvm/test/CodeGen/X86/inline-sse.ll4
-rw-r--r--llvm/test/CodeGen/X86/pr11415.ll8
-rw-r--r--llvm/test/CodeGen/X86/win64_frame.ll5
-rw-r--r--llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll37
-rw-r--r--llvm/test/CodeGen/X86/x86-flags-intrinsics.ll31
-rw-r--r--llvm/test/CodeGen/X86/x86-win64-shrink-wrapping.ll4
-rw-r--r--llvm/test/DebugInfo/COFF/asm.ll17
8 files changed, 84 insertions, 30 deletions
diff --git a/llvm/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll b/llvm/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll
index a74aa2dd462..dfb98bb1ab3 100644
--- a/llvm/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll
+++ b/llvm/test/CodeGen/X86/2009-06-03-Win64SpillXMM.ll
@@ -1,9 +1,7 @@
; RUN: llc -mcpu=generic -mtriple=x86_64-mingw32 < %s | FileCheck %s
-; CHECK: pushq %rbp
-; CHECK: subq $32, %rsp
-; CHECK: leaq 32(%rsp), %rbp
-; CHECK: movaps %xmm8, -16(%rbp)
-; CHECK: movaps %xmm7, -32(%rbp)
+; CHECK: subq $40, %rsp
+; CHECK: movaps %xmm8, 16(%rsp)
+; CHECK: movaps %xmm7, (%rsp)
define i32 @a() nounwind {
entry:
diff --git a/llvm/test/CodeGen/X86/inline-sse.ll b/llvm/test/CodeGen/X86/inline-sse.ll
index 78d6b762b5e..08819b85829 100644
--- a/llvm/test/CodeGen/X86/inline-sse.ll
+++ b/llvm/test/CodeGen/X86/inline-sse.ll
@@ -21,11 +21,9 @@ define void @nop() nounwind {
;
; X64-LABEL: nop:
; X64: # BB#0:
-; X64-NEXT: subq $24, %rsp
; X64-NEXT: #APP
; X64-NEXT: #NO_APP
-; X64-NEXT: movaps %xmm0, (%rsp)
-; X64-NEXT: addq $24, %rsp
+; X64-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp)
; X64-NEXT: retq
%1 = alloca <4 x float>, align 16
%2 = call <4 x float> asm "", "=x,~{dirflag},~{fpsr},~{flags}"()
diff --git a/llvm/test/CodeGen/X86/pr11415.ll b/llvm/test/CodeGen/X86/pr11415.ll
index 73c49701411..6c32a2206a7 100644
--- a/llvm/test/CodeGen/X86/pr11415.ll
+++ b/llvm/test/CodeGen/X86/pr11415.ll
@@ -4,17 +4,15 @@
; defining %0 before it was read. This caused us to omit the
; movq -8(%rsp), %rdx
-; CHECK: pushq %rax
; CHECK: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: movq %rcx, %rax
-; CHECK-NEXT: movq %rax, (%rsp)
-; CHECK-NEXT: movq (%rsp), %rdx
+; CHECK-NEXT: movq %rax, -8(%rsp)
+; CHECK-NEXT: movq -8(%rsp), %rdx
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: movq %rdx, %rax
-; CHECK-NEXT: movq %rdx, (%rsp)
-; CHECK-NEXT: popq %rcx
+; CHECK-NEXT: movq %rdx, -8(%rsp)
; CHECK-NEXT: ret
define i64 @foo() {
diff --git a/llvm/test/CodeGen/X86/win64_frame.ll b/llvm/test/CodeGen/X86/win64_frame.ll
index 27d78dbe547..fd7156ed2fe 100644
--- a/llvm/test/CodeGen/X86/win64_frame.ll
+++ b/llvm/test/CodeGen/X86/win64_frame.ll
@@ -128,11 +128,9 @@ entry:
; CHECK: .seh_setframe 5, 0
; CHECK: .seh_endprologue
- %call = call i64 asm sideeffect "pushf\0A\09popq $0\0A", "=r,~{dirflag},~{fpsr},~{flags}"()
- ; CHECK-NEXT: #APP
+ %call = call i64 @llvm.x86.flags.read.u64()
; CHECK-NEXT: pushfq
; CHECK-NEXT: popq %rax
- ; CHECK: #NO_APP
ret i64 %call
; CHECK-NEXT: popq %rbp
@@ -187,5 +185,6 @@ define i64 @f10(i64* %foo, i64 %bar, i64 %baz) {
}
declare i8* @llvm.returnaddress(i32) nounwind readnone
+declare i64 @llvm.x86.flags.read.u64()
declare void @llvm.va_start(i8*) nounwind
diff --git a/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll b/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll
new file mode 100644
index 00000000000..4c5032aedbc
--- /dev/null
+++ b/llvm/test/CodeGen/X86/x86-64-flags-intrinsics.ll
@@ -0,0 +1,37 @@
+; RUN: llc < %s | FileCheck %s
+target triple = "x86_64-pc-win32"
+
+declare i64 @llvm.x86.flags.read.u64()
+declare void @llvm.x86.flags.write.u64(i64)
+
+define i64 @read_flags() {
+entry:
+ %flags = call i64 @llvm.x86.flags.read.u64()
+ ret i64 %flags
+}
+
+; CHECK-LABEL: read_flags:
+; CHECK: pushq %rbp
+; CHECK: .seh_pushreg 5
+; CHECK: movq %rsp, %rbp
+; CHECK: .seh_setframe 5, 0
+; CHECK: .seh_endprologue
+; CHECK-NEXT: pushfq
+; CHECK-NEXT: popq %rax
+; CHECK-NEXT: popq %rbp
+
+define void @write_flags(i64 %arg) {
+entry:
+ call void @llvm.x86.flags.write.u64(i64 %arg)
+ ret void
+}
+
+; CHECK-LABEL: write_flags:
+; CHECK: pushq %rbp
+; CHECK: .seh_pushreg 5
+; CHECK: movq %rsp, %rbp
+; CHECK: .seh_setframe 5, 0
+; CHECK: .seh_endprologue
+; CHECK-NEXT: pushq %rcx
+; CHECK-NEXT: popfq
+; CHECK-NEXT: popq %rbp
diff --git a/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll b/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll
new file mode 100644
index 00000000000..325de7d5f1e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/x86-flags-intrinsics.ll
@@ -0,0 +1,31 @@
+; RUN: llc < %s | FileCheck %s
+target triple = "i686-pc-win32"
+
+declare i32 @llvm.x86.flags.read.u32()
+declare void @llvm.x86.flags.write.u32(i32)
+
+define i32 @read_flags() {
+entry:
+ %flags = call i32 @llvm.x86.flags.read.u32()
+ ret i32 %flags
+}
+
+; CHECK-LABEL: _read_flags:
+; CHECK: pushl %ebp
+; CHECK-NEXT: movl %esp, %ebp
+; CHECK-NEXT: pushfl
+; CHECK-NEXT: popl %eax
+; CHECK-NEXT: popl %ebp
+
+define x86_fastcallcc void @write_flags(i32 inreg %arg) {
+entry:
+ call void @llvm.x86.flags.write.u32(i32 %arg)
+ ret void
+}
+
+; CHECK-LABEL: @write_flags@4:
+; CHECK: pushl %ebp
+; CHECK-NEXT: movl %esp, %ebp
+; CHECK-NEXT: pushl %ecx
+; CHECK-NEXT: popfl
+; CHECK-NEXT: popl %ebp
diff --git a/llvm/test/CodeGen/X86/x86-win64-shrink-wrapping.ll b/llvm/test/CodeGen/X86/x86-win64-shrink-wrapping.ll
index 395de686d2e..5d9b2ba3267 100644
--- a/llvm/test/CodeGen/X86/x86-win64-shrink-wrapping.ll
+++ b/llvm/test/CodeGen/X86/x86-win64-shrink-wrapping.ll
@@ -11,10 +11,8 @@ target triple = "x86_64--windows-gnu"
; etc.) prior to the return and this is forbidden for Win64.
; CHECK-LABEL: loopInfoSaveOutsideLoop:
; CHECK: push
-; CHECK: push
; CHECK-NOT: popq
; CHECK: popq
-; CHECK: popq
; CHECK-NOT: popq
; CHECK-NEXT: retq
define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) #0 {
@@ -57,7 +55,6 @@ if.end: ; preds = %if.else, %for.end
;
; Prologue code.
; Make sure we save the CSR used in the inline asm: rbx.
-; CHECK: pushq %rbp
; CHECK: pushq %rbx
;
; DISABLE: testl %ecx, %ecx
@@ -79,7 +76,6 @@ if.end: ; preds = %if.else, %for.end
; DISABLE: jmp [[EPILOG_BB:.LBB[0-9_]+]]
;
; ENABLE-NEXT: popq %rbx
-; ENABLE-NEXT: popq %rbp
; ENABLE-NEXT: retq
;
; CHECK: [[ELSE_LABEL]]: # %if.else
diff --git a/llvm/test/DebugInfo/COFF/asm.ll b/llvm/test/DebugInfo/COFF/asm.ll
index f3e52df54be..b67100c87fd 100644
--- a/llvm/test/DebugInfo/COFF/asm.ll
+++ b/llvm/test/DebugInfo/COFF/asm.ll
@@ -130,15 +130,12 @@
; X64-NEXT: .L{{.*}}:{{$}}
; X64-NEXT: [[START:.*]]:{{$}}
; X64: # BB
-; X64: pushq %rbp
-; X64-NEXT: subq $32, %rsp
-; X64-NEXT: leaq 32(%rsp), %rbp
+; X64: subq $40, %rsp
; X64-NEXT: [[ASM_LINE:.*]]:{{$}}
; X64: [[CALL_LINE:.*]]:{{$}}
; X64: callq g
; X64-NEXT: [[EPILOG_AND_RET:.*]]:
-; X64: addq $32, %rsp
-; X64-NEXT: popq %rbp
+; X64: addq $40, %rsp
; X64-NEXT: ret
; X64-NEXT: [[END_OF_F:.*]]:
;
@@ -225,22 +222,22 @@
; OBJ64: ProcStart {
; OBJ64-NEXT: DisplayName: f
; OBJ64-NEXT: Section: f
-; OBJ64-NEXT: CodeSize: 0x17
+; OBJ64-NEXT: CodeSize: 0xE
; OBJ64-NEXT: }
; OBJ64-NEXT: ProcEnd
; OBJ64-NEXT: ]
; OBJ64: FunctionLineTable [
; OBJ64-NEXT: Name: f
; OBJ64-NEXT: Flags: 0x1
-; OBJ64-NEXT: CodeSize: 0x17
+; OBJ64-NEXT: CodeSize: 0xE
; OBJ64-NEXT: FilenameSegment [
; OBJ64-NEXT: Filename: D:\asm.c
; OBJ64-NEXT: +0x0: 3
; FIXME: An empty __asm stmt creates an extra entry.
; See PR18679 for the details.
-; OBJ64-NEXT: +0xA: 4
-; OBJ64-NEXT: +0xC: 5
-; OBJ64-NEXT: +0x11: 6
+; OBJ64-NEXT: +0x4: 4
+; OBJ64-NEXT: +0x4: 5
+; OBJ64-NEXT: +0x9: 6
; OBJ64-NEXT: ColStart: 0
; OBJ64-NEXT: ColEnd: 0
; OBJ64-NEXT: ColStart: 0
OpenPOWER on IntegriCloud