forked from OSchip/llvm-project
154 lines
4.1 KiB
LLVM
154 lines
4.1 KiB
LLVM
; 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 }
|