diff options
author | Quentin Colombet <qcolombet@apple.com> | 2015-12-09 23:08:18 +0000 |
---|---|---|
committer | Quentin Colombet <qcolombet@apple.com> | 2015-12-09 23:08:18 +0000 |
commit | 5d2f7cfd44db983c5c21d36356c3319d792a90bc (patch) | |
tree | 516d6364e8b823dcfa6d9c7915a950cae0c2f0cf /llvm/test/CodeGen/X86/x86-shrink-wrap-unwind.ll | |
parent | 429183e7c8b93e8fcbad7741f87fc25d1cb94d51 (diff) | |
download | bcm5719-llvm-5d2f7cfd44db983c5c21d36356c3319d792a90bc.tar.gz bcm5719-llvm-5d2f7cfd44db983c5c21d36356c3319d792a90bc.zip |
[X86] Enable shrink-wrapping by default, but keep it disabled for stack frames
without a frame pointer when unwind may happen.
This is a workaround for a bug in the way we emit the CFI directives for
frameless unwind information. See PR25614.
llvm-svn: 255175
Diffstat (limited to 'llvm/test/CodeGen/X86/x86-shrink-wrap-unwind.ll')
-rw-r--r-- | llvm/test/CodeGen/X86/x86-shrink-wrap-unwind.ll | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/X86/x86-shrink-wrap-unwind.ll b/llvm/test/CodeGen/X86/x86-shrink-wrap-unwind.ll new file mode 100644 index 00000000000..7c00f407b1e --- /dev/null +++ b/llvm/test/CodeGen/X86/x86-shrink-wrap-unwind.ll @@ -0,0 +1,153 @@ +; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK +; +; This test checks that we do not use shrink-wrapping when +; the function does not have any frame pointer and may unwind. +; This is a workaround for a limitation in the emission of +; the CFI directives, that are not correct in such case. +; PR25614 +; +; Note: This test cannot be merged with the shrink-wrapping tests +; because the booleans set on the command line take precedence on +; the target logic that disable shrink-wrapping. +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" +target triple = "x86_64-apple-macosx" + + +; No shrink-wrapping should occur here, until the CFI information are fixed. +; CHECK-LABEL: framelessUnwind: +; +; Prologue code. +; (What we push does not matter. It should be some random sratch register.) +; CHECK: pushq +; +; Compare the arguments and jump to exit. +; After the prologue is set. +; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]] +; CHECK-NEXT: cmpl %esi, [[ARG0CPY]] +; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]] +; +; Store %a in the alloca. +; CHECK: movl [[ARG0CPY]], 4(%rsp) +; Set the alloca address in the second argument. +; CHECK-NEXT: leaq 4(%rsp), %rsi +; Set the first argument to zero. +; CHECK-NEXT: xorl %edi, %edi +; CHECK-NEXT: callq _doSomething +; +; CHECK: [[EXIT_LABEL]]: +; +; Without shrink-wrapping, epilogue is in the exit block. +; Epilogue code. (What we pop does not matter.) +; CHECK-NEXT: popq +; +; CHECK-NEXT: retq +define i32 @framelessUnwind(i32 %a, i32 %b) #0 { + %tmp = alloca i32, align 4 + %tmp2 = icmp slt i32 %a, %b + br i1 %tmp2, label %true, label %false + +true: + store i32 %a, i32* %tmp, align 4 + %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) + br label %false + +false: + %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] + ret i32 %tmp.0 +} + +declare i32 @doSomething(i32, i32*) + +attributes #0 = { "no-frame-pointer-elim"="false" } + +; Shrink-wrapping should occur here. We have a frame pointer. +; CHECK-LABEL: frameUnwind: +; +; Compare the arguments and jump to exit. +; No prologue needed. +; +; Compare the arguments and jump to exit. +; After the prologue is set. +; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]] +; CHECK-NEXT: cmpl %esi, [[ARG0CPY]] +; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]] +; +; Prologue code. +; CHECK: pushq %rbp +; CHECK: movq %rsp, %rbp +; +; Store %a in the alloca. +; CHECK: movl [[ARG0CPY]], -4(%rbp) +; Set the alloca address in the second argument. +; CHECK-NEXT: leaq -4(%rbp), %rsi +; Set the first argument to zero. +; CHECK-NEXT: xorl %edi, %edi +; CHECK-NEXT: callq _doSomething +; +; Epilogue code. (What we pop does not matter.) +; CHECK: popq %rbp +; +; CHECK: [[EXIT_LABEL]]: +; CHECK-NEXT: retq +define i32 @frameUnwind(i32 %a, i32 %b) #1 { + %tmp = alloca i32, align 4 + %tmp2 = icmp slt i32 %a, %b + br i1 %tmp2, label %true, label %false + +true: + store i32 %a, i32* %tmp, align 4 + %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) + br label %false + +false: + %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] + ret i32 %tmp.0 +} + +attributes #1 = { "no-frame-pointer-elim"="true" } + +; Shrink-wrapping should occur here. We do not have to unwind. +; CHECK-LABEL: framelessnoUnwind: +; +; Compare the arguments and jump to exit. +; No prologue needed. +; +; Compare the arguments and jump to exit. +; After the prologue is set. +; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]] +; CHECK-NEXT: cmpl %esi, [[ARG0CPY]] +; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]] +; +; Prologue code. +; (What we push does not matter. It should be some random sratch register.) +; CHECK: pushq +; +; Store %a in the alloca. +; CHECK: movl [[ARG0CPY]], 4(%rsp) +; Set the alloca address in the second argument. +; CHECK-NEXT: leaq 4(%rsp), %rsi +; Set the first argument to zero. +; CHECK-NEXT: xorl %edi, %edi +; CHECK-NEXT: callq _doSomething +; +; Epilogue code. +; CHECK-NEXT: addq +; +; CHECK: [[EXIT_LABEL]]: +; CHECK-NEXT: retq +define i32 @framelessnoUnwind(i32 %a, i32 %b) #2 { + %tmp = alloca i32, align 4 + %tmp2 = icmp slt i32 %a, %b + br i1 %tmp2, label %true, label %false + +true: + store i32 %a, i32* %tmp, align 4 + %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) + br label %false + +false: + %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] + ret i32 %tmp.0 +} + +attributes #2 = { "no-frame-pointer-elim"="false" nounwind } |