Home | History | Annotate | Download | only in X86
      1 # RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass shadow-call-stack -verify-machineinstrs -o - %s | FileCheck %s
      2 --- |
      3 
      4   define void @no_return() #0 { ret void }
      5   define void @normal_return() #0 { ret void }
      6   define void @normal_return_leaf_func() #0 { ret void }
      7   define void @short_leaf_func() #0 { ret void }
      8   define void @normal_tail_call() #0 { ret void }
      9   define void @r11_tail_call() #0 { ret void }
     10   define void @conditional_tail_call() #0 { ret void }
     11   define void @r10_live_in() #0 { ret void }
     12 
     13   attributes #0 = { shadowcallstack }
     14 
     15 ...
     16 ---
     17 # CHECK-LABEL: name: no_return
     18 name: no_return
     19 tracksRegLiveness: true
     20 frameInfo:
     21   adjustsStack: true # not a leaf function
     22 body: |
     23   ; CHECK: bb.0:
     24   bb.0:
     25     ; CHECK-NEXT: $eax = MOV32ri 13
     26     $eax = MOV32ri 13
     27 ...
     28 ---
     29 # CHECK-LABEL: name: normal_return
     30 name: normal_return
     31 tracksRegLiveness: true
     32 frameInfo:
     33   adjustsStack: true # not a leaf function
     34 body: |
     35   ; CHECK: bb.0:
     36   bb.0:
     37     ; CHECK: $r10 = MOV64rm $rsp, 1, $noreg, 0, $noreg
     38     ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
     39     ; CHECK-NEXT: ADD64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
     40     ; CHECK-NEXT: $r11 = MOV64rm $r11, 1, $noreg, 0, $gs
     41     ; CHECK-NEXT: MOV64mr $r11, 1, $noreg, 0, $gs, $r10
     42     ; CHECK-NEXT: $eax = MOV32ri 13
     43     $eax = MOV32ri 13
     44 
     45     ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
     46     ; CHECK-NEXT: $r10 = MOV64rm $r11, 1, $noreg, 0, $gs
     47     ; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
     48     ; CHECK-NEXT: SUB64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
     49     ; CHECK-NEXT: CMP64mr $rsp, 1, $noreg, 0, $noreg, $r10, implicit-def $eflags
     50     ; CHECK-NEXT: JNE_1 %bb.1, implicit $eflags
     51     ; CHECK-NEXT: RETQ $eax
     52     RETQ $eax
     53 
     54     ; CHECK: bb.1:
     55     ; CHECK-NEXT; TRAP
     56 ...
     57 ---
     58 # CHECK-LABEL: name: normal_return_leaf_func
     59 name: normal_return_leaf_func
     60 tracksRegLiveness: true
     61 frameInfo:
     62   adjustsStack: false # leaf function
     63 body: |
     64   ; CHECK: bb.0:
     65   ; CHECK: liveins: $rcx
     66   bb.0:
     67     liveins: $rcx
     68 
     69     ; CHECK: $rdx = MOV64rm $rsp, 1, $noreg, 0, $noreg
     70     ; CHECK-NEXT: $eax = MOV32ri 0
     71     $eax = MOV32ri 0
     72     ; CHECK-NEXT: CMP64ri8 $rcx, 5, implicit-def $eflags
     73     CMP64ri8 $rcx, 5, implicit-def $eflags
     74     ; CHECK-NEXT: JA_1 %bb.1, implicit $eflags
     75     JA_1 %bb.1, implicit $eflags
     76     ; CHECK-NEXT: JMP_1 %bb.2
     77     JMP_1 %bb.2
     78 
     79   ; CHECK: bb.1
     80   ; CHECK: liveins: $eax, $rdx
     81   bb.1:
     82     liveins: $eax
     83 
     84     ; CHECKT: $eax = MOV32ri 1
     85     $eax = MOV32ri 1
     86 
     87   ; CHECK: bb.2
     88   ; CHECK: liveins: $eax, $rdx
     89   bb.2:
     90     liveins: $eax
     91 
     92     ; CHECK: CMP64mr $rsp, 1, $noreg, 0, $noreg, $rdx, implicit-def $eflags
     93     ; CHECK-NEXT: JNE_1 %bb.3, implicit $eflags
     94     ; CHECK-NEXT: RETQ $eax
     95     RETQ $eax
     96 
     97     ; CHECK: bb.3:
     98     ; CHECK-NEXT; TRAP
     99 ...
    100 ---
    101 # CHECK-LABEL: name: short_leaf_func
    102 name: short_leaf_func
    103 tracksRegLiveness: true
    104 frameInfo:
    105   adjustsStack: false # leaf function
    106 body: |
    107   ; CHECK: bb.0:
    108   bb.0:
    109     ; Ensure these are not counted as machine instructions
    110     CFI_INSTRUCTION 0
    111     CFI_INSTRUCTION 0
    112     CFI_INSTRUCTION 0
    113     DBG_VALUE 0
    114     DBG_VALUE 0
    115     DBG_VALUE 0
    116 
    117     ; CHECK: $eax = MOV32ri 13
    118     $eax = MOV32ri 13
    119 
    120     ; CHECK-NEXT: RETQ $eax
    121     RETQ $eax
    122 ...
    123 ---
    124 # CHECK-LABEL: name: normal_tail_call
    125 name: normal_tail_call
    126 tracksRegLiveness: true
    127 frameInfo:
    128   adjustsStack: true # not a leaf function
    129 body: |
    130   ; CHECK: bb.0:
    131   bb.0:
    132     ; CHECK: $r10 = MOV64rm $rsp, 1, $noreg, 0, $noreg
    133     ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
    134     ; CHECK-NEXT: ADD64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
    135     ; CHECK-NEXT: $r11 = MOV64rm $r11, 1, $noreg, 0, $gs
    136     ; CHECK-NEXT: MOV64mr $r11, 1, $noreg, 0, $gs, $r10
    137     ; CHECK-NEXT: $eax = MOV32ri 13
    138     $eax = MOV32ri 13
    139 
    140     ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
    141     ; CHECK-NEXT: $r10 = MOV64rm $r11, 1, $noreg, 0, $gs
    142     ; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
    143     ; CHECK-NEXT: SUB64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
    144     ; CHECK-NEXT: CMP64mr $rsp, 1, $noreg, 0, $noreg, $r10, implicit-def $eflags
    145     ; CHECK-NEXT: JNE_1 %bb.1, implicit $eflags
    146     ; CHECK-NEXT: TAILJMPr64 $rax
    147     TAILJMPr64 $rax
    148 
    149     ; CHECK: bb.1:
    150     ; CHECK-NEXT; TRAP
    151 ...
    152 ---
    153 # CHECK-LABEL: name: r11_tail_call
    154 name: r11_tail_call
    155 tracksRegLiveness: true
    156 frameInfo:
    157   adjustsStack: true # not a leaf function
    158 body: |
    159   ; CHECK: bb.0:
    160   bb.0:
    161     ; CHECK: $r10 = MOV64rm $rsp, 1, $noreg, 0, $noreg
    162     ; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
    163     ; CHECK-NEXT: ADD64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
    164     ; CHECK-NEXT: $r11 = MOV64rm $r11, 1, $noreg, 0, $gs
    165     ; CHECK-NEXT: MOV64mr $r11, 1, $noreg, 0, $gs, $r10
    166     ; CHECK-NEXT: $eax = MOV32ri 13
    167     $eax = MOV32ri 13
    168 
    169     ; CHECK-NEXT: $r10 = XOR64rr undef $r10, undef $r10, implicit-def $eflags
    170     ; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
    171     ; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
    172     ; CHECK-NEXT: SUB64mi8 $noreg, 1, $noreg, 0, $gs, 8, implicit-def $eflags
    173     ; CHECK-NEXT: CMP64mr $rsp, 1, $noreg, 0, $noreg, $r10, implicit-def $eflags
    174     ; CHECK-NEXT: JNE_1 %bb.1, implicit $eflags
    175     ; CHECK-NEXT: TAILJMPr64 undef $r11
    176     TAILJMPr64 undef $r11
    177 
    178     ; CHECK: bb.1:
    179     ; CHECK-NEXT; TRAP
    180 ...
    181 ---
    182 # CHECK-LABEL: name: conditional_tail_call
    183 name: conditional_tail_call
    184 tracksRegLiveness: true
    185 frameInfo:
    186   adjustsStack: true # not a leaf function
    187 body: |
    188   ; CHECK: bb.0:
    189   bb.0:
    190     ; CHECK: $eax = MOV32ri 13
    191     $eax = MOV32ri 13
    192 
    193     ; CHECK-NEXT: TAILJMPd64_CC @conditional_tail_call, undef $eflags
    194     TAILJMPd64_CC @conditional_tail_call, undef $eflags
    195 ...
    196 ---
    197 # CHECK-LABEL: name: r10_live_in
    198 name: r10_live_in
    199 tracksRegLiveness: true
    200 frameInfo:
    201   adjustsStack: true # not a leaf function
    202 body: |
    203   ; CHECK: bb.0:
    204   ; CHECK: liveins: $r10
    205   bb.0:
    206     liveins: $r10
    207 
    208     ; CHECK: $eax = MOV32ri 13
    209     $eax = MOV32ri 13
    210     ; CHECK-NEXT: RETQ $eax
    211     RETQ $eax
    212 ...
    213