1 ; RUN: llc %s -o - | FileCheck %s 2 ; 3 ; Note: This test cannot be merged with the shrink-wrapping tests 4 ; because the booleans set on the command line take precedence on 5 ; the target logic that disable shrink-wrapping. 6 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 7 target triple = "x86_64-apple-macosx" 8 9 10 ; This test checks that we do not use shrink-wrapping when 11 ; the function does not have any frame pointer and may unwind. 12 ; This is a workaround for a limitation in the emission of 13 ; the CFI directives, that are not correct in such case. 14 ; PR25614 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 155 156 ; Check that we generate correct code for segmented stack. 157 ; We used to emit the code at the entry point of the function 158 ; instead of just before the prologue. 159 ; For now, shrink-wrapping is disabled on segmented stack functions: PR26107. 160 ; 161 ; CHECK-LABEL: segmentedStack: 162 ; CHECK: cmpq 163 ; CHECK-NEXT: ja [[ENTRY_LABEL:LBB[0-9_]+]] 164 ; 165 ; CHECK: callq ___morestack 166 ; CHECK-NEXT: retq 167 ; 168 ; CHECK: [[ENTRY_LABEL]]: 169 ; Prologue 170 ; CHECK: push 171 ; 172 ; In PR26107, we use to drop these two basic blocks, because 173 ; the segmentedStack entry block was jumping directly to 174 ; the place where the prologue is actually needed, which is 175 ; the call to memcmp. 176 ; Then, those two basic blocks did not have any predecessors 177 ; anymore and were removed. 178 ; 179 ; Check if vk1 is null 180 ; CHECK: testq %rdi, %rdi 181 ; CHECK-NEXT: je [[STRINGS_EQUAL:LBB[0-9_]+]] 182 ; 183 ; Check if vk2 is null 184 ; CHECK: testq %rsi, %rsi 185 ; CHECK-NEXT: je [[STRINGS_EQUAL]] 186 ; 187 ; CHECK: [[STRINGS_EQUAL]] 188 ; CHECK: popq 189 define zeroext i1 @segmentedStack(i8* readonly %vk1, i8* readonly %vk2, i64 %key_size) #5 { 190 entry: 191 %cmp.i = icmp eq i8* %vk1, null 192 %cmp1.i = icmp eq i8* %vk2, null 193 %brmerge.i = or i1 %cmp.i, %cmp1.i 194 %cmp1.mux.i = and i1 %cmp.i, %cmp1.i 195 br i1 %brmerge.i, label %__go_ptr_strings_equal.exit, label %if.end4.i 196 197 if.end4.i: ; preds = %entry 198 %tmp = getelementptr inbounds i8, i8* %vk1, i64 8 199 %tmp1 = bitcast i8* %tmp to i64* 200 %tmp2 = load i64, i64* %tmp1, align 8 201 %tmp3 = getelementptr inbounds i8, i8* %vk2, i64 8 202 %tmp4 = bitcast i8* %tmp3 to i64* 203 %tmp5 = load i64, i64* %tmp4, align 8 204 %cmp.i.i = icmp eq i64 %tmp2, %tmp5 205 br i1 %cmp.i.i, label %land.rhs.i.i, label %__go_ptr_strings_equal.exit 206 207 land.rhs.i.i: ; preds = %if.end4.i 208 %tmp6 = bitcast i8* %vk2 to i8** 209 %tmp7 = load i8*, i8** %tmp6, align 8 210 %tmp8 = bitcast i8* %vk1 to i8** 211 %tmp9 = load i8*, i8** %tmp8, align 8 212 %call.i.i = tail call i32 @memcmp(i8* %tmp9, i8* %tmp7, i64 %tmp2) #5 213 %cmp4.i.i = icmp eq i32 %call.i.i, 0 214 br label %__go_ptr_strings_equal.exit 215 216 __go_ptr_strings_equal.exit: ; preds = %land.rhs.i.i, %if.end4.i, %entry 217 %retval.0.i = phi i1 [ %cmp1.mux.i, %entry ], [ false, %if.end4.i ], [ %cmp4.i.i, %land.rhs.i.i ] 218 ret i1 %retval.0.i 219 } 220 221 ; Function Attrs: nounwind readonly 222 declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) #5 223 224 attributes #5 = { nounwind readonly ssp uwtable "split-stack" } 225