Home | History | Annotate | Download | only in X86
      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