aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/CodeGen/AMDGPU/splitkit.mir
blob: dd3abf6007854089b47b01297488a585c1aa15c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
# RUN: llc -o - %s -mtriple=amdgcn-- -mcpu=fiji -verify-machineinstrs -run-pass=greedy,virtregrewriter | FileCheck %s
--- |
  define amdgpu_kernel void @func0() #0 { ret void }
  define amdgpu_kernel void @func1() #0 { ret void }
  define amdgpu_kernel void @splitHoist() #0 { ret void }

  attributes #0 = { "amdgpu-num-sgpr"="12" }
...
---
# Make sure we only get a single spill+reload even if liverange splitting
# created a sequence of multiple copy instructions.
name: func0
body: |
  bb.0:
    ; CHECK-LABEL: name: func0
    ; CHECK: S_NOP 0, implicit-def renamable $sgpr0
    ; CHECK-NEXT: S_NOP 0, implicit-def renamable $sgpr3
    ; CHECK-NEXT: SI_SPILL_S128_SAVE renamable $sgpr0_sgpr1_sgpr2_sgpr3, %stack.0, implicit $exec, implicit $sp_reg :: (store (s128) into %stack.0, align 4, addrspace 5)
    ; CHECK-NEXT: S_NOP 0, implicit-def dead $sgpr0, implicit-def dead $sgpr1, implicit-def dead $sgpr2, implicit-def dead $sgpr3, implicit-def dead $sgpr4, implicit-def dead $sgpr5, implicit-def dead $sgpr6, implicit-def dead $sgpr7, implicit-def dead $sgpr8, implicit-def dead $sgpr9, implicit-def dead $sgpr10, implicit-def dead $sgpr11
    ; CHECK-NEXT: renamable $sgpr0_sgpr1_sgpr2_sgpr3 = SI_SPILL_S128_RESTORE %stack.0, implicit $exec, implicit $sp_reg :: (load (s128) from %stack.0, align 4, addrspace 5)
    ; CHECK-NEXT: S_NOP 0, implicit renamable $sgpr0
    ; CHECK-NEXT: S_NOP 0, implicit renamable $sgpr3
    ; CHECK-NEXT: S_NOP 0, implicit renamable $sgpr0
    ; CHECK-NEXT: S_NOP 0, implicit killed renamable $sgpr3
    S_NOP 0, implicit-def undef %0.sub0 : sgpr_128
    S_NOP 0, implicit-def %0.sub3 : sgpr_128

    ; Clobber registers
    S_NOP 0, implicit-def dead $sgpr0, implicit-def dead $sgpr1, implicit-def dead $sgpr2, implicit-def dead $sgpr3, implicit-def dead $sgpr4, implicit-def dead $sgpr5, implicit-def dead $sgpr6, implicit-def dead $sgpr7, implicit-def dead $sgpr8, implicit-def dead $sgpr9, implicit-def dead $sgpr10, implicit-def dead $sgpr11

    S_NOP 0, implicit %0.sub0
    S_NOP 0, implicit %0.sub3
    S_NOP 0, implicit %0.sub0
    S_NOP 0, implicit %0.sub3
...
---
# LiveRange splitting should split this into 2 intervals with the second getting
# allocated to sgpr0_sgpr1 and the first to something else so we see two copies
# in between for the two subregisters that are alive.
name: func1
tracksRegLiveness: true
body: |
  bb.0:
    liveins: $sgpr0, $sgpr1, $sgpr2
    ; CHECK-LABEL: name: func1
    ; CHECK: liveins: $sgpr0, $sgpr1, $sgpr2
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: renamable $sgpr4 = COPY $sgpr0
    ; CHECK-NEXT: renamable $sgpr6 = COPY $sgpr2
    ; CHECK-NEXT: S_NOP 0, implicit-def dead $sgpr0, implicit-def dead $sgpr1
    ; CHECK-NEXT: S_NOP 0, implicit renamable $sgpr4
    ; CHECK-NEXT: S_NOP 0, implicit renamable $sgpr6
    ; CHECK-NEXT: renamable $sgpr0 = COPY killed renamable $sgpr4
    ; CHECK-NEXT: renamable $sgpr2 = COPY renamable $sgpr6
    ; CHECK-NEXT: S_NOP 0, implicit-def dead $sgpr4, implicit-def dead $sgpr5, implicit-def dead $sgpr6, implicit-def dead $sgpr7, implicit-def dead $sgpr8, implicit-def dead $sgpr9, implicit-def dead $sgpr10, implicit-def dead $sgpr11, implicit-def dead $sgpr12, implicit-def dead $sgpr13, implicit-def dead $sgpr14, implicit-def dead $sgpr15, implicit-def dead $vcc_lo, implicit-def dead $vcc_hi
    ; CHECK-NEXT: S_NOP 0, implicit renamable $sgpr0
    ; CHECK-NEXT: S_NOP 0, implicit killed renamable $sgpr2
    undef %0.sub0 : sgpr_128 = COPY $sgpr0
    %0.sub2 = COPY $sgpr2

    S_NOP 0, implicit-def dead $sgpr0, implicit-def dead $sgpr1

    S_NOP 0, implicit %0.sub0
    S_NOP 0, implicit %0.sub2

    ; Clobber everything but sgpr0-sgpr3
    S_NOP 0, implicit-def dead $sgpr4, implicit-def dead $sgpr5, implicit-def dead $sgpr6, implicit-def dead $sgpr7, implicit-def dead $sgpr8, implicit-def dead $sgpr9, implicit-def dead $sgpr10, implicit-def dead $sgpr11, implicit-def dead $sgpr12, implicit-def dead $sgpr13, implicit-def dead $sgpr14, implicit-def dead $sgpr15, implicit-def dead $vcc_lo, implicit-def dead $vcc_hi

    S_NOP 0, implicit %0.sub0
    S_NOP 0, implicit %0.sub2
...
---
# Check that copy hoisting out of loops works. This mainly should not crash the
# compiler when it hoists a subreg copy sequence.
name: splitHoist
tracksRegLiveness: true
body: |
  ; CHECK-LABEL: name: splitHoist
  ; CHECK: bb.0:
  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   S_NOP 0, implicit-def renamable $sgpr0
  ; CHECK-NEXT:   S_NOP 0, implicit-def renamable $sgpr3
  ; CHECK-NEXT:   SI_SPILL_S128_SAVE renamable $sgpr0_sgpr1_sgpr2_sgpr3, %stack.0, implicit $exec, implicit $sp_reg :: (store (s128) into %stack.0, align 4, addrspace 5)
  ; CHECK-NEXT:   S_CBRANCH_VCCNZ %bb.1, implicit undef $vcc
  ; CHECK-NEXT:   S_BRANCH %bb.2
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.1:
  ; CHECK-NEXT:   successors: %bb.1(0x40000000), %bb.3(0x40000000)
  ; CHECK-NEXT:   liveins: $sgpr0_sgpr1_sgpr2_sgpr3:0x00000000000000C3
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   S_NOP 0, implicit renamable $sgpr0
  ; CHECK-NEXT:   S_NOP 0, implicit-def dead $sgpr0, implicit-def dead $sgpr1, implicit-def dead $sgpr2, implicit-def dead $sgpr3, implicit-def dead $sgpr4, implicit-def dead $sgpr5, implicit-def dead $sgpr6, implicit-def dead $sgpr7, implicit-def dead $sgpr8, implicit-def dead $sgpr9, implicit-def dead $sgpr10, implicit-def dead $sgpr11
  ; CHECK-NEXT:   renamable $sgpr0_sgpr1_sgpr2_sgpr3 = SI_SPILL_S128_RESTORE %stack.0, implicit $exec, implicit $sp_reg :: (load (s128) from %stack.0, align 4, addrspace 5)
  ; CHECK-NEXT:   S_CBRANCH_VCCNZ %bb.1, implicit undef $vcc
  ; CHECK-NEXT:   S_BRANCH %bb.3
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.2:
  ; CHECK-NEXT:   successors: %bb.3(0x80000000)
  ; CHECK-NEXT:   liveins: $sgpr0_sgpr1_sgpr2_sgpr3:0x00000000000000C3
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   S_NOP 0, implicit-def dead $sgpr0, implicit-def dead $sgpr1, implicit-def dead $sgpr2, implicit-def dead $sgpr3, implicit-def dead $sgpr4, implicit-def dead $sgpr5, implicit-def dead $sgpr6, implicit-def dead $sgpr7, implicit-def dead $sgpr8, implicit-def dead $sgpr9, implicit-def dead $sgpr10, implicit-def dead $sgpr11
  ; CHECK-NEXT:   renamable $sgpr0_sgpr1_sgpr2_sgpr3 = SI_SPILL_S128_RESTORE %stack.0, implicit $exec, implicit $sp_reg :: (load (s128) from %stack.0, align 4, addrspace 5)
  ; CHECK-NEXT:   S_BRANCH %bb.3
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.3:
  ; CHECK-NEXT:   liveins: $sgpr0_sgpr1_sgpr2_sgpr3:0x00000000000000C3
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   S_NOP 0, implicit renamable $sgpr0
  ; CHECK-NEXT:   S_NOP 0, implicit renamable $sgpr3
  ; CHECK-NEXT:   S_NOP 0, implicit renamable $sgpr0
  ; CHECK-NEXT:   S_NOP 0, implicit killed renamable $sgpr3
  bb.0:
    successors: %bb.1, %bb.2
    S_NOP 0, implicit-def undef %0.sub0 : sgpr_128
    S_NOP 0, implicit-def %0.sub3 : sgpr_128

    S_CBRANCH_VCCNZ %bb.1, implicit undef $vcc
    S_BRANCH %bb.2

  bb.1:
    successors: %bb.1, %bb.3
    S_NOP 0, implicit %0.sub0

    ; Clobber registers
    S_NOP 0, implicit-def dead $sgpr0, implicit-def dead $sgpr1, implicit-def dead $sgpr2, implicit-def dead $sgpr3, implicit-def dead $sgpr4, implicit-def dead $sgpr5, implicit-def dead $sgpr6, implicit-def dead $sgpr7, implicit-def dead $sgpr8, implicit-def dead $sgpr9, implicit-def dead $sgpr10, implicit-def dead $sgpr11

    S_CBRANCH_VCCNZ %bb.1, implicit undef $vcc
    S_BRANCH %bb.3

  bb.2:
    successors: %bb.3
    ; Clobber registers
    S_NOP 0, implicit-def dead $sgpr0, implicit-def dead $sgpr1, implicit-def dead $sgpr2, implicit-def dead $sgpr3, implicit-def dead $sgpr4, implicit-def dead $sgpr5, implicit-def dead $sgpr6, implicit-def dead $sgpr7, implicit-def dead $sgpr8, implicit-def dead $sgpr9, implicit-def dead $sgpr10, implicit-def dead $sgpr11
    S_BRANCH %bb.3

  bb.3:
    S_NOP 0, implicit %0.sub0
    S_NOP 0, implicit %0.sub3
    S_NOP 0, implicit %0.sub0
    S_NOP 0, implicit %0.sub3
...