1 ; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK 2 ; 3 ; This test checks that we do not use shrink-wrapping when 4 ; the function does not have any frame pointer and may unwind. 5 ; This is a workaround for a limitation in the emission of 6 ; the CFI directives, that are not correct in such case. 7 ; PR25614 8 ; 9 ; Note: This test cannot be merged with the shrink-wrapping tests 10 ; because the booleans set on the command line take precedence on 11 ; the target logic that disable shrink-wrapping. 12 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 13 target triple = "x86_64-apple-macosx" 14 15 16 ; No shrink-wrapping should occur here, until the CFI information are fixed. 17 ; CHECK-LABEL: framelessUnwind: 18 ; 19 ; Prologue code. 20 ; (What we push does not matter. It should be some random sratch register.) 21 ; CHECK: pushq 22 ; 23 ; Compare the arguments and jump to exit. 24 ; After the prologue is set. 25 ; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]] 26 ; CHECK-NEXT: cmpl %esi, [[ARG0CPY]] 27 ; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]] 28 ; 29 ; Store %a in the alloca. 30 ; CHECK: movl [[ARG0CPY]], 4(%rsp) 31 ; Set the alloca address in the second argument. 32 ; CHECK-NEXT: leaq 4(%rsp), %rsi 33 ; Set the first argument to zero. 34 ; CHECK-NEXT: xorl %edi, %edi 35 ; CHECK-NEXT: callq _doSomething 36 ; 37 ; CHECK: [[EXIT_LABEL]]: 38 ; 39 ; Without shrink-wrapping, epilogue is in the exit block. 40 ; Epilogue code. (What we pop does not matter.) 41 ; CHECK-NEXT: popq 42 ; 43 ; CHECK-NEXT: retq 44 define i32 @framelessUnwind(i32 %a, i32 %b) #0 { 45 %tmp = alloca i32, align 4 46 %tmp2 = icmp slt i32 %a, %b 47 br i1 %tmp2, label %true, label %false 48 49 true: 50 store i32 %a, i32* %tmp, align 4 51 %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) 52 br label %false 53 54 false: 55 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] 56 ret i32 %tmp.0 57 } 58 59 declare i32 @doSomething(i32, i32*) 60 61 attributes #0 = { "no-frame-pointer-elim"="false" } 62 63 ; Shrink-wrapping should occur here. We have a frame pointer. 64 ; CHECK-LABEL: frameUnwind: 65 ; 66 ; Compare the arguments and jump to exit. 67 ; No prologue needed. 68 ; 69 ; Compare the arguments and jump to exit. 70 ; After the prologue is set. 71 ; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]] 72 ; CHECK-NEXT: cmpl %esi, [[ARG0CPY]] 73 ; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]] 74 ; 75 ; Prologue code. 76 ; CHECK: pushq %rbp 77 ; CHECK: movq %rsp, %rbp 78 ; 79 ; Store %a in the alloca. 80 ; CHECK: movl [[ARG0CPY]], -4(%rbp) 81 ; Set the alloca address in the second argument. 82 ; CHECK-NEXT: leaq -4(%rbp), %rsi 83 ; Set the first argument to zero. 84 ; CHECK-NEXT: xorl %edi, %edi 85 ; CHECK-NEXT: callq _doSomething 86 ; 87 ; Epilogue code. (What we pop does not matter.) 88 ; CHECK: popq %rbp 89 ; 90 ; CHECK: [[EXIT_LABEL]]: 91 ; CHECK-NEXT: retq 92 define i32 @frameUnwind(i32 %a, i32 %b) #1 { 93 %tmp = alloca i32, align 4 94 %tmp2 = icmp slt i32 %a, %b 95 br i1 %tmp2, label %true, label %false 96 97 true: 98 store i32 %a, i32* %tmp, align 4 99 %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) 100 br label %false 101 102 false: 103 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] 104 ret i32 %tmp.0 105 } 106 107 attributes #1 = { "no-frame-pointer-elim"="true" } 108 109 ; Shrink-wrapping should occur here. We do not have to unwind. 110 ; CHECK-LABEL: framelessnoUnwind: 111 ; 112 ; Compare the arguments and jump to exit. 113 ; No prologue needed. 114 ; 115 ; Compare the arguments and jump to exit. 116 ; After the prologue is set. 117 ; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]] 118 ; CHECK-NEXT: cmpl %esi, [[ARG0CPY]] 119 ; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]] 120 ; 121 ; Prologue code. 122 ; (What we push does not matter. It should be some random sratch register.) 123 ; CHECK: pushq 124 ; 125 ; Store %a in the alloca. 126 ; CHECK: movl [[ARG0CPY]], 4(%rsp) 127 ; Set the alloca address in the second argument. 128 ; CHECK-NEXT: leaq 4(%rsp), %rsi 129 ; Set the first argument to zero. 130 ; CHECK-NEXT: xorl %edi, %edi 131 ; CHECK-NEXT: callq _doSomething 132 ; 133 ; Epilogue code. 134 ; CHECK-NEXT: addq 135 ; 136 ; CHECK: [[EXIT_LABEL]]: 137 ; CHECK-NEXT: retq 138 define i32 @framelessnoUnwind(i32 %a, i32 %b) #2 { 139 %tmp = alloca i32, align 4 140 %tmp2 = icmp slt i32 %a, %b 141 br i1 %tmp2, label %true, label %false 142 143 true: 144 store i32 %a, i32* %tmp, align 4 145 %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) 146 br label %false 147 148 false: 149 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] 150 ret i32 %tmp.0 151 } 152 153 attributes #2 = { "no-frame-pointer-elim"="false" nounwind } 154