blob: f10fabf587de81cd1bf09859de119c0c98ebdc26 [file] [log] [blame]
# RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass shadow-call-stack -verify-machineinstrs -o - %s | FileCheck %s
--- |
define void @no_return() #0 { ret void }
define void @normal_return() #0 { ret void }
define void @normal_return_leaf_func() #0 { ret void }
define void @short_leaf_func() #0 { ret void }
define void @normal_tail_call() #0 { ret void }
define void @r11_tail_call() #0 { ret void }
define void @conditional_tail_call() #0 { ret void }
define void @r10_live_in() #0 { ret void }
attributes #0 = { shadowcallstack }
...
---
# CHECK-LABEL: name: no_return
name: no_return
tracksRegLiveness: true
frameInfo:
adjustsStack: true # not a leaf function
body: |
; CHECK: bb.0:
bb.0:
; CHECK-NEXT: $eax = MOV32ri 13
$eax = MOV32ri 13
...
---
# CHECK-LABEL: name: normal_return
name: normal_return
tracksRegLiveness: true
frameInfo:
adjustsStack: true # not a leaf function
body: |
; CHECK: bb.0:
bb.0:
; CHECK: $r10 = MOV64rm $rsp, 1, $noreg, 0, $noreg
; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
; CHECK-NEXT: ADD64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
; CHECK-NEXT: $r11 = MOV64rm $r11, 1, $noreg, 0, $gs
; CHECK-NEXT: MOV64mr $r11, 1, $noreg, 0, $gs, $r10
; CHECK-NEXT: $eax = MOV32ri 13
$eax = MOV32ri 13
; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
; CHECK-NEXT: $r10 = MOV64rm $r11, 1, $noreg, 0, $gs
; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
; CHECK-NEXT: SUB64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
; CHECK-NEXT: CMP64mr $rsp, 1, $noreg, 0, $noreg, $r10, implicit-def $eflags
; CHECK-NEXT: JNE_1 %bb.1, implicit $eflags
; CHECK-NEXT: RETQ $eax
RETQ $eax
; CHECK: bb.1:
; CHECK-NEXT; TRAP
...
---
# CHECK-LABEL: name: normal_return_leaf_func
name: normal_return_leaf_func
tracksRegLiveness: true
frameInfo:
adjustsStack: false # leaf function
body: |
; CHECK: bb.0:
; CHECK: liveins: $rcx
bb.0:
liveins: $rcx
; CHECK: $rdx = MOV64rm $rsp, 1, $noreg, 0, $noreg
; CHECK-NEXT: $eax = MOV32ri 0
$eax = MOV32ri 0
; CHECK-NEXT: CMP64ri8 $rcx, 5, implicit-def $eflags
CMP64ri8 $rcx, 5, implicit-def $eflags
; CHECK-NEXT: JA_1 %bb.1, implicit $eflags
JA_1 %bb.1, implicit $eflags
; CHECK-NEXT: JMP_1 %bb.2
JMP_1 %bb.2
; CHECK: bb.1
; CHECK: liveins: $eax, $rdx
bb.1:
liveins: $eax
; CHECKT: $eax = MOV32ri 1
$eax = MOV32ri 1
; CHECK: bb.2
; CHECK: liveins: $eax, $rdx
bb.2:
liveins: $eax
; CHECK: CMP64mr $rsp, 1, $noreg, 0, $noreg, $rdx, implicit-def $eflags
; CHECK-NEXT: JNE_1 %bb.3, implicit $eflags
; CHECK-NEXT: RETQ $eax
RETQ $eax
; CHECK: bb.3:
; CHECK-NEXT; TRAP
...
---
# CHECK-LABEL: name: short_leaf_func
name: short_leaf_func
tracksRegLiveness: true
frameInfo:
adjustsStack: false # leaf function
body: |
; CHECK: bb.0:
bb.0:
; Ensure these are not counted as machine instructions
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
DBG_VALUE 0
DBG_VALUE 0
DBG_VALUE 0
; CHECK: $eax = MOV32ri 13
$eax = MOV32ri 13
; CHECK-NEXT: RETQ $eax
RETQ $eax
...
---
# CHECK-LABEL: name: normal_tail_call
name: normal_tail_call
tracksRegLiveness: true
frameInfo:
adjustsStack: true # not a leaf function
body: |
; CHECK: bb.0:
bb.0:
; CHECK: $r10 = MOV64rm $rsp, 1, $noreg, 0, $noreg
; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
; CHECK-NEXT: ADD64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
; CHECK-NEXT: $r11 = MOV64rm $r11, 1, $noreg, 0, $gs
; CHECK-NEXT: MOV64mr $r11, 1, $noreg, 0, $gs, $r10
; CHECK-NEXT: $eax = MOV32ri 13
$eax = MOV32ri 13
; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
; CHECK-NEXT: $r10 = MOV64rm $r11, 1, $noreg, 0, $gs
; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
; CHECK-NEXT: SUB64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
; CHECK-NEXT: CMP64mr $rsp, 1, $noreg, 0, $noreg, $r10, implicit-def $eflags
; CHECK-NEXT: JNE_1 %bb.1, implicit $eflags
; CHECK-NEXT: TAILJMPr64 $rax
TAILJMPr64 $rax
; CHECK: bb.1:
; CHECK-NEXT; TRAP
...
---
# CHECK-LABEL: name: r11_tail_call
name: r11_tail_call
tracksRegLiveness: true
frameInfo:
adjustsStack: true # not a leaf function
body: |
; CHECK: bb.0:
bb.0:
; CHECK: $r10 = MOV64rm $rsp, 1, $noreg, 0, $noreg
; CHECK-NEXT: $r11 = XOR64rr undef $r11, undef $r11, implicit-def $eflags
; CHECK-NEXT: ADD64mi8 $r11, 1, $noreg, 0, $gs, 8, implicit-def $eflags
; CHECK-NEXT: $r11 = MOV64rm $r11, 1, $noreg, 0, $gs
; CHECK-NEXT: MOV64mr $r11, 1, $noreg, 0, $gs, $r10
; CHECK-NEXT: $eax = MOV32ri 13
$eax = MOV32ri 13
; CHECK-NEXT: $r10 = XOR64rr undef $r10, undef $r10, implicit-def $eflags
; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
; CHECK-NEXT: $r10 = MOV64rm $r10, 1, $noreg, 0, $gs
; CHECK-NEXT: SUB64mi8 $noreg, 1, $noreg, 0, $gs, 8, implicit-def $eflags
; CHECK-NEXT: CMP64mr $rsp, 1, $noreg, 0, $noreg, $r10, implicit-def $eflags
; CHECK-NEXT: JNE_1 %bb.1, implicit $eflags
; CHECK-NEXT: TAILJMPr64 undef $r11
TAILJMPr64 undef $r11
; CHECK: bb.1:
; CHECK-NEXT; TRAP
...
---
# CHECK-LABEL: name: conditional_tail_call
name: conditional_tail_call
tracksRegLiveness: true
frameInfo:
adjustsStack: true # not a leaf function
body: |
; CHECK: bb.0:
bb.0:
; CHECK: $eax = MOV32ri 13
$eax = MOV32ri 13
; CHECK-NEXT: TAILJMPd64_CC @conditional_tail_call, undef $eflags
TAILJMPd64_CC @conditional_tail_call, undef $eflags
...
---
# CHECK-LABEL: name: r10_live_in
name: r10_live_in
tracksRegLiveness: true
frameInfo:
adjustsStack: true # not a leaf function
body: |
; CHECK: bb.0:
; CHECK: liveins: $r10
bb.0:
liveins: $r10
; CHECK: $eax = MOV32ri 13
$eax = MOV32ri 13
; CHECK-NEXT: RETQ $eax
RETQ $eax
...