source: CLRX/CLRadeonExtender/trunk/tests/amdasm/AsmRegAlloc.cpp @ 3885

Last change on this file since 3885 was 3885, checked in by matszpk, 16 months ago

CLRadeonExtender: AsmRegAlloc?: Add next testcase to test retSSAIds.

File size: 184.8 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2018 Mateusz Szpakowski
4 *
5 *  This library is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Lesser General Public
7 *  License as published by the Free Software Foundation; either
8 *  version 2.1 of the License, or (at your option) any later version.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#include <CLRX/Config.h>
21#include <algorithm>
22#include <iostream>
23#include <sstream>
24#include <string>
25#include <vector>
26#include <cstring>
27#include <CLRX/utils/Utilities.h>
28#include <CLRX/amdasm/Assembler.h>
29#include <CLRX/utils/Containers.h>
30#include "../TestUtils.h"
31
32using namespace CLRX;
33
34typedef AsmRegAllocator::CodeBlock CodeBlock;
35typedef AsmRegAllocator::NextBlock NextBlock;
36
37struct CCodeBlock
38{
39    size_t start, end; // place in code
40    Array<NextBlock> nexts; ///< nexts blocks
41    bool haveCalls;
42    bool haveReturn;
43    bool haveEnd;
44};
45
46struct AsmCodeStructCase
47{
48    const char* input;
49    Array<CCodeBlock> codeBlocks;
50    bool good;
51    const char* errorMessages;
52};
53
54static const AsmCodeStructCase codeStructTestCases1Tbl[] =
55{
56    {   // 0
57        "v_mov_b32 v1, v2\n"
58        "v_mov_b32 v1, v3\n",
59        {
60            { 0, 8, { }, false, false, true }
61        },
62        true, ""
63    },
64    {   // 1
65        "v_mov_b32 v1, v2\n"
66        "v_mov_b32 v1, v3\n"
67        ".cf_end\n"
68        ".cf_start\n"
69        "v_mov_b32 v4, v2\n"
70        "v_mov_b32 v8, v3\n"
71        "v_mov_b32 v8, v3\n"
72        ".cf_end\n",
73        {
74            { 0, 8, { }, false, false, true },
75            { 8, 20, { }, false, false, true }
76        },
77        true, ""
78    },
79    {   // 2 - ignore cf_start to cf_end (except first)
80        "v_mov_b32 v1, v2\n"
81        "v_mov_b32 v1, v3\n"
82        ".cf_start\n"
83        "v_mov_b32 v4, v2\n"
84        "v_mov_b32 v8, v3\n"
85        ".cf_start\n"
86        "v_mov_b32 v8, v3\n"
87        ".cf_end\n"
88        ".cf_start\n"
89        "v_and_b32 v6, v1, v2\n"
90        ".cf_start\n"
91        "v_and_b32 v9, v1, v3\n"
92        ".cf_end\n",
93        {
94            { 0, 20, { }, false, false, true },
95            { 20, 28, { }, false, false, true }
96        },
97        true, ""
98    },
99    {   // 3 - ignore cf_end
100        "v_mov_b32 v1, v2\n"
101        "v_mov_b32 v1, v3\n"
102        ".cf_end\n"
103        "v_mov_b32 v4, v2\n"
104        "v_mov_b32 v8, v3\n"
105        "v_mov_b32 v8, v3\n"
106        ".cf_end\n"
107        ".cf_start\n"
108        "v_and_b32 v9, v1, v3\n"
109        ".cf_end\n",
110        {
111            { 0, 8, { }, false, false, true },
112            { 20, 24, { }, false, false, true }
113        },
114        true, ""
115    },
116    {   /* 4 - cond jump */
117        "v_mov_b32 v1, v2\n"
118        "v_mov_b32 v1, v3\n"
119        "label2:\n"
120        "v_mov_b32 v1, v3\n"
121        "v_mov_b32 v1, v3\n"
122        "s_cbranch_vccz label2\n"
123        "s_xor_b32 s3, s5, s8\n"
124        "s_endpgm\n",
125        {
126            { 0, 8, { }, false, false, false },
127            { 8, 20,
128              { { 1, false }, { 2, false } },
129              false, false, false },
130            { 20, 28, { }, false, false, true }
131        },
132        true, ""
133    },
134    {   /* 5 - jump */
135        "v_mov_b32 v1, v2\n"
136        "v_mov_b32 v1, v3\n"
137        "label2:\n"
138        "v_mov_b32 v1, v3\n"
139        "v_mov_b32 v1, v3\n"
140        "s_branch label2\n"
141        "s_xor_b32 s3, s5, s8\n"
142        "s_endpgm\n",
143        {
144            { 0, 8, { }, false, false, false },
145            { 8, 20,
146              { { 1, false } },
147              false, false, true }
148        },
149        true, ""
150    },
151    {
152        /* 6 - jump */
153        "v_mov_b32 v1, v2\n"
154        "v_mov_b32 v1, v3\n"
155        "lstart:\n"
156        ".cf_jump l0, l1, l2\n"
157        "s_setpc_b64 s[0:1]\n"
158        "l0:\n"
159        "v_add_f32 v1, v2, v3\n"
160        "s_branch lend\n"
161        "l1:\n"
162        "v_add_f32 v1, v2, v3\n"
163        "s_branch lend\n"
164        "l2:\n"
165        "v_add_f32 v1, v2, v3\n"
166        "s_branch lend\n"
167        "lend:\n"
168        "s_cbranch_vccz lstart\n"
169        "s_endpgm\n",
170        {
171            { 0, 8, { }, false, false, false },
172            { 8, 12,
173              { { 2, false }, { 3, false }, { 4, false } },
174              false, false, true },
175            { 12, 20,
176              { { 5, false } },
177              false, false, true },
178            { 20, 28,
179              { { 5, false } },
180              false, false, true },
181            { 28, 36,
182              { { 5, false } },
183              false, false, true },
184            { 36, 40,
185              { { 1, false }, { 6, false } },
186              false, false, false },
187            { 40, 44, { }, false, false, true }
188        },
189        true, ""
190    },
191    {   /* 7 - subroutines */
192        R"ffDXD(
193        v_mov_b32 v1, v2
194        v_mov_b32 v1, v3
195        .cf_call l0, l1, l2
196        s_setpc_b64 s[0:1]
197        v_sub_f32 v1, v3, v6    # 12
198        s_branch j0
199b0:     v_add_u32 v4, vcc, v6, v11  # 20
200        v_mac_f32 v6, v6, v6
201        s_endpgm
202l0:     # 32
203        v_add_f32 v1, v2, v3
204        v_add_f32 v1, v2, v3
205        .cf_ret
206        s_swappc_b64 s[0:1], s[0:1]
207l1:     # 44
208        v_add_f32 v1, v2, v3
209        v_add_f32 v1, v2, v3
210        v_add_f32 v1, v2, v3
211        .cf_ret
212        s_swappc_b64 s[0:1], s[0:1]
213l2:     # 60
214        v_add_f32 v1, v2, v3
215        v_add_f32 v1, v2, v3
216        v_add_f32 v1, v2, v3
217        v_add_f32 v1, v2, v3
218        v_add_f32 v1, v2, v3
219        .cf_ret
220        s_swappc_b64 s[0:1], s[0:1]
221j0:     # 84
222        v_lshrrev_b32 v4, 3, v2
223        v_lshrrev_b32 v4, 3, v2
224        s_branch b0
225)ffDXD",
226        {
227            { 0, 12,
228                { { 3, true }, { 4, true }, { 5, true } },
229                true, false, false },
230            { 12, 20, { { 6, false } }, false, false, true },
231            { 20, 32, { }, false, false, true },
232            { 32, 44, { }, false, true, true },
233            { 44, 60, { }, false, true, true },
234            { 60, 84, { }, false, true, true },
235            { 84, 96, { { 2, false } }, false, false, true }
236        },
237        true, ""
238    },
239    {   /* 8 - subroutines 2 - more complex */
240        R"ffDXD(
241        v_mov_b32 v1, v2    # 0
242        v_mov_b32 v1, v3
243loop:   s_mov_b32 s5, s0    # 8
244        .cf_call c1,c2,c3
245        s_swappc_b64 s[0:1], s[0:1]
246        v_and_b32 v4, v5, v4    # 16
247        v_and_b32 v4, v5, v3
248        v_and_b32 v4, v5, v4
249        .cf_call c5,c6
250        s_swappc_b64 s[0:1], s[0:1]
251        v_and_b32 v4, v5, v3    # 32
252        v_and_b32 v4, v5, v9
253        s_add_i32 s3, s3, s1
254        s_cbranch_vccnz loop
255        v_mac_f32 v4, v6, v7    # 48
256        s_endpgm
257.p2align 4
258c1:     v_xor_b32 v3, v4, v3    # 64
259        v_xor_b32 v3, v4, v7
260        v_xor_b32 v3, v4, v8
261        .cf_ret
262        s_swappc_b64 s[0:1], s[0:1]
263.p2align 4
264c2:     v_xor_b32 v3, v4, v3    # 80
265        v_xor_b32 v3, v4, v7
266c5:     v_xor_b32 v3, v4, v8    # 88
267        .cf_call c4
268        s_swappc_b64 s[0:1], s[0:1]
269        v_or_b32 v3, v11, v9    # 96
270        .cf_ret
271        s_swappc_b64 s[0:1], s[0:1]
272.p2align 4
273c3:     v_xor_b32 v3, v4, v3    # 112
274        v_xor_b32 v3, v4, v8
275        .cf_ret
276        s_swappc_b64 s[0:1], s[0:1]
277.p2align 4
278c4:     v_xor_b32 v3, v4, v3    # 128
279        v_xor_b32 v3, v9, v8
280c6: loop2:
281        v_xor_b32 v3, v9, v8    # 136
282        v_xor_b32 v3, v9, v8
283        s_add_i32 s4, 1, s34
284        s_cbranch_vccz loop2
285        v_lshlrev_b32 v3, 4, v2 # 152
286        .cf_ret
287        s_swappc_b64 s[0:1], s[0:1]
288)ffDXD",
289        {
290            { 0, 8, { }, false, false, false },
291            { 8, 16,
292                { { 5, true }, { 6, true }, { 9, true } },
293                true, false, false },
294            // 2
295            { 16, 32,
296                { { 7, true }, { 11, true } },
297                true, false, false },
298            { 32, 48,
299                { { 1, false }, { 4, false } },
300                false, false, false },
301            // 4
302            { 48, 56, { }, false, false, true },
303            // 5 - c1 subroutine
304            { 64, 80, { }, false, true, true },
305            // 6 - c2 subroutine
306            { 80, 88, { }, false, false, false },
307            { 88, 96, { { 10, true } },
308                true, false, false },
309            { 96, 104, { }, false, true, true },
310            // 9 - c3 subroutine
311            { 112, 124, { }, false, true, true },
312            // 10 - c4 subroutine
313            { 128, 136, { }, false, false, false },
314            { 136, 152,
315                { { 11, false }, { 12, false } },
316                false, false, false },
317            { 152, 160, { }, false, true, true }
318        },
319        true, ""
320    },
321    {   // 9 - switch
322        R"ffDXD(
323            v_mac_f32 v6, v9, v8    # 0
324            v_xor_b32 v3, v9, v8
325            .cf_jump j1, j2, j3, j4
326            s_setpc_b64 s[0:1]
327           
328j1:         v_xor_b32 v3, v9, v8    # 12
329            v_xor_b32 v3, v9, v8
330            v_xor_b32 v3, v9, v8
331            s_branch b0
332
333j2:         v_xor_b32 v3, v9, v8    # 28
334            v_xor_b32 v1, v5, v8
335            v_and_b32 v2, v9, v8
336            v_xor_b32 v3, v9, v8
337            s_branch b0
338
339j3:         v_xor_b32 v3, v9, v8    # 48
340            v_xor_b32 v1, v5, v8
341            s_branch b0
342
343j4:         v_xor_b32 v3, v9, v8    # 60
344            v_xor_b32 v1, v5, v8
345            v_xor_b32 v1, v5, v8
346b0:         s_sub_u32 s0, s1, s2    # 72
347            s_endpgm
348)ffDXD",
349        {
350            { 0, 12,
351                { { 1, false }, { 2, false }, { 3, false }, { 4, false } },
352                false, false, true },
353            { 12, 28, { { 5, false } }, false, false, true },
354            { 28, 48, { { 5, false } }, false, false, true },
355            { 48, 60, { { 5, false } }, false, false, true },
356            { 60, 72, { }, false, false, false },
357            { 72, 80, { }, false, false, true }
358        },
359        true, ""
360    },
361    {   // 10 - multiple kernels
362        R"ffDXD(
363            .cf_start
364            v_mac_f32 v6, v9, v8    # 0
365            v_xor_b32 v3, v9, v8
366            .cf_end
367.p2align 6
368            .cf_start
369            v_xor_b32 v3, v9, v8
370            v_xor_b32 v1, v5, v8
371            v_xor_b32 v1, v5, v8
372            v_xor_b32 v1, v5, v8
373            s_endpgm
374.p2align 6
375            .cf_start       # empty block, ignored
376            .cf_end
377            .cf_start
378            v_xor_b32 v3, v9, v8
379            v_xor_b32 v1, v5, v8
380            v_xor_b32 v3, v9, v8
381            v_or_b32 v3, v9, v8
382            v_or_b32 v3, v9, v8
383            s_endpgm
384            .cf_end
385            .cf_start
386            v_or_b32 v3, v9, v8
387            .cf_end
388            .cf_start   # empty block, ignored
389            .cf_end
390)ffDXD",
391        {
392            { 0, 8, { }, false, false, true },
393            { 64, 84, { }, false, false, true },
394            { 128, 152, { }, false, false, true },
395            { 152, 156, { }, false, false, true }
396        },
397        true, ""
398    },
399    {   // 11 - different type of jumps
400        R"ffDXD(
401            v_mac_f32 v6, v9, v8    # 0
402            v_xor_b32 v3, v9, v8
403            .cf_jump j1, j4
404            .cf_cjump j2, j3
405            s_setpc_b64 s[0:1]
406           
407            v_mov_b32 v5, v3
408            .cf_jump j1, j4
409            .cf_cjump j2, j3
410            s_setpc_b64 s[0:1]
411            .cf_end
412           
413j1:         v_xor_b32 v3, v9, v8    # 20
414            v_xor_b32 v3, v9, v8
415            v_xor_b32 v3, v9, v8
416            s_branch b0
417
418j2:         v_xor_b32 v3, v9, v8    # 36
419            v_xor_b32 v1, v5, v8
420            v_and_b32 v2, v9, v8
421            v_xor_b32 v3, v9, v8
422            s_branch b0
423
424j3:         v_xor_b32 v3, v9, v8    # 56
425            v_xor_b32 v1, v5, v8
426            s_branch b0
427
428j4:         v_xor_b32 v3, v9, v8    # 68
429            v_xor_b32 v1, v5, v8
430            v_xor_b32 v1, v5, v8
431b0:         s_sub_u32 s0, s1, s2    # 80
432            s_endpgm
433)ffDXD",
434        {
435            { 0, 12,
436                { { 1, false }, { 2, false }, { 3, false },
437                  { 4, false }, { 5, false } },
438                false, false, false },
439            { 12, 20,
440                { { 2, false }, { 3, false }, { 4, false }, { 5, false } },
441                false, false, true }, // have cf_end, force haveEnd
442            { 20, 36, { { 6, false } }, false, false, true },
443            { 36, 56, { { 6, false } }, false, false, true },
444            { 56, 68, { { 6, false } }, false, false, true },
445            { 68, 80, { }, false, false, false },
446            { 80, 88, { }, false, false, true }
447        },
448        true, ""
449    },
450    {   // 12 - many jumps to same place
451        R"ffDXD(
452            v_mac_f32 v6, v9, v8    # 0
453            v_xor_b32 v3, v9, v8
454            s_cbranch_vccz j1
455            v_mov_b32 v4, v3        # 12
456            v_mov_b32 v4, v3
457            s_cbranch_execz j1
458            v_mov_b32 v4, v3        # 24
459            v_mov_b32 v4, v3
460            s_cbranch_execnz b0
461            s_branch j2             # 36
462b0:         v_mov_b32 v4, v3        # 40
463            v_mov_b32 v5, v3
464            v_mov_b32 v5, v4
465            s_branch j2
466j1:         v_max_u32 v4, v1, v6    # 56
467            s_endpgm
468j2:         v_min_i32 v4, v1, v6    # 64
469            v_min_i32 v3, v1, v6
470            .cf_call c1
471            s_swappc_b64 s[0:1], s[0:1]
472            v_min_i32 v3, v1, v6    # 76
473            .cf_call c1
474            s_swappc_b64 s[0:1], s[0:1]
475            v_min_i32 v3, v1, v6    # 84
476            s_endpgm
477c1:         v_add_f32 v6, v1, v4    # 92
478            v_add_f32 v6, v1, v4
479            .cf_ret
480            s_swappc_b64 s[0:1], s[0:1]
481)ffDXD",
482        {
483            { 0, 12,
484                { { 1, false }, { 5, false } },
485                false, false, false },
486            { 12, 24,
487                { { 2, false }, { 5, false } },
488                false, false, false },
489            { 24, 36,
490                { { 3, false }, { 4, false } },
491                false, false, false },
492            { 36, 40, { { 6, false } }, false, false, true },
493            { 40, 56, { { 6, false } }, false, false, true },
494            // 5
495            { 56, 64, { }, false, false, true },
496            { 64, 76,
497                { { 9, true } },
498                true, false, false },
499            { 76, 84,
500                { { 9, true } },
501                true, false, false },
502            { 84, 92, { }, false, false, true },
503            // 9 - subroutine
504            { 92, 104, { }, false, true, true }
505        },
506        true, ""
507    },
508    {   /* 13 - subroutines 2 (one is jump) */
509        R"ffDXD(
510        v_mov_b32 v1, v2
511        v_mov_b32 v1, v3
512        .cf_call l0, l1
513        .cf_jump l2
514        s_setpc_b64 s[0:1]
515        v_sub_f32 v1, v3, v6    # 12
516        s_branch j0
517b0:     v_add_u32 v4, vcc, v6, v11  # 20
518        v_mac_f32 v6, v6, v6
519        s_endpgm
520l0:     # 32
521        v_add_f32 v1, v2, v3
522        v_add_f32 v1, v2, v3
523        .cf_ret
524        s_swappc_b64 s[0:1], s[0:1]
525l1:     # 44
526        v_add_f32 v1, v2, v3
527        v_add_f32 v1, v2, v3
528        v_add_f32 v1, v2, v3
529        .cf_ret
530        s_swappc_b64 s[0:1], s[0:1]
531l2:     # 60
532        v_add_f32 v1, v2, v3
533        v_add_f32 v1, v2, v3
534        v_add_f32 v1, v2, v3
535        v_add_f32 v1, v2, v3
536        v_add_f32 v1, v2, v3
537        .cf_ret
538        s_swappc_b64 s[0:1], s[0:1]
539j0:     # 84
540        v_lshrrev_b32 v4, 3, v2
541        v_lshrrev_b32 v4, 3, v2
542        s_branch b0
543)ffDXD",
544        {
545            { 0, 12,
546                { { 5, false }, { 3, true }, { 4, true } },
547                true, false, true },
548            { 12, 20, { { 6, false } }, false, false, true },
549            { 20, 32, { }, false, false, true },
550            { 32, 44, { }, false, true, true },
551            { 44, 60, { }, false, true, true },
552            { 60, 84, { }, false, true, true },
553            { 84, 96, { { 2, false } }, false, false, true }
554        },
555        true, ""
556    },
557    {   /* 14 - empty */
558        ".regvar sa:s:8, va:v:12, vb:v:10\n",
559        { },
560        true, ""
561    },
562    {   // 15 - switch (empty block at end)
563        R"ffDXD(
564            v_mac_f32 v6, v9, v8    # 0
565            v_xor_b32 v3, v9, v8
566            .cf_jump j1, j2, j3, j4
567            s_setpc_b64 s[0:1]
568           
569j1:         v_xor_b32 v3, v9, v8    # 12
570            v_xor_b32 v3, v9, v8
571            v_xor_b32 v3, v9, v8
572            s_branch b0
573
574j2:         v_xor_b32 v3, v9, v8    # 28
575            v_xor_b32 v1, v5, v8
576            v_and_b32 v2, v9, v8
577            v_xor_b32 v3, v9, v8
578            s_branch b0
579
580j3:         v_xor_b32 v3, v9, v8    # 48
581            v_xor_b32 v1, v5, v8
582            s_branch b0
583
584j4:         v_xor_b32 v3, v9, v8    # 60
585            v_xor_b32 v1, v5, v8
586            v_xor_b32 v1, v5, v8
587b0:         # 72
588)ffDXD",
589        {
590            { 0, 12,
591                { { 1, false }, { 2, false }, { 3, false }, { 4, false } },
592                false, false, true },
593            { 12, 28, { { 5, false } }, false, false, true },
594            { 28, 48, { { 5, false } }, false, false, true },
595            { 48, 60, { { 5, false } }, false, false, true },
596            { 60, 72, { }, false, false, false },
597            { 72, 72, { }, false, false, true }
598        },
599        true, ""
600    }
601};
602
603static void testCreateCodeStructure(cxuint i, const AsmCodeStructCase& testCase)
604{
605    std::istringstream input(testCase.input);
606    std::ostringstream errorStream;
607   
608    Assembler assembler("test.s", input, ASM_ALL&~ASM_ALTMACRO,
609                    BinaryFormat::RAWCODE, GPUDeviceType::CAPE_VERDE, errorStream);
610    bool good = assembler.assemble();
611   
612    if (assembler.getSections().size()<1)
613    {
614        std::ostringstream oss;
615        oss << "FAILED for " << " testAsmCodeStructCase#" << i;
616        throw Exception(oss.str());
617    }
618    const AsmSection& section = assembler.getSections()[0];
619   
620    AsmRegAllocator regAlloc(assembler);
621   
622    regAlloc.createCodeStructure(section.codeFlow, section.getSize(),
623                            section.content.data());
624    const std::vector<CodeBlock>& resCodeBlocks = regAlloc.getCodeBlocks();
625    std::ostringstream oss;
626    oss << " testAsmCodeStructCase#" << i;
627    const std::string testCaseName = oss.str();
628    assertValue<bool>("testAsmCodeStruct", testCaseName+".good",
629                      testCase.good, good);
630    assertString("testAsmCodeStruct", testCaseName+".errorMessages",
631              testCase.errorMessages, errorStream.str());
632   
633    assertValue("testAsmCodeStruct", testCaseName+".codeBlocks.size",
634                testCase.codeBlocks.size(), resCodeBlocks.size());
635   
636    for (size_t j = 0; j < resCodeBlocks.size(); j++)
637    {
638        const CCodeBlock& expCBlock = testCase.codeBlocks[j];
639        const CodeBlock& resCBlock = resCodeBlocks[j];
640        std::ostringstream codeBlockOss;
641        codeBlockOss << ".codeBlock#" << j << ".";
642        codeBlockOss.flush();
643        std::string cbname(codeBlockOss.str());
644        assertValue("testAsmCodeStruct", testCaseName + cbname + "start",
645                    expCBlock.start, resCBlock.start);
646        assertValue("testAsmCodeStruct", testCaseName + cbname + "end",
647                    expCBlock.end, resCBlock.end);
648        assertValue("testAsmCodeStruct", testCaseName + cbname + "nextsSize",
649                    expCBlock.nexts.size(), resCBlock.nexts.size());
650       
651        for (size_t k = 0; k < expCBlock.nexts.size(); k++)
652        {
653            std::ostringstream nextOss;
654            nextOss << "next#" << k << ".";
655            nextOss.flush();
656            std::string nname(nextOss.str());
657           
658            assertValue("testAsmCodeStruct", testCaseName + cbname + nname + "block",
659                    expCBlock.nexts[k].block, resCBlock.nexts[k].block);
660            assertValue("testAsmCodeStruct", testCaseName + cbname + nname + "isCall",
661                    int(expCBlock.nexts[k].isCall), int(resCBlock.nexts[k].isCall));
662        }
663       
664        assertValue("testAsmCodeStruct", testCaseName + cbname + "haveCalls",
665                    int(expCBlock.haveCalls), int(resCBlock.haveCalls));
666        assertValue("testAsmCodeStruct", testCaseName + cbname + "haveReturn",
667                    int(expCBlock.haveReturn), int(resCBlock.haveReturn));
668        assertValue("testAsmCodeStruct", testCaseName + cbname + "haveEnd",
669                    int(expCBlock.haveEnd), int(resCBlock.haveEnd));
670    }
671}
672
673typedef AsmRegAllocator::SSAInfo SSAInfo;
674typedef AsmRegAllocator::SSAReplace SSAReplace;
675typedef AsmRegAllocator::SSAReplacesMap SSAReplacesMap;
676
677struct TestSingleVReg
678{
679    CString name;
680    uint16_t index;
681   
682    bool operator==(const TestSingleVReg& b) const
683    { return name==b.name && index==b.index; }
684    bool operator!=(const TestSingleVReg& b) const
685    { return name!=b.name || index!=b.index; }
686    bool operator<(const TestSingleVReg& b) const
687    { return name<b.name || (name==b.name && index<b.index); }
688};
689
690struct TestSingleVReg2
691{
692    const char* name;
693    uint16_t index;
694};
695
696std::ostream& operator<<(std::ostream& os, const TestSingleVReg& vreg)
697{
698    if (!vreg.name.empty())
699        os << vreg.name << "[" << vreg.index << "]";
700    else
701        os << "@REG[" << vreg.index << "]";
702    return os;
703}
704
705struct CCodeBlock2
706{
707    size_t start, end; // place in code
708    Array<NextBlock> nexts; ///< nexts blocks
709    Array<std::pair<TestSingleVReg2, SSAInfo> > ssaInfos;
710    bool haveCalls;
711    bool haveReturn;
712    bool haveEnd;
713};
714
715struct AsmSSADataCase
716{
717    const char* input;
718    Array<CCodeBlock2> codeBlocks;
719    Array<std::pair<TestSingleVReg2, Array<SSAReplace> > > ssaReplaces;
720    bool good;
721    const char* errorMessages;
722};
723
724static const AsmSSADataCase ssaDataTestCases1Tbl[] =
725{
726    {   /* 0 - simple */
727        ".regvar sa:s:8, va:v:10\n"
728        "s_mov_b32 sa[4], sa[2]\n"
729        "s_add_u32 sa[4], sa[2], s3\n"
730        "ds_read_b64 va[4:5], v0\n"
731        "v_add_f64 va[0:1], va[4:5], va[2:3]\n"
732        "v_mac_f32 va[0], va[4], va[5]\n"  // ignore this write, because also read
733        "v_mul_f32 va[1], va[4], va[5]\n"
734        "ds_read_b32 v10, v0\n"
735        "v_mul_lo_u32 v10, va[2], va[3]\n"
736        "v_mul_lo_u32 v10, va[2], va[3]\n",
737        {
738            { 0, 56, { },
739                {
740                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
741                    { { "", 256 }, SSAInfo(0, 0, 0, 0, 0, true) },
742                    { { "", 266 }, SSAInfo(0, 0, 0, 0, 0, false) },
743                    { { "sa", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
744                    { { "sa", 4 }, SSAInfo(0, 1, 1, 2, 2, false) },
745                    { { "va", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
746                    { { "va", 1 }, SSAInfo(0, 1, 1, 2, 2, false) },
747                    { { "va", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
748                    { { "va", 3 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
749                    { { "va", 4 }, SSAInfo(0, 1, 1, 1, 1, false) },
750                    { { "va", 5 }, SSAInfo(0, 1, 1, 1, 1, false) }
751                }, false, false, true }
752        },
753        { },
754        true, ""
755    },
756    {   /* 1 - tree */
757        R"ffDXD(.regvar sa:s:8, va:v:10
758        s_mov_b32 sa[4], sa[2]  # 0
759        s_add_u32 sa[4], sa[2], s3
760        ds_read_b64 va[4:5], v0
761        v_add_f64 va[0:1], va[4:5], va[2:3]
762        v_add_f64 va[0:1], va[4:5], va[2:3]
763        v_add_f64 va[0:1], va[4:5], va[2:3]
764        .cf_jump j1,j2,j3
765        s_setpc_b64 s[0:1]
766        # 44
767j1:     v_add_f32 va[5], va[2], va[3]
768        v_mov_b32 va[6], va[2]
769        s_endpgm
770j2:     v_add_f32 va[3], va[2], va[5]
771        v_add_f32 va[6], va[2], va[3]
772        s_endpgm
773j3:     v_add_f32 va[2], va[5], va[3]
774        s_endpgm
775)ffDXD",
776        {
777            { 0, 44,
778                { { 1, false }, { 2, false }, { 3, false } },
779                {
780                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
781                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
782                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
783                    { { "", 256 }, SSAInfo(0, 0, 0, 0, 0, true) },
784                    { { "sa", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
785                    { { "sa", 4 }, SSAInfo(0, 1, 1, 2, 2, false) },
786                    { { "va", 0 }, SSAInfo(0, 1, 1, 3, 3, false) },
787                    { { "va", 1 }, SSAInfo(0, 1, 1, 3, 3, false) },
788                    { { "va", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
789                    { { "va", 3 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
790                    { { "va", 4 }, SSAInfo(0, 1, 1, 1, 1, false) },
791                    { { "va", 5 }, SSAInfo(0, 1, 1, 1, 1, false) }
792                }, false, false, true },
793            { 44, 56, { },
794                {
795                    { { "va", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
796                    { { "va", 3 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
797                    { { "va", 5 }, SSAInfo(1, 2, 2, 2, 1, false) },
798                    { { "va", 6 }, SSAInfo(0, 1, 1, 1, 1, false) }
799                }, false, false, true },
800            { 56, 68, { },
801                {
802                    { { "va", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
803                    { { "va", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
804                    { { "va", 5 }, SSAInfo(1, SIZE_MAX, 3, SIZE_MAX, 0, true) },
805                    { { "va", 6 }, SSAInfo(0, 2, 2, 2, 1, false) }
806                }, false, false, true },
807            { 68, 76, { },
808                {
809                    { { "va", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
810                    { { "va", 3 }, SSAInfo(0, SIZE_MAX, 2, SIZE_MAX, 0, true) },
811                    { { "va", 5 }, SSAInfo(1, SIZE_MAX, 3, SIZE_MAX, 0, true) }
812                }, false, false, true },
813        },
814        { },
815        true, ""
816    },
817    {   /* 2 - tree (align) */
818        R"ffDXD(.regvar sa:s:8, va:v:10
819        s_mov_b32 sa[4], sa[2]  # 0
820        s_add_u32 sa[4], sa[2], s3
821        ds_read_b64 va[4:5], v0
822        v_add_f64 va[0:1], va[4:5], va[2:3]
823        v_add_f64 va[0:1], va[4:5], va[2:3]
824        v_add_f64 va[0:1], va[4:5], va[2:3]
825        .cf_jump j1,j2,j3
826        s_setpc_b64 s[0:1]
827.p2align 6
828        # 64
829j1:     v_add_f32 va[5], va[2], va[3]
830        v_mov_b32 va[6], va[2]
831        s_endpgm
832j2:     v_add_f32 va[3], va[2], va[5]
833        v_add_f32 va[6], va[2], va[3]
834        s_endpgm
835j3:     v_add_f32 va[2], va[5], va[3]
836        s_endpgm
837)ffDXD",
838        {
839            { 0, 44,
840                { { 1, false }, { 2, false }, { 3, false } },
841                {
842                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
843                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
844                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
845                    { { "", 256 }, SSAInfo(0, 0, 0, 0, 0, true) },
846                    { { "sa", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
847                    { { "sa", 4 }, SSAInfo(0, 1, 1, 2, 2, false) },
848                    { { "va", 0 }, SSAInfo(0, 1, 1, 3, 3, false) },
849                    { { "va", 1 }, SSAInfo(0, 1, 1, 3, 3, false) },
850                    { { "va", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
851                    { { "va", 3 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
852                    { { "va", 4 }, SSAInfo(0, 1, 1, 1, 1, false) },
853                    { { "va", 5 }, SSAInfo(0, 1, 1, 1, 1, false) }
854                }, false, false, true },
855            { 64, 76, { },
856                {
857                    { { "va", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
858                    { { "va", 3 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
859                    { { "va", 5 }, SSAInfo(1, 2, 2, 2, 1, false) },
860                    { { "va", 6 }, SSAInfo(0, 1, 1, 1, 1, false) }
861                }, false, false, true },
862            { 76, 88, { },
863                {
864                    { { "va", 2 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
865                    { { "va", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
866                    { { "va", 5 }, SSAInfo(1, SIZE_MAX, 3, SIZE_MAX, 0, true) },
867                    { { "va", 6 }, SSAInfo(0, 2, 2, 2, 1, false) }
868                }, false, false, true },
869            { 88, 96, { },
870                {
871                    { { "va", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
872                    { { "va", 3 }, SSAInfo(0, SIZE_MAX, 2, SIZE_MAX, 0, true) },
873                    { { "va", 5 }, SSAInfo(1, SIZE_MAX, 3, SIZE_MAX, 0, true) }
874                }, false, false, true },
875        },
876        { },
877        true, ""
878    },
879    {   /* 3 - longer tree (more blocks) */
880        R"ffDXD(.regvar sa:s:8, va:v:12, vb:v:10
881        # 0
882        ds_read_b64 v[2:3], v0
883        ds_read_b64 v[4:5], v0
884        v_mov_b32 va[0], v1
885        v_mul_f32 va[1], v0, v1
886        .cf_cjump tx1, tx2, tx3
887        s_setpc_b64 s[0:1]
888        # 28
889        v_mul_lo_u32 va[2], va[0], va[1]
890        v_mul_hi_u32 va[3], va[0], va[1]
891        v_lshrrev_b32 va[4], v2, va[5]
892        .cf_cjump ux1, ux2, ux3
893        s_setpc_b64 s[0:1]
894        # 52
895        v_mul_u32_u24 va[2], va[0], va[1]
896        v_mul_hi_u32_u24 va[3], va[0], va[1]
897        v_lshlrev_b32 va[5], v3, va[4]
898        .cf_cjump vx1, vx2, vx3
899        s_setpc_b64 s[0:1]
900        # 68
901        v_mul_lo_i32 va[2], va[0], va[1]
902        v_mul_hi_i32 va[3], va[0], va[1]
903        v_ashrrev_i32 va[6], v4, va[4]
904        .cf_jump wx1, wx2, wx3
905        s_setpc_b64 s[0:1]
906       
907.p2align 4
908        # 96
909tx1:    v_min_f32 vb[0], va[0], va[1]
910        v_madak_f32 vb[5], vb[0], va[1], 2.5
911        s_endpgm
912ux1:    v_nop
913        s_endpgm
914vx1:    v_add_f32 va[9], v11, vb[4]
915        s_endpgm
916wx1:    v_add_f32 va[10], v11, vb[4]
917        s_endpgm
918.p2align 4
919tx2:    v_max_f32 vb[1], va[0], va[1]
920        v_madak_f32 va[3], va[0], va[1], 2.5
921        s_endpgm
922ux2:    v_nop
923        s_nop 7
924        s_endpgm
925vx2:    v_nop
926        s_endpgm
927wx2:    v_add_f32 va[8], v19, vb[5]
928        s_endpgm
929.p2align 4
930tx3:    v_max_u32 vb[2], va[0], va[1]
931        v_madmk_f32 vb[3], va[0], 1.23, vb[1]
932        s_endpgm
933ux3:    v_add_f32 va[7], v11, vb[5]
934        s_endpgm
935vx3:    v_add_f32 va[6], v13, vb[5]
936        s_endpgm
937wx3:    v_nop
938        s_endpgm
939)ffDXD",
940        {
941            { 0, 28,
942                { { 1, false }, { 4, false }, { 8, false }, { 12, false } },
943                {
944                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
945                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
946                    { { "", 256 }, SSAInfo(0, 0, 0, 0, 0, true) },
947                    { { "", 256+1 }, SSAInfo(0, 0, 0, 0, 0, true) },
948                    { { "", 256+2 }, SSAInfo(0, 0, 0, 0, 0, false) },
949                    { { "", 256+3 }, SSAInfo(0, 0, 0, 0, 0, false) },
950                    { { "", 256+4 }, SSAInfo(0, 0, 0, 0, 0, false) },
951                    { { "", 256+5 }, SSAInfo(0, 0, 0, 0, 0, false) },
952                    { { "va", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
953                    { { "va", 1 }, SSAInfo(0, 1, 1, 1, 1, false) }
954                }, false, false, false },
955            { 28, 52,
956                { { 2, false }, { 5, false }, { 9, false }, { 13, false } },
957                {
958                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
959                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
960                    { { "", 256+2 }, SSAInfo(0, 0, 0, 0, 0, true) },
961                    { { "va", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
962                    { { "va", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
963                    { { "va", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
964                    { { "va", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
965                    { { "va", 4 }, SSAInfo(0, 1, 1, 1, 1, false) },
966                    { { "va", 5 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
967                }, false, false, false },
968            { 52, 68,
969                { { 3, false }, { 6, false }, { 10, false }, { 14, false } },
970                {
971                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
972                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
973                    { { "", 256+3, }, SSAInfo(0, 0, 0, 0, 0, true) },
974                    { { "va", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
975                    { { "va", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
976                    { { "va", 2 }, SSAInfo(1, 2, 2, 2, 1, false) },
977                    { { "va", 3 }, SSAInfo(1, 2, 2, 2, 1, false) },
978                    { { "va", 4 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
979                    { { "va", 5 }, SSAInfo(0, 1, 1, 1, 1, false) }
980                }, false, false, false },
981            { 68, 92,
982                { { 7, false }, { 11, false }, { 15, false } },
983                {
984                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
985                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
986                    { { "", 256+4 }, SSAInfo(0, 0, 0, 0, 0, true) },
987                    { { "va", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
988                    { { "va", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
989                    { { "va", 2 }, SSAInfo(2, 3, 3, 3, 1, false) },
990                    { { "va", 3 }, SSAInfo(2, 3, 3, 3, 1, false) },
991                    { { "va", 4 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
992                    { { "va", 6 }, SSAInfo(0, 1, 1, 1, 1, false) }
993                }, false, false, true },
994            // 4-7:
995            { 96, 112,
996                { },
997                {
998                    { { "va", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
999                    { { "va", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1000                    { { "vb", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
1001                    { { "vb", 5 }, SSAInfo(0, 1, 1, 1, 1, false) }
1002                }, false, false, true },
1003            { 112, 120,
1004                { },
1005                { }, false, false, true },
1006            { 120, 128,
1007                { },
1008                {
1009                    { { "", 256+11 }, SSAInfo(0, 0, 0, 0, 0, true) },
1010                    { { "va", 9 }, SSAInfo(0, 1, 1, 1, 1, false) },
1011                    { { "vb", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
1012                }, false, false, true },
1013            { 128, 136,
1014                { },
1015                {
1016                    { { "", 256+11 }, SSAInfo(0, 0, 0, 0, 0, true) },
1017                    { { "va", 10 }, SSAInfo(0, 1, 1, 1, 1, false) },
1018                    { { "vb", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
1019                }, false, false, true },
1020            // 8-11
1021            { 144, 160,
1022                { },
1023                {
1024                    { { "va", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1025                    { { "va", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1026                    { { "va", 3 }, SSAInfo(0, 4, 4, 4, 1, false) },
1027                    { { "vb", 1 }, SSAInfo(0, 1, 1, 1, 1, false) }
1028                }, false, false, true },
1029            { 160, 172,
1030                { },
1031                { }, false, false, true },
1032            { 172, 180,
1033                { },
1034                { }, false, false, true },
1035            { 180, 188,
1036                { },
1037                {
1038                    { { "", 256+19 }, SSAInfo(0, 0, 0, 0, 0, true) },
1039                    { { "va", 8 }, SSAInfo(0, 1, 1, 1, 1, false) },
1040                    { { "vb", 5 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
1041                }, false, false, true },
1042            // 12-15
1043            { 192, 208,
1044                { },
1045                {
1046                    { { "va", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1047                    { { "va", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1048                    { { "vb", 1 }, SSAInfo(0, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1049                    { { "vb", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
1050                    { { "vb", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
1051                }, false, false, true },
1052            { 208, 216,
1053                { },
1054                {
1055                    { { "", 256+11 }, SSAInfo(0, 0, 0, 0, 0, true) },
1056                    { { "va", 7 }, SSAInfo(0, 1, 1, 1, 1, false) },
1057                    { { "vb", 5 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
1058                }, false, false, true },
1059            { 216, 224,
1060                { },
1061                {
1062                    { { "", 256+13 }, SSAInfo(0, 0, 0, 0, 0, true) },
1063                    { { "va", 6 }, SSAInfo(0, 2, 2, 2, 1, false) },
1064                    { { "vb", 5 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
1065                }, false, false, true },
1066            { 224, 232,
1067                { },
1068                { }, false, false, true }
1069        },
1070        { },
1071        true, ""
1072    },
1073    {   /* 4 - empty! */
1074        ".regvar sa:s:8, va:v:12, vb:v:10\n",
1075        { },
1076        { },
1077        true, ""
1078    },
1079    {   /* 5 - longer blocks (tree) */
1080        R"ffDXD(.regvar sa:s:8, va:v:12, vb:v:10
1081        # block 0, offset - 0
1082        s_mov_b32 s0, 0x11
1083        s_mov_b32 s1, 0x11
1084        s_mov_b64 s[2:3], 3344
1085        v_mov_b32 v1, v0
1086        v_add_f32 v2, v1, v0
1087        v_and_b32 v1, v1, v2
1088       
1089        s_mov_b32 sa[0], 1
1090        s_mov_b32 sa[1], 1
1091        s_mov_b32 sa[2], 1
1092        s_mov_b32 sa[3], 1
1093       
1094.rept 4
1095        s_xor_b32 sa[0], sa[1], sa[3]
1096        s_and_b32 sa[1], sa[2], sa[3]
1097        s_xor_b32 sa[3], sa[0], sa[2]
1098        s_xor_b32 sa[2], sa[1], sa[3]
1099.endr
1100        s_and_b32 sa[1], sa[2], sa[3]
1101        s_xor_b32 sa[2], sa[1], sa[3]
1102        s_xor_b32 sa[2], sa[1], sa[3]
1103       
1104        .cf_jump b1, b2
1105        s_setpc_b64 s[4:5]
1106       
1107        # block 1, offset - 124
1108b1:     s_add_u32 s4, s1, sa[2]
1109        s_add_u32 sa[4], s2, sa[3]
1110       
1111        s_mov_b32 sa[6], s[4]
1112.rept 3
1113        s_xor_b32 sa[0], sa[6], sa[3]
1114        s_and_b32 sa[5], sa[2], sa[3]
1115        s_and_b32 sa[6], sa[0], sa[5]
1116.endr
1117        .cf_jump b11, b12
1118        s_setpc_b64 s[6:7]
1119       
1120        # block 2, offset - 176
1121b2:     v_mul_lo_u32 va[1], va[1], va[4]
1122        v_mul_lo_u32 va[2], sa[1], va[1]
1123        v_mov_b32 va[3], 2343
1124.rept 3
1125        v_mul_lo_u32 va[3], sa[1], va[3]
1126        v_mul_lo_u32 va[1], sa[0], va[4]
1127        v_mul_lo_u32 va[2], sa[2], va[1]
1128.endr
1129.rept 4
1130        v_mul_lo_u32 va[1], sa[0], va[4]
1131.endr
1132.rept 2
1133        v_mul_lo_u32 va[2], v1, v4
1134.endr
1135        v_and_b32 v3, v3, v2
1136        s_endpgm
1137       
1138        # block 2, offset - xx
1139b11:    v_mov_b32 va[0], 122
1140        v_mov_b32 va[1], 122
1141        v_mov_b32 va[2], 122
1142.rept 4
1143        v_xor_b32 va[0], va[1], v2
1144        v_xor_b32 va[1], va[1], v1
1145        v_xor_b32 va[2], sa[2], va[1]
1146.endr
1147        v_xor_b32 va[1], sa[1], v0
1148        s_xor_b32 sa[1], sa[2], s3
1149        s_endpgm
1150       
1151        # block 3, offset - xx
1152b12:    v_mov_b32 va[4], 122
1153        v_xor_b32 va[1], 112, va[1]
1154        v_xor_b32 va[0], v2, va[0]
1155.rept 5
1156        v_xor_b32 va[0], va[1], v2
1157        v_xor_b32 va[1], va[0], v0
1158        v_xor_b32 va[4], sa[3], va[4]
1159.endr
1160        v_xor_b32 va[4], sa[2], v0
1161        s_xor_b32 sa[1], sa[3], s3
1162        s_endpgm
1163)ffDXD",
1164        {
1165            { 0, 124,
1166                { { 1, false }, { 2, false } },
1167                {
1168                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
1169                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
1170                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
1171                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
1172                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
1173                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
1174                    { { "", 256+0 }, SSAInfo(0, 0, 0, 0, 0, true) },
1175                    { { "", 256+1 }, SSAInfo(0, 0, 0, 0, 0, false) },
1176                    { { "", 256+2 }, SSAInfo(0, 0, 0, 0, 0, false) },
1177                    { { "sa", 0 }, SSAInfo(0, 1, 1, 5, 5, false) },
1178                    { { "sa", 1 }, SSAInfo(0, 1, 1, 6, 6, false) },
1179                    { { "sa", 2 }, SSAInfo(0, 1, 1, 7, 7, false) },
1180                    { { "sa", 3 }, SSAInfo(0, 1, 1, 5, 5, false) }
1181                }, false, false, true },
1182            // block 1
1183            { 124, 176,
1184                { { 3, false }, { 4, false } },
1185                {
1186                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1187                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1188                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, false) },
1189                    { { "", 6 }, SSAInfo(0, 0, 0, 0, 0, true) },
1190                    { { "", 7 }, SSAInfo(0, 0, 0, 0, 0, true) },
1191                    { { "sa", 0 }, SSAInfo(5, 6, 6, 8, 3, false) },
1192                    { { "sa", 2 }, SSAInfo(7, SIZE_MAX, 8, SIZE_MAX, 0, true) },
1193                    { { "sa", 3 }, SSAInfo(5, SIZE_MAX, 6, SIZE_MAX, 0, true) },
1194                    { { "sa", 4 }, SSAInfo(0, 1, 1, 1, 1, false) },
1195                    { { "sa", 5 }, SSAInfo(0, 1, 1, 3, 3, false) },
1196                    { { "sa", 6 }, SSAInfo(0, 1, 1, 4, 4, false) }
1197                }, false, false, true },
1198            // block 2
1199            { 176, 328,
1200                { },
1201                {
1202                    { { "", 256+1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1203                    { { "", 256+2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1204                    { { "", 256+3 }, SSAInfo(0, 0, 0, 0, 0, true) },
1205                    { { "", 256+4 }, SSAInfo(0, 0, 0, 0, 0, true) },
1206                    { { "sa", 0 }, SSAInfo(5, SIZE_MAX, 9, SIZE_MAX, 0, true) },
1207                    { { "sa", 1 }, SSAInfo(6, SIZE_MAX, 9, SIZE_MAX, 0, true) },
1208                    { { "sa", 2 }, SSAInfo(7, SIZE_MAX, 8, SIZE_MAX, 0, true) },
1209                    { { "va", 1 }, SSAInfo(0, 13, 13, 20, 8, true) },
1210                    { { "va", 2 }, SSAInfo(0, 6, 6, 11, 6, false) },
1211                    { { "va", 3 }, SSAInfo(0, 1, 1, 4, 4, false) },
1212                    { { "va", 4 }, SSAInfo(0, SIZE_MAX, 8, SIZE_MAX, 0, true) },
1213                }, false, false, true },
1214            // block 3
1215            { 328, 412,
1216                { },
1217                {
1218                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
1219                    { { "", 256 }, SSAInfo(0, 0, 0, 0, 0, true) },
1220                    { { "", 256+1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1221                    { { "", 256+2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1222                    { { "sa", 1 }, SSAInfo(6, 7, 7, 7, 1, true) },
1223                    { { "sa", 2 }, SSAInfo(7, SIZE_MAX, 8, SIZE_MAX, 0, true) },
1224                    { { "va", 0 }, SSAInfo(0, 1, 1, 5, 5, false) },
1225                    { { "va", 1 }, SSAInfo(0, 1, 1, 6, 6, false) },
1226                    { { "va", 2 }, SSAInfo(0, 1, 1, 5, 5, false) }
1227                }, false, false, true },
1228            // block 4
1229            { 412, 504,
1230                { },
1231                {
1232                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
1233                    { { "", 256 }, SSAInfo(0, 0, 0, 0, 0, true) },
1234                    { { "", 256+2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1235                    { { "sa", 1 }, SSAInfo(6, 8, 8, 8, 1, false) },
1236                    { { "sa", 2 }, SSAInfo(7, SIZE_MAX, 8, SIZE_MAX, 0, true) },
1237                    { { "sa", 3 }, SSAInfo(5, SIZE_MAX, 6, SIZE_MAX, 0, true) },
1238                    { { "va", 0 }, SSAInfo(0, 6, 6, 11, 6, true) },
1239                    { { "va", 1 }, SSAInfo(0, 7, 7, 12, 6, true) },
1240                    { { "va", 4 }, SSAInfo(0, 1, 1, 7, 7, false) }
1241                }, false, false, true }
1242        },
1243        { },
1244        true, ""
1245    },
1246    {   // 6 - simple loop
1247        R"ffDXD(.regvar sa:s:8, va:v:8
1248        s_mov_b32 sa[0], 0
1249        s_mov_b32 sa[1], s10
1250        v_mov_b32 va[0], v0
1251        v_mov_b32 va[1], v1
1252        v_mov_b32 va[3], 0
1253        v_mov_b32 va[4], 11
1254loop:
1255        ds_read_b32 va[2], va[3]
1256        v_xor_b32 va[0], va[1], va[2]
1257        v_not_b32 va[0], va[0]
1258        v_xor_b32 va[0], 0xfff, va[0]
1259        v_xor_b32 va[4], va[4], va[2]
1260        v_not_b32 va[4], va[0]
1261        v_xor_b32 va[4], 0xfff, va[0]
1262        v_add_u32 va[1], vcc, 1001, va[1]
1263       
1264        s_add_u32 sa[0], sa[0], 1
1265        s_cmp_lt_u32 sa[0], sa[1]
1266        s_cbranch_scc1 loop
1267       
1268        v_xor_b32 va[0], 33, va[0]
1269        s_add_u32 sa[0], 14, sa[0]
1270        s_endpgm
1271)ffDXD",
1272        {
1273            { 0, 24,
1274                { },
1275                {
1276                    { { "", 10 }, SSAInfo(0, 0, 0, 0, 0, true) },
1277                    { { "", 256 }, SSAInfo(0, 0, 0, 0, 0, true) },
1278                    { { "", 256+1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1279                    { { "sa", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
1280                    { { "sa", 1 }, SSAInfo(0, 1, 1, 1, 1, false) },
1281                    { { "va", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
1282                    { { "va", 1 }, SSAInfo(0, 1, 1, 1, 1, false) },
1283                    { { "va", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
1284                    { { "va", 4 }, SSAInfo(0, 1, 1, 1, 1, false) }
1285                }, false, false, false },
1286            { 24, 84,
1287                { { 1, false }, { 2, false } },
1288                {
1289                    { { "sa", 0 }, SSAInfo(1, 2, 2, 2, 1, true) },
1290                    { { "sa", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1291                    { { "va", 0 }, SSAInfo(1, 2, 2, 4, 3, false) },
1292                    { { "va", 1 }, SSAInfo(1, 2, 2, 2, 1, true) },
1293                    { { "va", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
1294                    { { "va", 3 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1295                    { { "va", 4 }, SSAInfo(1, 2, 2, 4, 3, true) }
1296                }, false, false, false },
1297            { 84, 96,
1298                { },
1299                {
1300                    { { "sa", 0 }, SSAInfo(2, 3, 3, 3, 1, true) },
1301                    { { "va", 0 }, SSAInfo(4, 5, 5, 5, 1, true) }
1302                }, false, false, true, }
1303        },
1304        {   // SSA replaces
1305            { { "sa", 0 }, { { 2, 1 } } },
1306            { { "va", 1 }, { { 2, 1 } } },
1307            { { "va", 4 }, { { 4, 1 } } }
1308        },
1309        true, ""
1310    },
1311    {   // 7 - branches
1312        R"ffDXD(.regvar sa:s:8, va:v:8
1313        # block 0
1314        s_mov_b32 sa[0], s0
1315        s_mov_b32 sa[1], s1
1316        s_mov_b32 sa[2], s2
1317        s_add_u32 sa[0], sa[1], sa[2]
1318        s_mov_b32 sa[3], 31
1319        s_mov_b32 sa[4], 11
1320        s_cbranch_scc0 pp0
1321       
1322        # block 1
1323bb0:    s_xor_b32 sa[1], sa[1], sa[0]
1324        s_xor_b32 sa[1], 122, sa[1]
1325        s_xor_b32 sa[2], sa[1], sa[0]
1326        s_cbranch_scc0 pp1
1327       
1328        # block 2
1329        s_xor_b32 sa[0], 122, sa[0]
1330        s_xor_b32 sa[2], sa[0], sa[2]
1331        s_bfe_u32 sa[3], sa[2], sa[0]
1332        s_endpgm
1333       
1334        # block 3
1335pp1:    s_xor_b32 sa[1], sa[0], sa[1]
1336        s_and_b32 sa[0], sa[0], sa[1]
1337        s_xor_b32 sa[2], sa[0], sa[1]
1338        s_bfe_u32 sa[4], sa[4], sa[0]
1339        s_endpgm
1340       
1341        # block 4
1342pp0:    s_xor_b32 sa[1], sa[1], sa[0]
1343        s_sub_u32 sa[0], sa[1], sa[0]
1344        s_xor_b32 sa[1], sa[1], sa[0]
1345        s_xor_b32 sa[1], sa[1], sa[0]
1346        s_add_u32 sa[0], sa[1], sa[0]
1347        s_xor_b32 sa[2], sa[1], sa[2]
1348        s_add_u32 sa[2], sa[0], sa[0]
1349        s_cbranch_scc0 pp2
1350       
1351        # block 5
1352        s_xor_b32 sa[2], sa[1], sa[2]
1353        s_add_u32 sa[2], sa[0], sa[0]
1354        s_xor_b32 sa[2], sa[1], sa[2]
1355        s_sub_u32 sa[4], sa[4], sa[0]
1356        s_sub_u32 sa[4], sa[4], sa[2]
1357        s_branch bb0
1358       
1359        # block 6
1360pp2:    s_xor_b32 sa[1], sa[1], sa[0]
1361        s_xor_b32 sa[0], sa[1], sa[2]
1362        s_add_u32 sa[0], sa[1], sa[2]
1363        s_and_b32 sa[3], sa[3], sa[0]
1364        s_bfe_u32 sa[3], sa[3], sa[4]
1365        s_bfe_u32 sa[3], sa[3], sa[1]
1366        s_branch bb0
1367)ffDXD",
1368        {
1369            // block 0
1370            { 0, 28,
1371                { { 1, false }, { 4, false } },
1372                {
1373                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
1374                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1375                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1376                    { { "sa", 0 }, SSAInfo(0, 1, 1, 2, 2, false) },
1377                    { { "sa", 1 }, SSAInfo(0, 1, 1, 1, 1, false) },
1378                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
1379                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
1380                    { { "sa", 4 }, SSAInfo(0, 1, 1, 1, 1, false) }
1381                }, false, false, false },
1382            // block 1
1383            { 28, 48,
1384                { { 2, false }, { 3, false } },
1385                {
1386                    { { "sa", 0 }, SSAInfo(2, SIZE_MAX, 3, SIZE_MAX, 0, true) },
1387                    { { "sa", 1 }, SSAInfo(1, 2, 2, 3, 2, true) },
1388                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, false) },
1389                }, false, false, false },
1390            // block 2
1391            { 48, 68,
1392                { },
1393                {
1394                    { { "sa", 0 }, SSAInfo(2, 3, 3, 3, 1, true) },
1395                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
1396                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, false) }
1397                }, false, false, true },
1398            // block 3
1399            { 68, 88,
1400                { },
1401                {
1402                    { { "sa", 0 }, SSAInfo(2, 4, 4, 4, 1, true) },
1403                    { { "sa", 1 }, SSAInfo(3, 4, 4, 4, 1, true) },
1404                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, false) },
1405                    { { "sa", 4 }, SSAInfo(1, 2, 2, 2, 1, true) }
1406                }, false, false, true },
1407            // block 4
1408            { 88, 120,
1409                { { 5, false }, { 6, false } },
1410                {
1411                    { { "sa", 0 }, SSAInfo(2, 5, 5, 6, 2, true) },
1412                    { { "sa", 1 }, SSAInfo(1, 5, 5, 7, 3, true) },
1413                    { { "sa", 2 }, SSAInfo(1, 5, 5, 6, 2, true) }
1414                }, false, false, false },
1415            // block 5
1416            { 120, 144,
1417                { { 1, false } },
1418                {
1419                    { { "sa", 0 }, SSAInfo(6, SIZE_MAX, 7, SIZE_MAX, 0, true) },
1420                    { { "sa", 1 }, SSAInfo(7, SIZE_MAX, 8, SIZE_MAX, 0, true) },
1421                    { { "sa", 2 }, SSAInfo(6, 7, 7, 9, 3, true) },
1422                    { { "sa", 4 }, SSAInfo(1, 3, 3, 4, 2, true) }
1423                }, false, false, true },
1424            // block 6
1425            { 144, 172,
1426                { { 1, false } },
1427                {
1428                    { { "sa", 0 }, SSAInfo(6, 7, 7, 8, 2, true) },
1429                    { { "sa", 1 }, SSAInfo(7, 8, 8, 8, 1, true) },
1430                    { { "sa", 2 }, SSAInfo(6, SIZE_MAX, 10, SIZE_MAX, 0, true) },
1431                    { { "sa", 3 }, SSAInfo(1, 3, 3, 5, 3, true) },
1432                    { { "sa", 4 }, SSAInfo(1, SIZE_MAX, 5, SIZE_MAX, 0, true) }
1433                }, false, false, true }
1434        },
1435        {
1436            { { "sa", 0 }, { { 6, 2 }, { 8, 2 } } },
1437            { { "sa", 1 }, { { 7, 1 }, { 8, 1 } } },
1438            { { "sa", 4 }, { { 4, 1 } } }
1439        },
1440        true, ""
1441    },
1442    {   // 8 - two loops, one nested
1443        R"ffDXD(.regvar sa:s:8, va:v:8
1444        s_mov_b64 sa[0:1], 0
1445        v_mov_b32 va[0], v1
1446        v_mov_b32 va[1], v2
1447        v_mov_b32 va[2], v3
1448       
1449loop0:  v_lshrrev_b32 va[0], va[2], va[0]
1450        v_xor_b32 va[0], va[1], va[0]
1451       
1452        s_xor_b32 sa[3], sa[0], 0x5
1453        s_cmp_eq_u32 sa[3], 9
1454        s_cbranch_scc1 bb0
1455       
1456        v_and_b32 va[0], -15, va[0]
1457        v_sub_u32 va[0], vcc, -13, va[0]
1458        s_branch loop1start
1459       
1460bb0:    v_xor_b32 va[0], 15, va[0]
1461        v_add_u32 va[0], vcc, 17, va[0]
1462loop1start:
1463        s_mov_b32 sa[1], sa[0]
1464       
1465loop1:  v_add_u32 va[2], vcc, va[2], va[1]
1466        v_xor_b32 va[2], 0xffaaaa, va[0]
1467       
1468        s_xor_b32 sa[2], sa[1], 0x5
1469        s_cmp_eq_u32 sa[2], 7
1470        s_cbranch_scc1 bb1
1471       
1472        v_sub_u32 va[1], vcc, 5, va[1]
1473        v_sub_u32 va[2], vcc, 7, va[2]
1474        s_branch loop1end
1475       
1476bb1:    v_xor_b32 va[1], 15, va[1]
1477        v_xor_b32 va[2], 17, va[2]
1478loop1end:
1479       
1480        s_add_u32 sa[1], sa[1], 1
1481        s_cmp_lt_u32 sa[1], 52
1482        s_cbranch_scc1 loop1
1483       
1484        v_xor_b32 va[0], va[1], va[0]
1485        v_xor_b32 va[0], va[2], va[0]
1486        v_xor_b32 va[0], sa[0], va[0]
1487       
1488        s_add_u32 sa[0], sa[0], 1
1489        s_cmp_lt_u32 sa[0], 33
1490        s_cbranch_scc1 loop0
1491       
1492        s_endpgm
1493)ffDXD",
1494        {
1495            // block 0
1496            { 0, 16,
1497                { },
1498                {
1499                    { { "", 256+1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1500                    { { "", 256+2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1501                    { { "", 256+3 }, SSAInfo(0, 0, 0, 0, 0, true) },
1502                    { { "sa", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
1503                    { { "sa", 1 }, SSAInfo(0, 1, 1, 1, 1, false) },
1504                    { { "va", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
1505                    { { "va", 1 }, SSAInfo(0, 1, 1, 1, 1, false) },
1506                    { { "va", 2 }, SSAInfo(0, 1, 1, 1, 1, false) }
1507                }, false, false, false },
1508            // block 1 (loop0)
1509            { 16, 36,
1510                { { 2, false }, { 3, false } },
1511                {
1512                    { { "sa", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1513                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
1514                    { { "va", 0 }, SSAInfo(1, 2, 2, 3, 2, true) },
1515                    { { "va", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1516                    { { "va", 2 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
1517                }, false, false, false },
1518            // block 2 (to bb0)
1519            { 36, 48,
1520                { { 4, false } },
1521                {
1522                    { { "va", 0 }, SSAInfo(3, 4, 4, 5, 2, true) }
1523                }, false, false, true },
1524            // block 3 (bb0)
1525            { 48, 56,
1526                { },
1527                {
1528                    { { "va", 0 }, SSAInfo(3, 9, 9, 10, 2, true) }
1529                }, false, false, false },
1530            // block 4 (loop1start)
1531            { 56, 60,
1532                { },
1533                {
1534                    { { "sa", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1535                    { { "sa", 1 }, SSAInfo(1, 2, 2, 2, 1, false) }
1536                }, false, false, false },
1537            // block 5 (loop1)
1538            { 60, 84,
1539                { { 6, false }, { 7, false } },
1540                {
1541                    { { "sa", 1 }, SSAInfo(2, SIZE_MAX, 3, SIZE_MAX, 0, true) },
1542                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
1543                    { { "va", 0 }, SSAInfo(5, SIZE_MAX, 6, SIZE_MAX, 0, true) },
1544                    { { "va", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1545                    { { "va", 2 }, SSAInfo(1, 2, 2, 3, 2, true) }
1546                }, false, false, false },
1547            // block 6 (to bb1)
1548            { 84, 96,
1549                { { 8, false } },
1550                {
1551                    { { "va", 1 }, SSAInfo(1, 2, 2, 2, 1, true) },
1552                    { { "va", 2 }, SSAInfo(3, 4, 4, 4, 1, true) }
1553                }, false, false, true },
1554            // block 7 (b11)
1555            { 96, 104,
1556                { },
1557                {
1558                    { { "va", 1 }, SSAInfo(1, 3, 3, 3, 1, true) },
1559                    { { "va", 2 }, SSAInfo(3, 5, 5, 5, 1, true) }
1560                }, false, false, false },
1561            // block 8 (loop1end)
1562            { 104, 116,
1563                { { 5, false }, { 9, false } },
1564                {
1565                    { { "sa", 1 }, SSAInfo(2, 3, 3, 3, 1, true) }
1566                }, false, false, false },
1567            // block 9 (loop0end)
1568            { 116, 140,
1569                { { 1, false }, { 10, false } },
1570                {
1571                    { { "sa", 0 }, SSAInfo(1, 2, 2, 2, 1, true) },
1572                    { { "va", 0 }, SSAInfo(5, 6, 6, 8, 3, true) },
1573                    { { "va", 1 }, SSAInfo(2, SIZE_MAX, 3, SIZE_MAX, 0, true) },
1574                    { { "va", 2 }, SSAInfo(4, SIZE_MAX, 5, SIZE_MAX, 0, true) }
1575                }, false, false, false },
1576            // block 10 (to bb0)
1577            { 140, 144,
1578                { },
1579                { }, false, false, true }
1580        },
1581        {   // SSA replaces
1582            { { "sa", 0 }, { { 2, 1 } } },
1583            { { "sa", 1 }, { { 3, 2 } } },
1584            { { "va", 0 }, { { 8, 1 }, { 10, 5 } } },
1585            { { "va", 1 }, { { 2, 1 }, { 2, 1 }, { 3, 1 }, { 3, 2 } } },
1586            { { "va", 2 }, { { 4, 1 }, { 4, 1 }, { 5, 1 }, { 5, 4 } } }
1587        },
1588        true, ""
1589    },
1590    {   // 9 - two branches
1591        R"ffDXD(.regvar sa:s:8, va:v:8
1592        # block 0
1593        s_mov_b64 sa[0:1], 321
1594        s_mov_b32 sa[2], s1
1595        s_mov_b32 sa[3], s2
1596        s_cmpk_eq_u32 s1, 321
1597        s_cbranch_scc1 bb10
1598       
1599        # block 1
1600        s_add_u32 sa[0], sa[0], sa[1]
1601        s_add_u32 sa[0], sa[0], sa[1]
1602        s_add_u32 sa[0], sa[0], sa[1]
1603        s_cbranch_scc1 bb01
1604       
1605        # block 2
1606        s_add_u32 sa[0], sa[0], sa[1]
1607        s_add_u32 sa[0], sa[0], sa[1]
1608        s_branch bb0e
1609       
1610        # block 3
1611bb01:   s_add_u32 sa[0], sa[0], sa[1]
1612        s_add_u32 sa[0], sa[0], sa[1]
1613       
1614        # block 4
1615bb0e:   s_add_u32 sa[0], sa[0], sa[2]
1616        s_endpgm
1617       
1618        # block 5
1619bb10:   s_add_u32 sa[0], sa[0], sa[1]
1620        s_add_u32 sa[0], sa[0], sa[1]
1621        s_add_u32 sa[0], sa[0], sa[1]
1622        s_add_u32 sa[0], sa[0], sa[1]
1623        s_add_u32 sa[0], sa[0], sa[1]
1624        s_cbranch_scc1 bb11
1625       
1626        # block 6
1627        s_add_u32 sa[0], sa[0], sa[2]
1628        s_add_u32 sa[0], sa[0], sa[2]
1629        s_branch bb1e
1630       
1631        # block 7
1632bb11:   s_add_u32 sa[0], sa[0], sa[3]
1633        s_add_u32 sa[0], sa[0], sa[3]
1634       
1635        # block 8
1636bb1e:   s_add_u32 sa[0], sa[0], sa[1]
1637        s_endpgm
1638)ffDXD",
1639        {
1640            // block 0 - start
1641            { 0, 24,
1642                { { 1, false }, { 5, false } },
1643                {
1644                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1645                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1646                    { { "sa", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
1647                    { { "sa", 1 }, SSAInfo(0, 1, 1, 1, 1, false) },
1648                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
1649                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
1650                }, false, false, false },
1651            // block 1 - bb00
1652            { 24, 40,
1653                { { 2, false }, { 3, false } },
1654                {
1655                    { { "sa", 0 }, SSAInfo(1, 2, 2, 4, 3, true) },
1656                    { { "sa", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
1657                }, false, false, false },
1658            // block 2 - bb00 second
1659            { 40, 52,
1660                { { 4, false } },
1661                {
1662                    { { "sa", 0 }, SSAInfo(4, 5, 5, 6, 2, true) },
1663                    { { "sa", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
1664                }, false, false, true },
1665            // block 3 - bb01
1666            { 52, 60,
1667                { },
1668                {
1669                    { { "sa", 0 }, SSAInfo(4, 8, 8, 9, 2, true) },
1670                    { { "sa", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
1671                }, false, false, false },
1672            // block 4 - bb0e
1673            { 60, 68,
1674                { },
1675                {
1676                    { { "sa", 0 }, SSAInfo(6, 7, 7, 7, 1, true) },
1677                    { { "sa", 2 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
1678                }, false, false, true },
1679            // block 5 - bb10
1680            { 68, 92,
1681                { { 6, false }, { 7, false } },
1682                {
1683                    { { "sa", 0 }, SSAInfo(1, 10, 10, 14, 5, true) },
1684                    { { "sa", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
1685                }, false, false, false },
1686            // block 6 - bb10 (second)
1687            { 92, 104,
1688                { { 8, false } },
1689                {
1690                    { { "sa", 0 }, SSAInfo(14, 15, 15, 16, 2, true) },
1691                    { { "sa", 2 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
1692                }, false, false, true },
1693            // block 7 - bb11
1694            { 104, 112,
1695                { },
1696                {
1697                    { { "sa", 0 }, SSAInfo(14, 18, 18, 19, 2, true) },
1698                    { { "sa", 3 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
1699                }, false, false, false },
1700            // block 8 - bb1e
1701            { 112, 120,
1702                { },
1703                {
1704                    { { "sa", 0 }, SSAInfo(16, 17, 17, 17, 1, true) },
1705                    { { "sa", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
1706                }, false, false, true }
1707        },
1708        {   // SSA replaces
1709            { { "sa", 0 }, { { 9, 6 }, { 19, 16 } } }
1710        },
1711        true, ""
1712    },
1713    {   // 10 - two branches with various SSAIds
1714        R"ffDXD(.regvar sa:s:8, va:v:8
1715        # block 0
1716        s_mov_b32 sa[0], s2
1717        s_mov_b32 sa[1], s3
1718        s_mov_b32 sa[2], s4
1719        s_mov_b32 sa[3], s5
1720       
1721        s_cmp_lt_u32 s0, s1
1722        s_cbranch_scc1 bb1
1723       
1724        # block 1, bb0
1725bb0:    s_add_u32 sa[3], sa[3], s1   # replace from this
1726        s_add_u32 sa[3], sa[3], s2
1727        s_cbranch_scc1 bb01
1728       
1729        # block 2, bb00
1730        s_add_u32 sa[2], sa[2], sa[1]   # replace from this
1731        s_add_u32 sa[3], sa[3], sa[2]
1732        s_endpgm
1733
1734bb01:   s_add_u32 sa[2], sa[2], sa[1]
1735        s_add_u32 sa[2], sa[2], sa[0]
1736        s_add_u32 sa[3], sa[3], sa[2]
1737        s_endpgm
1738       
1739bb1:    s_xor_b32 sa[2], sa[2], sa[0]
1740        s_xor_b32 sa[3], sa[3], sa[1]
1741        s_branch bb0
1742)ffDXD",
1743        {
1744            // block 0 - start
1745            { 0, 24,
1746                { { 1, false }, { 4, false } },
1747                {
1748                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
1749                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1750                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1751                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
1752                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
1753                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
1754                    { { "sa", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
1755                    { { "sa", 1 }, SSAInfo(0, 1, 1, 1, 1, false) },
1756                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
1757                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
1758                }, false, false, false },
1759            // block 1 - bb0
1760            { 24, 36,
1761                { { 2, false }, { 3, false } },
1762                {
1763                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1764                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1765                    { { "sa", 3 }, SSAInfo(1, 2, 2, 3, 2, true) }
1766                }, false, false, false },
1767            // block 2 - bb00
1768            { 36, 48,
1769                { },
1770                {
1771                    { { "sa", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1772                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
1773                    { { "sa", 3 }, SSAInfo(3, 4, 4, 4, 1, true) }
1774                }, false, false, true },
1775            // block 3 - bb01
1776            { 48, 64,
1777                { },
1778                {
1779                    { { "sa", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1780                    { { "sa", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1781                    { { "sa", 2 }, SSAInfo(1, 3, 3, 4, 2, true) },
1782                    { { "sa", 3 }, SSAInfo(3, 5, 5, 5, 1, true) }
1783                }, false, false, true },
1784            // block 4 - bb1
1785            { 64, 76,
1786                { { 1, false } },
1787                {
1788                    { { "sa", 0 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1789                    { { "sa", 1 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1790                    { { "sa", 2 }, SSAInfo(1, 5, 5, 5, 1, true) },
1791                    { { "sa", 3 }, SSAInfo(1, 6, 6, 6, 1, true) }
1792                }, false, false, true }
1793        },
1794        {   // SSA replaces
1795            { { "sa", 2 }, { { 5, 1 }, { 5, 1 } } },
1796            { { "sa", 3 }, { { 6, 1 } } }
1797        },
1798        true, ""
1799    },
1800    {   // 11 - with trap: first branch have unhandled SSA replace
1801        R"ffDXD(.regvar sa:s:8, va:v:8
1802        # block 0
1803        s_mov_b32 sa[0], s2
1804        s_mov_b32 sa[1], s3
1805        s_mov_b32 sa[2], s4
1806        s_mov_b32 sa[3], s5
1807        s_cmp_lt_u32 s0, s1
1808        s_cbranch_scc1 bb1
1809       
1810        # bb0
1811bb0:    s_add_u32 sa[3], sa[3], s1      # SSAID replace
1812        s_add_u32 sa[3], sa[3], s2
1813        s_endpgm
1814       
1815bb3:    s_add_u32 sa[3], sa[3], s2      # no SSAID replace (this same SSAID)
1816        s_endpgm
1817       
1818bb1:    s_add_u32 sa[3], sa[3], s2
1819bb1x:   .cf_jump bb3, bb2, bb4
1820        s_setpc_b64 s[0:1]
1821
1822bb2:    s_branch bb0
1823       
1824bb4:    s_branch bb1x       # jump to point to resolve conflict (bb1x)
1825)ffDXD",
1826        {
1827            // block 0
1828            { 0, 24,
1829                { { 1, false }, { 3, false } },
1830                {
1831                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
1832                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1833                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1834                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
1835                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
1836                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
1837                    { { "sa", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
1838                    { { "sa", 1 }, SSAInfo(0, 1, 1, 1, 1, false) },
1839                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
1840                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
1841                }, false, false, false },
1842            // block 1
1843            { 24, 36,
1844                { },
1845                {
1846                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1847                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1848                    { { "sa", 3 }, SSAInfo(1, 2, 2, 3, 2, true) }
1849                }, false, false, true },
1850            // block 2
1851            { 36, 44,
1852                { },
1853                {
1854                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1855                    { { "sa", 3 }, SSAInfo(4, 5, 5, 5, 1, true) }
1856                }, false, false, true },
1857            // block 3 - bb1 - main part
1858            { 44, 48,
1859                { },
1860                {
1861                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1862                    { { "sa", 3 }, SSAInfo(1, 4, 4, 4, 1, true) }
1863                }, false, false, false },
1864            // block 4 - bb1x - jmp part
1865            { 48, 52,
1866                { { 2, false }, { 5, false }, { 6, false } },
1867                {
1868                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
1869                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) }
1870                }, false, false, true },
1871            // block 5
1872            { 52, 56,
1873                { { 1, false } },
1874                { }, false, false, true },
1875            // block 6
1876            { 56, 60,
1877                { { 4, false } },
1878                { }, false, false, true }
1879        },
1880        {
1881            { { "sa", 3 }, { { 4, 1 }, { 4, 1 } } }
1882        },
1883        true, ""
1884    },
1885    {   // 12 - with trap: first branch have higher SSAId
1886        R"ffDXD(.regvar sa:s:8, va:v:8
1887        # block 0
1888        s_mov_b32 sa[0], s2
1889        s_mov_b32 sa[1], s3
1890        s_mov_b32 sa[2], s4
1891        s_mov_b32 sa[3], s5
1892        s_cmp_lt_u32 s0, s1
1893        .cf_jump bb1, bbx, bb3, bb2
1894        s_setpc_b64 s[0:1]
1895       
1896bb1:    s_add_u32 sa[3], sa[3], sa[2]
1897        s_endpgm
1898       
1899bbx:    s_add_u32 sa[3], sa[3], sa[2]
1900        s_cbranch_scc1 bb1_
1901
1902bb0:    s_add_u32 sa[3], sa[3], sa[2]
1903        s_endpgm
1904       
1905bb1_:   s_branch bb1
1906
1907bb3:    .cf_jump bb0, bb1_
1908        s_setpc_b64 s[0:1]
1909               
1910bb2:    s_add_u32 sa[3], sa[3], sa[2]
1911        s_branch bb3
1912)ffDXD",
1913        {
1914            // block 0
1915            { 0, 24,
1916                { { 1, false }, { 2, false }, { 5, false }, { 6, false } },
1917                {
1918                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
1919                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
1920                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
1921                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
1922                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
1923                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
1924                    { { "sa", 0 }, SSAInfo(0, 1, 1, 1, 1, false) },
1925                    { { "sa", 1 }, SSAInfo(0, 1, 1, 1, 1, false) },
1926                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
1927                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
1928                }, false, false, true },
1929            // block 1 - bb1
1930            { 24, 32,
1931                { },
1932                {
1933                    { { "sa", 2 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1934                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) }
1935                }, false, false, true },
1936            // block 2 - bbx
1937            { 32, 40,
1938                { { 3, false }, { 4, false } },
1939                {
1940                    { { "sa", 2 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1941                    { { "sa", 3 }, SSAInfo(1, 3, 3, 3, 1, true) }
1942                }, false, false, false },
1943            // block 3 - bb0
1944            { 40, 48,
1945                { },
1946                {
1947                    { { "sa", 2 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1948                    { { "sa", 3 }, SSAInfo(3, 4, 4, 4, 1, true) }
1949                }, false, false, true },
1950            // block 4 - bb1_
1951            { 48, 52,
1952                { { 1, false } },
1953                { }, false, false, true },
1954            // block 5
1955            { 52, 56,
1956                { { 3, false }, { 4, false } },
1957                {
1958                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
1959                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) }
1960                }, false, false, true },
1961            // block 5
1962            { 56, 64,
1963                { { 5, false } },
1964                {
1965                    { { "sa", 2 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) },
1966                    { { "sa", 3 }, SSAInfo(1, 5, 5, 5, 1, true) }
1967                }, false, false, true }
1968        },
1969        {
1970            { { "sa", 3 }, { { 3, 1 }, { 3, 1 }, { 5, 3 }, { 5, 1 } } }
1971        },
1972        true, ""
1973    },
1974    {   // 13 - yet another branch example
1975        R"ffDXD(.regvar sa:s:8, va:v:8
1976        s_mov_b32 sa[2], s4
1977        s_mov_b32 sa[3], s5
1978       
1979        .cf_cjump b1, b2, b3
1980        s_setpc_b64 s[0:1]
1981
1982b0:     s_xor_b32 sa[2], sa[2], sa[4]
1983        s_xor_b32 sa[3], sa[3], sa[4]
1984        s_endpgm
1985       
1986b1:     s_xor_b32 sa[2], sa[2], sa[4]
1987        s_xor_b32 sa[3], sa[3], sa[4]
1988b1x:    s_xor_b32 sa[2], sa[2], sa[4]
1989        s_branch b0
1990       
1991b2:     s_xor_b32 sa[2], sa[2], sa[4]
1992        s_xor_b32 sa[3], sa[3], sa[4]
1993b2x:    s_xor_b32 sa[2], sa[2], sa[4]
1994        s_branch b1x
1995       
1996b3:     s_xor_b32 sa[2], sa[2], sa[4]
1997        s_xor_b32 sa[3], sa[3], sa[4]
1998        s_branch b2x
1999)ffDXD",
2000        {
2001            // block 0
2002            { 0, 12,
2003                { { 1, false }, { 2, false }, { 4, false }, { 6, false } },
2004                {
2005                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2006                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2007                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2008                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2009                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2010                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2011                }, false, false, false },
2012            // block 1 - b0
2013            { 12, 24,
2014                { },
2015                {
2016                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2017                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
2018                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2019                }, false, false, true },
2020            // block 2 - b1
2021            { 24, 32,
2022                { },
2023                {
2024                    { { "sa", 2 }, SSAInfo(1, 3, 3, 3, 1, true) },
2025                    { { "sa", 3 }, SSAInfo(1, 3, 3, 3, 1, true) },
2026                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2027                }, false, false, false },
2028            // block 3 - b1x
2029            { 32, 40,
2030                { { 1, false } },
2031                {
2032                    { { "sa", 2 }, SSAInfo(3, 4, 4, 4, 1, true) },
2033                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2034                }, false, false, true },
2035            // block 4 - b2
2036            { 40, 48,
2037                { },
2038                {
2039                    { { "sa", 2 }, SSAInfo(1, 5, 5, 5, 1, true) },
2040                    { { "sa", 3 }, SSAInfo(1, 4, 4, 4, 1, true) },
2041                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2042                }, false, false, false },
2043            // block 5 - b2x
2044            { 48, 56,
2045                { { 3, false } },
2046                {
2047                    { { "sa", 2 }, SSAInfo(5, 6, 6, 6, 1, true) },
2048                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2049                }, false, false, true },
2050            // block 6 - b3
2051            { 56, 68,
2052                { { 5, false } },
2053                {
2054                    { { "sa", 2 }, SSAInfo(1, 7, 7, 7, 1, true) },
2055                    { { "sa", 3 }, SSAInfo(1, 5, 5, 5, 1, true) },
2056                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2057                }, false, false, true }
2058        },
2059        {   // SSA replaces
2060            { { "sa", 2 }, { { 4, 1 }, { 6, 3 }, { 7, 5 } } },
2061            { { "sa", 3 }, { { 3, 1 }, { 4, 1 }, { 5, 1 } } }
2062        },
2063        true, ""
2064    },
2065    {   // 14 -
2066        R"ffDXD(.regvar sa:s:8, va:v:8
2067        s_mov_b32 sa[2], s4
2068        s_mov_b32 sa[3], s5
2069        .cf_jump b1, b2
2070        s_setpc_b64 s[0:1]
2071       
2072b11:    s_xor_b32 sa[2], sa[2], sa[3]
2073        s_endpgm
2074       
2075b1:     s_xor_b32 sa[2], sa[2], sa[3]
2076        s_branch b11
2077       
2078b2:     s_branch b11
2079)ffDXD",
2080        {
2081            // block 0 - start
2082            { 0, 12,
2083                { { 2, false }, { 3, false } },
2084                {
2085                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2086                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2087                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2088                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2089                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2090                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2091                }, false, false, true },
2092            // block 1 - b11
2093            { 12, 20,
2094                { },
2095                {
2096                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
2097                    { { "sa", 3 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
2098                }, false, false, true },
2099            // block 2 - b1
2100            { 20, 28,
2101                { { 1, false } },
2102                {
2103                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2104                    { { "sa", 3 }, SSAInfo(1, SIZE_MAX, 2, SIZE_MAX, 0, true) }
2105                }, false, false, true },
2106            // block 3 - b2
2107            { 28, 32,
2108                { { 1, false } },
2109                { }, false, false, true }
2110        },
2111        {
2112            { { "sa", 2 }, { { 2, 1 } } }
2113        },
2114        true, ""
2115    },
2116    {   // 15 - trick - SSA replaces beyond visited point
2117        R"ffDXD(.regvar sa:s:8, va:v:8
2118        s_mov_b32 sa[2], s4
2119        s_mov_b32 sa[3], s5
2120       
2121loop:   s_xor_b32 sa[2], sa[2], sa[4]
2122        s_cbranch_scc0 end
2123       
2124        s_xor_b32 sa[3], sa[2], sa[4]
2125        s_cbranch_scc0 loop
2126       
2127        s_endpgm
2128       
2129end:    s_xor_b32 sa[3], sa[3], sa[4]
2130        s_endpgm
2131)ffDXD",
2132        {
2133            // block 0 - start
2134            { 0, 8,
2135                { },
2136                {
2137                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2138                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2139                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2140                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2141                }, false, false, false },
2142            // block 1 - loop
2143            { 8, 16,
2144                { { 2, false }, { 4, false } },
2145                {
2146                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2147                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2148                }, false, false, false },
2149            // block 2 - loop part 2
2150            { 16, 24,
2151                { { 1, false }, { 3, false } },
2152                {
2153                    { { "sa", 2 }, SSAInfo(2, SIZE_MAX, 3, SIZE_MAX, 0, true) },
2154                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, false) },
2155                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2156                }, false, false, false },
2157            // block 3 - end 2
2158            { 24, 28,
2159                { },
2160                { }, false, false, true },
2161            // block 4 - end
2162            { 28, 36,
2163                { },
2164                {
2165                    { { "sa", 3 }, SSAInfo(1, 3, 3, 3, 1, true) },
2166                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2167                }, false, false, true }
2168        },
2169        {
2170            { { "sa", 2 }, { { 2, 1 } } },
2171            // must be
2172            { { "sa", 3 }, { { 2, 1 } } }
2173        },
2174        true, ""
2175    },
2176    {   // 16 - trick - SSA replaces beyond visited point
2177        R"ffDXD(.regvar sa:s:8, va:v:8
2178        s_mov_b32 sa[2], s4
2179        s_mov_b32 sa[3], s5
2180       
2181loop:   s_xor_b32 sa[2], sa[2], sa[4]
2182        s_cbranch_scc0 end
2183       
2184        s_xor_b32 sa[3], sa[2], sa[4]
2185        s_cbranch_scc0 loop
2186       
2187end:    s_xor_b32 sa[3], sa[3], sa[4]
2188        s_endpgm
2189)ffDXD",
2190        {
2191            // block 0 - start
2192            { 0, 8,
2193                { },
2194                {
2195                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2196                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2197                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2198                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2199                }, false, false, false },
2200            // block 1 - loop
2201            { 8, 16,
2202                { { 2, false }, { 3, false } },
2203                {
2204                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2205                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2206                }, false, false, false },
2207            // block 2 - loop part 2
2208            { 16, 24,
2209                { { 1, false }, { 3, false } },
2210                {
2211                    { { "sa", 2 }, SSAInfo(2, SIZE_MAX, 3, SIZE_MAX, 0, true) },
2212                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, false) },
2213                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2214                }, false, false, false },
2215            // block 3 - end
2216            { 24, 32,
2217                { },
2218                {
2219                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) },
2220                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2221                }, false, false, true }
2222        },
2223        {
2224            { { "sa", 2 }, { { 2, 1 } } },
2225            // must be
2226            { { "sa", 3 }, { { 2, 1 } } }
2227        },
2228        true, ""
2229    },
2230    {   // 17 - simple call
2231        R"ffDXD(.regvar sa:s:8, va:v:8
2232        s_mov_b32 sa[2], s4
2233        s_mov_b32 sa[3], s5
2234       
2235        s_getpc_b64 s[2:3]
2236        s_add_u32 s2, s2, routine-.
2237        s_add_u32 s3, s3, routine-.+4
2238        .cf_call routine
2239        s_swappc_b64 s[0:1], s[2:3]
2240       
2241        s_lshl_b32 sa[2], sa[2], 3
2242        s_lshl_b32 sa[3], sa[3], 4
2243        s_endpgm
2244       
2245routine:
2246        s_xor_b32 sa[2], sa[2], sa[4]
2247        s_xor_b32 sa[3], sa[3], sa[4]
2248        .cf_ret
2249        s_setpc_b64 s[0:1]
2250)ffDXD",
2251        {
2252            { 0, 32,
2253                { { 2, true } },
2254                {
2255                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2256                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2257                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2258                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2259                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2260                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2261                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2262                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2263                }, true, false, false },
2264            { 32, 44,
2265                { },
2266                {
2267                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
2268                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) }
2269                }, false, false, true },
2270            { 44, 56,
2271                { },
2272                {
2273                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2274                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2275                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2276                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
2277                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2278                }, false, true, true }
2279        },
2280        { },
2281        true, ""
2282    },
2283    {   // 18 - simple call, more complex routine
2284        R"ffDXD(.regvar sa:s:8, va:v:8
2285        s_mov_b32 sa[2], s4
2286        s_mov_b32 sa[3], s5
2287       
2288        s_getpc_b64 s[2:3]
2289        s_add_u32 s2, s2, routine-.
2290        s_add_u32 s3, s3, routine-.+4
2291        .cf_call routine
2292        s_swappc_b64 s[0:1], s[2:3]
2293       
2294        s_lshl_b32 sa[2], sa[2], 3
2295        s_lshl_b32 sa[3], sa[3], 4
2296        s_endpgm
2297       
2298routine:
2299        s_xor_b32 sa[2], sa[2], sa[4]
2300        s_xor_b32 sa[3], sa[3], sa[4]
2301        s_cbranch_scc1 bb1
2302       
2303        s_min_u32 sa[2], sa[2], sa[4]
2304        s_min_u32 sa[3], sa[3], sa[4]
2305        .cf_ret
2306        s_setpc_b64 s[0:1]
2307       
2308bb1:    s_and_b32 sa[2], sa[2], sa[4]
2309        s_and_b32 sa[3], sa[3], sa[4]
2310        .cf_ret
2311        s_setpc_b64 s[0:1]
2312)ffDXD",
2313        {
2314            { 0, 32,
2315                { { 2, true } },
2316                {
2317                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2318                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2319                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2320                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2321                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2322                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2323                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2324                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2325                }, true, false, false },
2326            // block 1 - after call
2327            { 32, 44,
2328                { },
2329                {
2330                    { { "sa", 2 }, SSAInfo(3, 5, 5, 5, 1, true) },
2331                    { { "sa", 3 }, SSAInfo(3, 5, 5, 5, 1, true) }
2332                }, false, false, true },
2333            // block 2 - routine
2334            { 44, 56,
2335                { { 3, false }, { 4, false } },
2336                {
2337                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2338                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
2339                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2340                }, false, false, false },
2341            // block 3 - first return
2342            { 56, 68,
2343                { },
2344                {
2345                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2346                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2347                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
2348                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) },
2349                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2350                }, false, true, true },
2351            // block 4 - second return
2352            { 68, 80,
2353                { },
2354                {
2355                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2356                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2357                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, true) },
2358                    { { "sa", 3 }, SSAInfo(2, 4, 4, 4, 1, true) },
2359                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2360                }, false, true, true }
2361        },
2362        {   // SSA replaces
2363            { { "sa", 2 }, { { 4, 3 } } },
2364            { { "sa", 3 }, { { 4, 3 } } }
2365        },
2366        true, ""
2367    },
2368    {   // 19 - simple call, more complex routine
2369        R"ffDXD(.regvar sa:s:8, va:v:8
2370        s_mov_b32 sa[2], s4
2371        s_mov_b32 sa[3], s5
2372       
2373        s_getpc_b64 s[2:3]
2374        s_add_u32 s2, s2, routine-.
2375        s_add_u32 s3, s3, routine-.+4
2376        .cf_call routine
2377        s_swappc_b64 s[0:1], s[2:3]
2378       
2379        s_lshl_b32 sa[2], sa[2], 3
2380        s_lshl_b32 sa[3], sa[3], 4
2381        s_endpgm
2382       
2383routine:
2384        s_xor_b32 sa[2], sa[2], sa[4]
2385        s_cbranch_scc1 bb1
2386       
2387        s_min_u32 sa[2], sa[2], sa[4]
2388        s_xor_b32 sa[3], sa[3], sa[4]
2389        .cf_ret
2390        s_setpc_b64 s[0:1]
2391       
2392bb1:    s_and_b32 sa[2], sa[2], sa[4]
2393        .cf_ret
2394        s_setpc_b64 s[0:1]
2395)ffDXD",
2396        {
2397            { 0, 32,
2398                { { 2, true } },
2399                {
2400                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2401                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2402                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2403                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2404                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2405                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2406                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2407                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2408                }, true, false, false },
2409            // block 1 - after call
2410            { 32, 44,
2411                { },
2412                {
2413                    { { "sa", 2 }, SSAInfo(3, 5, 5, 5, 1, true) },
2414                    { { "sa", 3 }, SSAInfo(1, 3, 3, 3, 1, true) }
2415                }, false, false, true },
2416            // block 2 - routine
2417            { 44, 52,
2418                { { 3, false }, { 4, false } },
2419                {
2420                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2421                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2422                }, false, false, false },
2423            // block 3 - first return
2424            { 52, 64,
2425                { },
2426                {
2427                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2428                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2429                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
2430                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
2431                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2432                }, false, true, true },
2433            // block 4 - second return
2434            { 64, 72,
2435                { },
2436                {
2437                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2438                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2439                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, true) },
2440                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2441                }, false, true, true }
2442        },
2443        {   // SSA replaces
2444            { { "sa", 2 }, { { 4, 3 } } },
2445            { { "sa", 3 }, { { 2, 1 } } }
2446        },
2447        true, ""
2448    },
2449    {   // 20 - simple call, more complex routine
2450        R"ffDXD(.regvar sa:s:8, va:v:8
2451        s_mov_b32 sa[2], s4
2452        s_mov_b32 sa[3], s5
2453       
2454        s_getpc_b64 s[2:3]
2455        s_add_u32 s2, s2, routine-.
2456        s_add_u32 s3, s3, routine-.+4
2457        .cf_call routine
2458        s_swappc_b64 s[0:1], s[2:3]
2459       
2460        s_lshl_b32 sa[2], sa[2], 3
2461        s_lshl_b32 sa[3], sa[3], 4
2462        s_endpgm
2463       
2464routine:
2465        s_xor_b32 sa[2], sa[2], sa[4]
2466        s_xor_b32 sa[3], sa[3], sa[4]
2467        s_cbranch_scc1 bb1
2468       
2469        s_min_u32 sa[2], sa[2], sa[4]
2470        .cf_ret
2471        s_setpc_b64 s[0:1]
2472       
2473bb1:    s_and_b32 sa[2], sa[2], sa[4]
2474        .cf_ret
2475        s_setpc_b64 s[0:1]
2476)ffDXD",
2477        {
2478            { 0, 32,
2479                { { 2, true } },
2480                {
2481                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2482                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2483                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2484                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2485                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2486                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2487                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2488                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2489                }, true, false, false },
2490            // block 1 - after call
2491            { 32, 44,
2492                { },
2493                {
2494                    { { "sa", 2 }, SSAInfo(3, 5, 5, 5, 1, true) },
2495                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) }
2496                }, false, false, true },
2497            // block 2 - routine
2498            { 44, 56,
2499                { { 3, false }, { 4, false } },
2500                {
2501                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2502                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
2503                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2504                }, false, false, false },
2505            // block 3 - first return
2506            { 56, 64,
2507                { },
2508                {
2509                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2510                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2511                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
2512                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2513                }, false, true, true },
2514            // block 4 - second return
2515            { 64, 72,
2516                { },
2517                {
2518                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2519                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2520                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, true) },
2521                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2522                }, false, true, true }
2523        },
2524        {   // SSA replaces
2525            { { "sa", 2 }, { { 4, 3 } } }
2526        },
2527        true, ""
2528    },
2529    {   // 21 - simple call, many deep returns
2530        R"ffDXD(.regvar sa:s:8, va:v:8
2531        s_mov_b32 sa[2], s4
2532        s_mov_b32 sa[3], s5
2533       
2534        s_getpc_b64 s[2:3]
2535        s_add_u32 s2, s2, routine-.
2536        s_add_u32 s3, s3, routine-.+4
2537        .cf_call routine
2538        s_swappc_b64 s[0:1], s[2:3]
2539       
2540        s_lshl_b32 sa[2], sa[2], 3
2541        s_lshl_b32 sa[3], sa[3], 4
2542        s_lshl_b32 sa[4], sa[4], 5
2543        s_lshl_b32 sa[5], sa[5], 5
2544        s_lshl_b32 sa[6], sa[6], 5
2545        s_endpgm
2546       
2547routine:
2548        s_xor_b32 sa[2], sa[2], sa[0]
2549        s_xor_b32 sa[3], sa[3], sa[0]
2550        s_xor_b32 sa[6], sa[3], sa[0]
2551        s_cbranch_scc1 bb1
2552       
2553b0:     s_xor_b32 sa[2], sa[2], sa[0]
2554        s_xor_b32 sa[3], sa[3], sa[0]
2555        s_cbranch_scc1 bb01
2556       
2557bb00:   s_xor_b32 sa[2], sa[2], sa[0]
2558        s_branch bb00_
2559       
2560bb00_:  s_xor_b32 sa[2], sa[2], sa[0]
2561        s_xor_b32 sa[3], sa[3], sa[0]
2562        .cf_ret
2563        s_setpc_b64 s[0:1]
2564       
2565bb01:   s_xor_b32 sa[2], sa[2], sa[0]
2566        s_branch bb01_
2567       
2568bb01_:  s_xor_b32 sa[2], sa[2], sa[0]
2569        s_xor_b32 sa[3], sa[3], sa[0]
2570        s_xor_b32 sa[4], sa[4], sa[0]
2571        .cf_ret
2572        s_setpc_b64 s[0:1]
2573       
2574bb1:    s_xor_b32 sa[2], sa[2], sa[0]
2575        s_xor_b32 sa[3], sa[3], sa[0]
2576        s_cbranch_scc1 bb11
2577       
2578bb10:   s_xor_b32 sa[2], sa[2], sa[0]
2579        s_branch bb10_
2580       
2581bb10_:  s_xor_b32 sa[2], sa[2], sa[0]
2582        s_xor_b32 sa[3], sa[3], sa[0]
2583        s_xor_b32 sa[5], sa[3], sa[2]
2584        .cf_ret
2585        s_setpc_b64 s[0:1]
2586       
2587bb11:   s_xor_b32 sa[2], sa[2], sa[0]
2588        s_branch bb11_
2589       
2590bb11_:  s_xor_b32 sa[2], sa[2], sa[0]
2591        s_xor_b32 sa[3], sa[3], sa[0]
2592        s_xor_b32 sa[4], sa[4], sa[0]
2593        .cf_ret
2594        s_setpc_b64 s[0:1]
2595)ffDXD",
2596        {
2597            // block 0
2598            { 0, 32,
2599                { { 2, true } },
2600                {
2601                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2602                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2603                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2604                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2605                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2606                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2607                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2608                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2609                }, true, false, false },
2610            // block 1
2611            { 32, 56,
2612                { },
2613                {
2614                    { { "sa", 2 }, SSAInfo(5, 13, 13, 13, 1, true) },
2615                    { { "sa", 3 }, SSAInfo(4, 9, 9, 9, 1, true) },
2616                    { { "sa", 4 }, SSAInfo(0, 3, 3, 3, 1, true) },
2617                    { { "sa", 5 }, SSAInfo(0, 2, 2, 2, 1, true) },
2618                    { { "sa", 6 }, SSAInfo(1, 2, 2, 2, 1, true) }
2619                }, false, false, true },
2620            // block 2 - routine
2621            { 56, 72,
2622                { { 3, false }, { 8, false } },
2623                {
2624                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2625                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2626                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
2627                    { { "sa", 6 }, SSAInfo(0, 1, 1, 1, 1, false) }
2628                }, false, false, false },
2629            // block 3 - bb0
2630            { 72, 84,
2631                { { 4, false }, { 6, false } },
2632                {
2633                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2634                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
2635                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) }
2636                }, false, false, false },
2637            // block 4 - bb00
2638            { 84, 92,
2639                { { 5, false } },
2640                {
2641                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2642                    { { "sa", 2 }, SSAInfo(3, 4, 4, 4, 1, true) }
2643                }, false, false, true },
2644            // block 5 - bb00_
2645            { 92, 104,
2646                { },
2647                {
2648                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2649                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2650                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2651                    { { "sa", 2 }, SSAInfo(4, 5, 5, 5, 1, true) },
2652                    { { "sa", 3 }, SSAInfo(3, 4, 4, 4, 1, true) }
2653                }, false, true, true },
2654            // block 6 - bb01
2655            { 104, 112,
2656                { { 7, false } },
2657                {
2658                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2659                    { { "sa", 2 }, SSAInfo(3, 6, 6, 6, 1, true) }
2660                }, false, false, true },
2661            // block 7 - bb01_
2662            { 112, 128,
2663                { },
2664                {
2665                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2666                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2667                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2668                    { { "sa", 2 }, SSAInfo(6, 7, 7, 7, 1, true) },
2669                    { { "sa", 3 }, SSAInfo(3, 5, 5, 5, 1, true) },
2670                    { { "sa", 4 }, SSAInfo(0, 1, 1, 1, 1, true) }
2671                }, false, true, true },
2672            // block 8 - bb1
2673            { 128, 140,
2674                { { 9, false }, { 11, false } },
2675                {
2676                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2677                    { { "sa", 2 }, SSAInfo(2, 8, 8, 8, 1, true) },
2678                    { { "sa", 3 }, SSAInfo(2, 6, 6, 6, 1, true) }
2679                }, false, false, false },
2680            // block 9 - bb10
2681            { 140, 148,
2682                { { 10, false } },
2683                {
2684                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2685                    { { "sa", 2 }, SSAInfo(8, 9, 9, 9, 1, true) }
2686                }, false, false, true },
2687            // block 10 - bb10_
2688            { 148, 164,
2689                { },
2690                {
2691                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2692                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2693                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2694                    { { "sa", 2 }, SSAInfo(9, 10, 10, 10, 1, true) },
2695                    { { "sa", 3 }, SSAInfo(6, 7, 7, 7, 1, true) },
2696                    { { "sa", 5 }, SSAInfo(0, 1, 1, 1, 1, false) }
2697                }, false, true, true },
2698            // block 11
2699            { 164, 172,
2700                { { 12, false } },
2701                {
2702                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2703                    { { "sa", 2 }, SSAInfo(8, 11, 11, 11, 1, true) }
2704                }, false, false, true },
2705            // block 12
2706            { 172, 188,
2707                { },
2708                {
2709                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2710                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2711                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
2712                    { { "sa", 2 }, SSAInfo(11, 12, 12, 12, 1, true) },
2713                    { { "sa", 3 }, SSAInfo(6, 8, 8, 8, 1, true) },
2714                    { { "sa", 4 }, SSAInfo(0, 2, 2, 2, 1, true) }
2715                }, false, true, true }
2716        },
2717        {   // SSA replaces
2718            { { "sa", 2 }, { { 7, 5 }, { 10, 5 }, { 12, 5 } } },
2719            { { "sa", 3 }, { { 5, 4 }, { 7, 4 }, { 8, 4 } } },
2720            { { "sa", 4 }, { { 1, 0 }, { 2, 0 } } },
2721            { { "sa", 5 }, { { 1, 0 } } }
2722        },
2723        true, ""
2724    },
2725    {   // 22 - multiple call of routine
2726        R"ffDXD(.regvar sa:s:8, va:v:8
2727        s_mov_b32 sa[2], s4
2728        s_mov_b32 sa[3], s5
2729       
2730        s_getpc_b64 s[2:3]
2731        s_add_u32 s2, s2, routine-.
2732        s_add_u32 s3, s3, routine-.+4
2733        .cf_call routine
2734        s_swappc_b64 s[0:1], s[2:3]
2735       
2736        s_lshl_b32 sa[2], sa[2], 3
2737        s_lshl_b32 sa[3], sa[3], 4
2738       
2739        s_getpc_b64 s[2:3]
2740        s_add_u32 s2, s2, routine-.
2741        s_add_u32 s3, s3, routine-.+4
2742        .cf_call routine
2743        s_swappc_b64 s[0:1], s[2:3]
2744       
2745        s_ashr_i32 sa[2], sa[2], 3
2746        s_ashr_i32 sa[2], sa[2], 3
2747        s_ashr_i32 sa[3], sa[3], 4
2748        s_ashr_i32 sa[3], sa[3], 4
2749       
2750        s_getpc_b64 s[2:3]
2751        s_add_u32 s2, s2, routine-.
2752        s_add_u32 s3, s3, routine-.+4
2753        .cf_call routine
2754        s_swappc_b64 s[0:1], s[2:3]
2755       
2756        s_ashr_i32 sa[2], sa[2], 3
2757        s_ashr_i32 sa[3], sa[3], 3
2758        s_endpgm
2759       
2760routine:
2761        s_xor_b32 sa[2], sa[2], sa[4]
2762        s_xor_b32 sa[3], sa[3], sa[4]
2763        s_cbranch_scc1 bb1
2764       
2765        s_min_u32 sa[2], sa[2], sa[4]
2766        .cf_ret
2767        s_setpc_b64 s[0:1]
2768       
2769bb1:    s_and_b32 sa[2], sa[2], sa[4]
2770        .cf_ret
2771        s_setpc_b64 s[0:1]
2772)ffDXD",
2773        {
2774            // block 0
2775            { 0, 32,
2776                { { 4, true } },
2777                {
2778                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2779                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2780                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2781                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2782                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2783                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2784                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2785                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2786                }, true, false, false },
2787            // block 1
2788            { 32, 64,
2789                { { 4, true } },
2790                {
2791                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2792                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2793                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2794                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2795                    { { "sa", 2 }, SSAInfo(3, 5, 5, 5, 1, true) },
2796                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) }
2797                }, true, false, false },
2798            // block 2
2799            { 64, 104,
2800                { { 4, true } },
2801                {
2802                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2803                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2804                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2805                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2806                    { { "sa", 2 }, SSAInfo(3, 6, 6, 7, 2, true) },
2807                    { { "sa", 3 }, SSAInfo(2, 4, 4, 5, 2, true) }
2808                }, true, false, false },
2809            // block 3
2810            { 104, 116,
2811                { },
2812                {
2813                    { { "sa", 2 }, SSAInfo(3, 8, 8, 8, 1, true) },
2814                    { { "sa", 3 }, SSAInfo(2, 6, 6, 6, 1, true) }
2815                }, false, false, true},
2816            // block 4 - routine
2817            { 116, 128,
2818                { { 5, false }, { 6, false } },
2819                {
2820                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2821                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
2822                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2823                }, false, false, false },
2824            // block 5
2825            { 128, 136,
2826                { },
2827                {
2828                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2829                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2830                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
2831                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2832                }, false, true, true },
2833            // block 6
2834            { 136, 144,
2835                { },
2836                {
2837                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2838                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2839                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, true) },
2840                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2841                }, false, true, true }
2842        },
2843        {   // SSA replaces
2844            { { "sa", 2 }, { { 4, 3 }, { 5, 1 }, { 7, 1 } } },
2845            { { "sa", 3 }, { { 3, 1 }, { 5, 1 } } }
2846        },
2847        true, ""
2848    },
2849    {   // 23 - simple call, more complex routine (no use return)
2850        R"ffDXD(.regvar sa:s:8, va:v:8
2851        s_mov_b32 sa[2], s4
2852        s_mov_b32 sa[3], s5
2853       
2854        s_getpc_b64 s[2:3]
2855        s_add_u32 s2, s2, routine-.
2856        s_add_u32 s3, s3, routine-.+4
2857        .cf_call routine
2858        s_swappc_b64 s[0:1], s[2:3]
2859       
2860        s_lshl_b32 sa[3], sa[3], 4
2861        s_endpgm
2862       
2863routine:
2864        s_xor_b32 sa[2], sa[2], sa[4]
2865        s_xor_b32 sa[3], sa[3], sa[4]
2866        s_cbranch_scc1 bb1
2867       
2868        s_min_u32 sa[2], sa[2], sa[4]
2869        .cf_ret
2870        s_setpc_b64 s[0:1]
2871       
2872bb1:    s_and_b32 sa[2], sa[2], sa[4]
2873        .cf_ret
2874        s_setpc_b64 s[0:1]
2875)ffDXD",
2876        {
2877            { 0, 32,
2878                { { 2, true } },
2879                {
2880                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2881                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2882                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2883                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2884                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2885                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2886                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2887                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2888                }, true, false, false },
2889            // block 1 - after call
2890            { 32, 40,
2891                { },
2892                {
2893                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) }
2894                }, false, false, true },
2895            // block 2 - routine
2896            { 40, 52,
2897                { { 3, false }, { 4, false } },
2898                {
2899                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2900                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
2901                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2902                }, false, false, false },
2903            // block 3 - first return
2904            { 52, 60,
2905                { },
2906                {
2907                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2908                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2909                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
2910                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2911                }, false, true, true },
2912            // block 4 - second return
2913            { 60, 68,
2914                { },
2915                {
2916                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2917                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2918                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, true) },
2919                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2920                }, false, true, true }
2921        },
2922        { },
2923        true, ""
2924    },
2925    {   // 24 - simple call, more complex routine
2926        R"ffDXD(.regvar sa:s:8, va:v:8
2927        s_mov_b32 sa[2], s4
2928        s_mov_b32 sa[3], s5
2929       
2930        s_getpc_b64 s[2:3]
2931        s_add_u32 s2, s2, routine-.
2932        s_add_u32 s3, s3, routine-.+4
2933        .cf_call routine
2934        s_swappc_b64 s[0:1], s[2:3]
2935       
2936        s_lshl_b32 sa[2], sa[2], 3
2937        s_lshl_b32 sa[3], sa[3], 4
2938        s_endpgm
2939       
2940routine:
2941        s_xor_b32 sa[2], sa[2], sa[4]
2942        s_xor_b32 sa[3], sa[3], sa[4]
2943        s_cbranch_scc1 bb2
2944
2945        s_min_u32 sa[3], sa[3], sa[4]
2946        .cf_ret
2947        s_setpc_b64 s[0:1]
2948       
2949bb2:    s_min_u32 sa[2], sa[2], sa[4]
2950        .cf_ret
2951        s_setpc_b64 s[0:1]
2952)ffDXD",
2953        {
2954            { 0, 32,
2955                { { 2, true } },
2956                {
2957                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
2958                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
2959                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
2960                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
2961                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
2962                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
2963                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
2964                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
2965                }, true, false, false },
2966            // block 1 - after call
2967            { 32, 44,
2968                { },
2969                {
2970                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, true) },
2971                    { { "sa", 3 }, SSAInfo(2, 4, 4, 4, 1, true) }
2972                }, false, false, true },
2973            // block 2 - routine
2974            { 44, 56,
2975                { { 3, false }, { 4, false } },
2976                {
2977                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
2978                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
2979                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2980                }, false, false, false },
2981            // block 3 - first return
2982            { 56, 64,
2983                { },
2984                {
2985                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2986                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2987                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) },
2988                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2989                }, false, true, true },
2990            // block 4 - second return
2991            { 64, 72,
2992                { },
2993                {
2994                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
2995                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
2996                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
2997                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
2998                }, false, true, true }
2999        },
3000        {   // SSA replaces
3001            { { "sa", 2 }, { { 3, 2 } } },
3002            { { "sa", 3 }, { { 3, 2 } } }
3003        },
3004        true, ""
3005    },
3006    {   // 25 - nested calls
3007        R"ffDXD(.regvar sa:s:8, va:v:8
3008        s_mov_b32 sa[2], s4
3009        s_mov_b32 sa[3], s5
3010       
3011        s_getpc_b64 s[2:3]
3012        s_add_u32 s2, s2, routine-.
3013        s_add_u32 s3, s3, routine-.+4
3014        .cf_call routine
3015        s_swappc_b64 s[0:1], s[2:3]
3016       
3017        s_lshl_b32 sa[2], sa[2], 4
3018        s_lshl_b32 sa[3], sa[3], 4
3019       
3020        s_getpc_b64 s[2:3]
3021        s_add_u32 s2, s2, routine2-.
3022        s_add_u32 s3, s3, routine2-.+4
3023        .cf_call routine2
3024        s_swappc_b64 s[0:1], s[2:3]
3025       
3026        s_lshr_b32 sa[2], sa[2], 2
3027        s_min_u32 sa[2], sa[2], sa[3]
3028        s_lshr_b32 sa[3], sa[3], 2
3029        s_endpgm
3030       
3031routine:
3032        s_xor_b32 sa[2], sa[2], sa[4]
3033        s_xor_b32 sa[3], sa[3], sa[4]
3034        s_cbranch_scc1 bb1
3035       
3036        s_min_u32 sa[2], sa[2], sa[4]
3037       
3038        s_getpc_b64 s[2:3]
3039        s_add_u32 s2, s2, routine2-.
3040        s_add_u32 s3, s3, routine2-.+4
3041        .cf_call routine2
3042        s_swappc_b64 s[0:1], s[2:3]
3043       
3044        .cf_ret
3045        s_setpc_b64 s[0:1]
3046       
3047bb1:    s_and_b32 sa[2], sa[2], sa[4]
3048        .cf_ret
3049        s_setpc_b64 s[0:1]
3050
3051routine2:
3052        s_xor_b32 sa[2], sa[2], sa[4]
3053        s_xor_b32 sa[3], sa[3], sa[4]
3054        s_cbranch_scc1 bb2
3055
3056        s_min_u32 sa[3], sa[3], sa[4]
3057        .cf_ret
3058        s_setpc_b64 s[0:1]
3059       
3060bb2:    s_min_u32 sa[2], sa[2], sa[4]
3061        .cf_ret
3062        s_setpc_b64 s[0:1]
3063)ffDXD",
3064        {
3065            // block 0 - start
3066            { 0, 32,
3067                { { 3, true } },
3068                {
3069                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
3070                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
3071                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
3072                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
3073                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
3074                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
3075                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
3076                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
3077                }, true, false, false },
3078            // block 1
3079            { 32, 64,
3080                { { 7, true } },
3081                {
3082                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
3083                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
3084                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
3085                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
3086                    { { "sa", 2 }, SSAInfo(4, 7, 7, 7, 1, true) },
3087                    { { "sa", 3 }, SSAInfo(2, 5, 5, 5, 1, true) }
3088                }, true, false, false },
3089            // block 2
3090            { 64, 80,
3091                { },
3092                {
3093                    { { "sa", 2 }, SSAInfo(4, 8, 8, 9, 2, true) },
3094                    { { "sa", 3 }, SSAInfo(3, 6, 6, 6, 1, true) }
3095                }, false, false, true },
3096            // block 3 - routine
3097            { 80, 92,
3098                { { 4, false }, { 6, false } },
3099                {
3100                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
3101                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
3102                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3103                }, false, false, false },
3104            // block 4 - routine - first way bb0
3105            { 92, 120,
3106                { { 7, true } },
3107                {
3108                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
3109                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
3110                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
3111                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
3112                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
3113                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3114                }, true, false, false },
3115            // block 5 - routine - return 0
3116            { 120, 124,
3117                { },
3118                {
3119                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3120                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) }
3121                }, false, true, true },
3122            // block 6 - routine - bb1
3123            { 124, 132,
3124                { },
3125                {
3126                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3127                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3128                    { { "sa", 2 }, SSAInfo(2, 6, 6, 6, 1, true) },
3129                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3130                }, false, true, true },
3131            // block 7
3132            { 132, 144,
3133                { { 8, false }, { 9, false } },
3134                {
3135                    { { "sa", 2 }, SSAInfo(3, 4, 4, 4, 1, true) },
3136                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) },
3137                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3138                }, false, false, false },
3139            // block 8
3140            { 144, 152,
3141                { },
3142                {
3143                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3144                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3145                    { { "sa", 3 }, SSAInfo(3, 4, 4, 4, 1, true) },
3146                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3147                }, false, true, true },
3148            // block 9
3149            { 152, 160,
3150                { },
3151                {
3152                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3153                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3154                    { { "sa", 2 }, SSAInfo(4, 5, 5, 5, 1, true) },
3155                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3156                }, false, true, true }
3157        },
3158        {   // SSA replaces
3159            { { "sa", 2 }, { { 5, 4 }, { 6, 4 }, { 5, 4 }, { 7, 3 } } },
3160            { { "sa", 3 }, { { 3, 2 }, { 4, 2 }, { 4, 3 }, { 5, 2 } } }
3161        },
3162        true, ""
3163    },
3164    {   // 26 - many routines in single calls
3165        R"ffDXD(.regvar sa:s:8, va:v:8
3166        s_mov_b32 sa[2], s4
3167        s_mov_b32 sa[3], s5
3168        s_mov_b32 sa[4], s6
3169        s_mov_b32 sa[5], s7
3170       
3171        s_getpc_b64 s[2:3]
3172        s_add_u32 s2, s2, routine-.
3173        s_add_u32 s3, s3, routine-.+4
3174        .cf_call routine, routine2
3175        s_swappc_b64 s[0:1], s[2:3]
3176       
3177        s_lshl_b32 sa[2], sa[2], 6
3178        s_lshl_b32 sa[3], sa[3], 6
3179        s_lshl_b32 sa[4], sa[4], 6
3180        s_lshl_b32 sa[5], sa[5], 6
3181       
3182        s_getpc_b64 s[2:3]
3183        s_add_u32 s2, s2, routine2-.
3184        s_add_u32 s3, s3, routine2-.+4
3185        .cf_call routine2, routine3
3186        s_swappc_b64 s[0:1], s[2:3]
3187       
3188        s_lshl_b32 sa[2], sa[2], 4
3189        s_lshl_b32 sa[3], sa[3], 4
3190        s_lshl_b32 sa[4], sa[4], 4
3191        s_lshl_b32 sa[5], sa[5], 4
3192        s_endpgm
3193       
3194routine:
3195        s_xor_b32 sa[2], sa[2], sa[6]
3196        s_xor_b32 sa[3], sa[3], sa[6]
3197        s_cbranch_scc1 bb1
3198       
3199        s_min_u32 sa[2], sa[2], sa[6]
3200        .cf_ret
3201        s_setpc_b64 s[0:1]
3202       
3203bb1:    s_and_b32 sa[2], sa[2], sa[6]
3204        .cf_ret
3205        s_setpc_b64 s[0:1]
3206
3207routine2:
3208        s_xor_b32 sa[2], sa[2], sa[6]
3209        s_xor_b32 sa[4], sa[4], sa[6]
3210        s_cbranch_scc1 bb2
3211       
3212        s_min_u32 sa[2], sa[2], sa[6]
3213        .cf_ret
3214        s_setpc_b64 s[0:1]
3215       
3216bb2:    s_and_b32 sa[2], sa[2], sa[6]
3217        .cf_ret
3218        s_setpc_b64 s[0:1]
3219
3220routine3:
3221        s_xor_b32 sa[3], sa[3], sa[6]
3222        s_xor_b32 sa[5], sa[5], sa[6]
3223        s_cbranch_scc1 bb3
3224       
3225        s_min_u32 sa[3], sa[3], sa[6]
3226        .cf_ret
3227        s_setpc_b64 s[0:1]
3228       
3229bb3:    s_and_b32 sa[5], sa[5], sa[6]
3230        .cf_ret
3231        s_setpc_b64 s[0:1]
3232)ffDXD",
3233        {
3234            // block 0 - start
3235            { 0, 40,
3236                { { 3, true }, { 6, true } },
3237                {
3238                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
3239                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
3240                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
3241                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
3242                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
3243                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
3244                    { { "", 6 }, SSAInfo(0, 0, 0, 0, 0, true) },
3245                    { { "", 7 }, SSAInfo(0, 0, 0, 0, 0, true) },
3246                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
3247                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
3248                    { { "sa", 4 }, SSAInfo(0, 1, 1, 1, 1, false) },
3249                    { { "sa", 5 }, SSAInfo(0, 1, 1, 1, 1, false) }
3250                }, true, false, false },
3251            // block 1 - after first call
3252            { 40, 80,
3253                { { 6, true }, { 9, true } },
3254                {
3255                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
3256                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
3257                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
3258                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) },
3259                    { { "sa", 2 }, SSAInfo(3, 8, 8, 8, 1, true) },
3260                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) },
3261                    { { "sa", 4 }, SSAInfo(2, 3, 3, 3, 1, true) },
3262                    { { "sa", 5 }, SSAInfo(1, 2, 2, 2, 1, true) }
3263                }, true, false, false },
3264            // block 2 - end
3265            { 80, 100,
3266                { },
3267                {
3268                    { { "sa", 2 }, SSAInfo(3, 9, 9, 9, 1, true) },
3269                    { { "sa", 3 }, SSAInfo(4, 6, 6, 6, 1, true) },
3270                    { { "sa", 4 }, SSAInfo(2, 4, 4, 4, 1, true) },
3271                    { { "sa", 5 }, SSAInfo(3, 5, 5, 5, 1, true) }
3272                }, false, false, true },
3273            // block 3 - routine
3274            { 100, 112,
3275                { { 4, false }, { 5, false } },
3276                {
3277                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
3278                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
3279                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3280                }, false, false, false },
3281            // block 4 - routine way 0
3282            { 112, 120,
3283                { },
3284                {
3285                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3286                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3287                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
3288                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3289                }, false, true, true },
3290            // block 5 - routine way 1
3291            { 120, 128,
3292                { },
3293                {
3294                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3295                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3296                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, true) },
3297                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3298                }, false, true, true },
3299            // block 6 - routine 2
3300            { 128, 140,
3301                { { 7, false }, { 8, false } },
3302                {
3303                    { { "sa", 2 }, SSAInfo(1, 5, 5, 5, 1, true) },
3304                    { { "sa", 4 }, SSAInfo(1, 2, 2, 2, 1, true) },
3305                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3306                }, false, false, false },
3307            // block 7 - routine 2 way 0
3308            { 140, 148,
3309                { },
3310                {
3311                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3312                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3313                    { { "sa", 2 }, SSAInfo(5, 6, 6, 6, 1, true) },
3314                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3315                }, false, true, true },
3316            // block 8 - routine 2 way 1
3317            { 148, 156,
3318                { },
3319                {
3320                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3321                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3322                    { { "sa", 2 }, SSAInfo(5, 7, 7, 7, 1, true) },
3323                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3324                }, false, true, true },
3325            // block 9 - routine 3
3326            { 156, 168,
3327                { { 10, false }, { 11, false } },
3328                {
3329                    { { "sa", 3 }, SSAInfo(3, 4, 4, 4, 1, true) },
3330                    { { "sa", 5 }, SSAInfo(2, 3, 3, 3, 1, true) },
3331                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3332                }, false, false, false },
3333            // block 10 - routine 3 way 0
3334            { 168, 176,
3335                { },
3336                {
3337                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3338                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3339                    { { "sa", 3 }, SSAInfo(4, 5, 5, 5, 1, true) },
3340                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3341                }, false, true, true },
3342            // block 11 - routine 3 way 1
3343            { 176, 184,
3344                { },
3345                {
3346                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3347                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3348                    { { "sa", 5 }, SSAInfo(3, 4, 4, 4, 1, true) },
3349                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3350                }, false, true, true  }
3351        },
3352        {   // SSA replaces
3353            { { "sa", 2 }, { { 4, 3 }, { 6, 3 }, { 7, 3 }, { 8, 1 } } },
3354            { { "sa", 3 }, { { 5, 4 } } },
3355            { { "sa", 4 }, { { 3, 1 } } },
3356            { { "sa", 5 }, { { 4, 3 } } }
3357        },
3358        true, ""
3359    },
3360    {   // 27 - conflicts inside routines
3361        R"ffDXD(.regvar sa:s:8, va:v:8
3362        s_mov_b32 sa[2], s4
3363        s_mov_b32 sa[3], s5
3364        s_mov_b32 sa[4], s6
3365        s_cbranch_scc1 aa0
3366       
3367        s_getpc_b64 s[2:3]
3368        s_add_u32 s2, s2, routine1-.
3369        s_add_u32 s3, s3, routine1-.+4
3370        .cf_call routine1
3371        s_swappc_b64 s[0:1], s[2:3]
3372       
3373        s_and_b32 sa[5], sa[5], s0
3374       
3375aa0:    s_getpc_b64 s[2:3]
3376        s_add_u32 s2, s2, routine2-.
3377        s_add_u32 s3, s3, routine2-.+4
3378        .cf_call routine2
3379        s_swappc_b64 s[0:1], s[2:3]
3380       
3381        s_lshr_b32 sa[2], sa[2], 2
3382        s_min_u32 sa[2], sa[2], sa[3]
3383        s_lshr_b32 sa[3], sa[3], 2
3384        s_endpgm
3385       
3386routine1:
3387        s_xor_b32 sa[2], sa[2], sa[6]
3388        s_xor_b32 sa[3], sa[3], sa[6]
3389        s_cbranch_scc1 bb1
3390       
3391        s_min_u32 sa[2], sa[2], sa[6]
3392        s_and_b32 sa[4], sa[4], sa[6]
3393        .cf_ret
3394        s_setpc_b64 s[0:1]
3395       
3396bb1:    s_and_b32 sa[2], sa[2], sa[6]
3397        s_and_b32 sa[4], sa[4], sa[6]
3398        .cf_ret
3399        s_setpc_b64 s[0:1]
3400       
3401routine2:
3402        s_xor_b32 sa[2], sa[2], sa[6]
3403        s_xor_b32 sa[3], sa[3], sa[6]
3404        s_cbranch_scc1 bb2
3405       
3406        s_min_u32 sa[2], sa[2], sa[6]
3407        s_max_u32 sa[4], sa[4], sa[6]
3408        .cf_ret
3409        s_setpc_b64 s[0:1]
3410       
3411bb2:    s_and_b32 sa[3], sa[3], sa[6]
3412        .cf_ret
3413        s_setpc_b64 s[0:1]
3414)ffDXD",
3415        {
3416            // block 0 - start
3417            { 0, 16,
3418                { { 1, false }, { 3, false } },
3419                {
3420                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
3421                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
3422                    { { "", 6 }, SSAInfo(0, 0, 0, 0, 0, true) },
3423                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
3424                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
3425                    { { "sa", 4 }, SSAInfo(0, 1, 1, 1, 1, false) }
3426                }, false, false, false },
3427            // block 1 - call routine1
3428            { 16, 40,
3429                { { 5, true } },
3430                {
3431                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
3432                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
3433                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
3434                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) }
3435                }, true, false, false },
3436            // block 2 - before aa0
3437            { 40, 44,
3438                { },
3439                {
3440                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3441                    { { "sa", 5 }, SSAInfo(0, 1, 1, 1, 1, true) }
3442                }, false, false, false },
3443            // block 3 - aa0
3444            { 44, 68,
3445                { { 8, true } },
3446                {
3447                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
3448                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
3449                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, false) },
3450                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, false) }
3451                }, true, false, false },
3452            // block 4 - end
3453            { 68, 84,
3454                { },
3455                {
3456                    { { "sa", 2 }, SSAInfo(5, 7, 7, 8, 2, true) },
3457                    { { "sa", 3 }, SSAInfo(3, 5, 5, 5, 1, true) }
3458                }, false, false, true },
3459            // block 5 - routine1
3460            { 84, 96,
3461                { { 6, false }, { 7, false } },
3462                {
3463                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
3464                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
3465                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3466                }, false, false, false },
3467            // block 6 - routine1 way 1
3468            { 96, 108,
3469                { },
3470                {
3471                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3472                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3473                    { { "sa", 2 }, SSAInfo(2, 3, 3, 3, 1, true) },
3474                    { { "sa", 4 }, SSAInfo(1, 2, 2, 2, 1, true) },
3475                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3476                }, false, true, true },
3477            // block 7 - routine1 way 2
3478            { 108, 120,
3479                { },
3480                {
3481                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3482                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3483                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, true) },
3484                    { { "sa", 4 }, SSAInfo(1, 3, 3, 3, 1, true) },
3485                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3486                }, false, true, true },
3487            // block 8 - routine 2
3488            { 120, 132,
3489                { { 9, false }, { 10, false } },
3490                {
3491                    { { "sa", 2 }, SSAInfo(3, 5, 5, 5, 1, true) },
3492                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) },
3493                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3494                }, false, false, false },
3495            // block 9 - routine 2 way 0
3496            { 132, 144,
3497                { },
3498                {
3499                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3500                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3501                    { { "sa", 2 }, SSAInfo(5, 6, 6, 6, 1, true) },
3502                    { { "sa", 4 }, SSAInfo(2, 4, 4, 4, 1, true) },
3503                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3504                }, false, true, true },
3505            // block 10 - routine 2 way 1
3506            { 144, 152,
3507                { },
3508                {
3509                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3510                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3511                    { { "sa", 3 }, SSAInfo(3, 4, 4, 4, 1, true) },
3512                    { { "sa", 6 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3513                }, false, true, true }
3514        },
3515        {   // SSA replaces
3516            { { "sa", 2 }, { { 4, 3 }, { 6, 5 }, { 3, 1 } } },
3517            { { "sa", 3 }, { { 4, 3 }, { 2, 1 } } },
3518            { { "sa", 4 }, { { 3, 2 }, { 2, 1 } } }
3519        },
3520        true, ""
3521    },
3522    {  // 28 - res second point cache test 1
3523        R"ffDXD(.regvar sa:s:8, va:v:8, xa:s:8
3524        s_mov_b32 sa[2], s4
3525        s_mov_b32 sa[3], s5
3526        s_mov_b32 sa[4], s6
3527        .cf_cjump aa0, bb0, cc0
3528        s_setpc_b64 s[0:1]
3529       
3530        s_mov_b32 sa[3], s3
3531        s_mov_b32 sa[6], s3
3532        s_branch mainx
3533       
3534aa0:    s_mov_b32 sa[2], s2
3535        s_mov_b32 sa[6], s2
3536        s_cbranch_scc0 mainx
3537       
3538        s_mov_b32 sa[4], s5
3539        s_branch mainx
3540
3541bb0:    v_mov_b32 va[3], 4
3542        v_mov_b32 va[2], v6
3543        s_cbranch_scc0 mainy
3544       
3545        v_mov_b32 va[0], v6
3546        v_mov_b32 va[4], v6
3547        s_branch mainy
3548       
3549cc0:    s_mov_b32 xa[3], 4
3550        s_mov_b32 xa[4], 4
3551        s_cbranch_scc0 mainz
3552       
3553        s_mov_b32 xa[0], s6
3554        s_mov_b32 xa[3], s6
3555        s_cbranch_scc0 mainz
3556       
3557        s_mov_b32 xa[0], s6
3558       
3559mainx:
3560        s_add_u32 sa[2], sa[2], sa[7]
3561        s_add_u32 sa[3], sa[3], sa[7]
3562        s_sub_u32 sa[4], sa[4], sa[7]
3563        s_add_u32 sa[5], sa[5], sa[7]
3564       
3565        v_xor_b32 va[2], va[2], va[1]
3566        s_add_u32 xa[0], xa[0], xa[7]
3567        s_cbranch_scc0 mainz
3568       
3569mainy:
3570        v_xor_b32 va[0], va[0], va[1]
3571        v_xor_b32 va[2], va[2], va[1]
3572        v_xor_b32 va[3], va[3], va[1]
3573        v_xor_b32 va[4], va[4], va[1]
3574        s_endpgm
3575       
3576mainz:
3577        s_add_u32 xa[0], xa[0], xa[7]
3578        s_add_u32 xa[3], xa[3], xa[7]
3579        s_sub_u32 xa[4], xa[4], xa[7]
3580        s_add_u32 xa[5], xa[5], xa[7]
3581        s_add_u32 sa[6], sa[6], sa[7]
3582        s_add_u32 sa[3], sa[3], sa[7]
3583        s_sub_u32 sa[4], sa[4], sa[7]
3584        s_add_u32 sa[5], sa[5], sa[7]
3585        s_endpgm
3586)ffDXD",
3587        {
3588            {   // block 0 - start
3589                0, 16,
3590                { { 1, false }, { 2, false }, { 4, false }, { 6, false } },
3591                {
3592                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3593                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3594                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
3595                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
3596                    { { "", 6 }, SSAInfo(0, 0, 0, 0, 0, true) },
3597                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
3598                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
3599                    { { "sa", 4 }, SSAInfo(0, 1, 1, 1, 1, false) }
3600                }, false, false, false },
3601            {   // block 1 - before aa0
3602                16, 28,
3603                { { 9, false } },
3604                {
3605                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
3606                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, false) },
3607                    { { "sa", 6 }, SSAInfo(0, 1, 1, 1, 1, false) }
3608                }, false, false, true },
3609            {   // block 2 - aa0
3610                28, 40,
3611                { { 3, false }, { 9, false } },
3612                {
3613                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
3614                    { { "sa", 2 }, SSAInfo(1, 3, 3, 3, 1, false) },
3615                    { { "sa", 6 }, SSAInfo(0, 3, 3, 3, 1, false) }
3616                }, false, false, false },
3617            {   // block 3 - after aa0
3618                40, 48,
3619                { { 9, false } },
3620                {
3621                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
3622                    { { "sa", 4 }, SSAInfo(1, 4, 4, 4, 1, false) }
3623                }, false, false, true },
3624            {   // block 4 - bb0
3625                48, 60,
3626                { { 5, false }, { 10, false } },
3627                {
3628                    { { "", 256+6 }, SSAInfo(0, 0, 0, 0, 0, true) },
3629                    { { "va", 2 }, SSAInfo(0, 3, 3, 3, 1, false) },
3630                    { { "va", 3 }, SSAInfo(0, 2, 2, 2, 1, false) }
3631                }, false, false, false },
3632            {   // block 5 - after bb0
3633                60, 72,
3634                { { 10, false } },
3635                {
3636                    { { "", 256+6 }, SSAInfo(0, 0, 0, 0, 0, true) },
3637                    { { "va", 0 }, SSAInfo(0, 2, 2, 2, 1, false) },
3638                    { { "va", 4 }, SSAInfo(0, 2, 2, 2, 1, false) }
3639                }, false, false, true },
3640            {   // block 6 - cc0
3641                72, 84,
3642                { { 7, false }, { 11, false } },
3643                {
3644                    { { "xa", 3 }, SSAInfo(0, 2, 2, 2, 1, false) },
3645                    { { "xa", 4 }, SSAInfo(0, 2, 2, 2, 1, false) }
3646                }, false, false, false },
3647            {   // block 7 - after cc0
3648                84, 96,
3649                { { 8, false }, { 11, false } },
3650                {
3651                    { { "", 6 }, SSAInfo(0, 0, 0, 0, 0, true) },
3652                    { { "xa", 0 }, SSAInfo(0, 3, 3, 3, 1, false) },
3653                    { { "xa", 3 }, SSAInfo(2, 3, 3, 3, 1, false) }
3654                }, false, false, false },
3655            {   // block 8 - before mainx
3656                96, 100,
3657                { },
3658                {
3659                    { { "", 6 }, SSAInfo(0, 0, 0, 0, 0, true) },
3660                    { { "xa", 0 }, SSAInfo(3, 4, 4, 4, 1, false) }
3661                }, false, false, false },
3662            {   // block 9 - mainx
3663                100, 128,
3664                { { 10, false }, { 11, false } },
3665                {
3666                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
3667                    { { "sa", 3 }, SSAInfo(2, 3, 3, 3, 1, true) },
3668                    { { "sa", 4 }, SSAInfo(1, 2, 2, 2, 1, true) },
3669                    { { "sa", 5 }, SSAInfo(0, 1, 1, 1, 1, true) },
3670                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3671                    { { "va", 1 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3672                    { { "va", 2 }, SSAInfo(0, 1, 1, 1, 1, true) },
3673                    { { "xa", 0 }, SSAInfo(0, 1, 1, 1, 1, true) },
3674                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3675                }, false, false, false },
3676            {   // block 10 - mainy
3677                128, 148,
3678                { },
3679                {
3680                    { { "va", 0 }, SSAInfo(0, 1, 1, 1, 1, true) },
3681                    { { "va", 1 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3682                    { { "va", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
3683                    { { "va", 3 }, SSAInfo(0, 1, 1, 1, 1, true) },
3684                    { { "va", 4 }, SSAInfo(0, 1, 1, 1, 1, true) }
3685                }, false, false, true },
3686            {   // block 11 - mainz
3687                148, 184,
3688                { },
3689                {
3690                    { { "sa", 3 }, SSAInfo(3, 4, 4, 4, 1, true) },
3691                    { { "sa", 4 }, SSAInfo(2, 3, 3, 3, 1, true) },
3692                    { { "sa", 5 }, SSAInfo(1, 2, 2, 2, 1, true) },
3693                    { { "sa", 6 }, SSAInfo(1, 2, 2, 2, 1, true) },
3694                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3695                    { { "xa", 0 }, SSAInfo(1, 2, 2, 2, 1, true) },
3696                    { { "xa", 3 }, SSAInfo(0, 1, 1, 1, 1, true) },
3697                    { { "xa", 4 }, SSAInfo(0, 1, 1, 1, 1, true) },
3698                    { { "xa", 5 }, SSAInfo(0, 1, 1, 1, 1, true) },
3699                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3700                }, false, false, true },
3701        },
3702        {   // SSA replaces
3703            { { "sa", 2 }, { { 3, 1 }, { 3, 1 } } },
3704            { { "sa", 3 }, { { 2, 1 }, { 2, 1 }, { 2, 1 }, { 3, 1 }, { 3, 1 } } },
3705            { { "sa", 4 }, { { 4, 1 }, { 2, 1 }, { 2, 1 } } },
3706            { { "sa", 6 }, { { 3, 1 }, { 3, 1 } } },
3707            { { "va", 0 }, { { 2, 0 } } },
3708            { { "va", 2 }, { { 3, 1 }, { 3, 1 } } },
3709            { { "va", 3 }, { { 2, 0 }, { 2, 0 } } },
3710            { { "va", 4 }, { { 2, 0 } } },
3711            { { "xa", 0 }, { { 4, 0 }, { 3, 1 } } },
3712            { { "xa", 3 }, { { 3, 0 }, { 3, 0 }, { 2, 0 } } },
3713            { { "xa", 4 }, { { 2, 0 }, { 2, 0 }, { 2, 0 } } }
3714        },
3715        true, ""
3716    },
3717    {   // 29 - cache test 2: loop
3718        R"ffDXD(.regvar sa:s:8, va:v:8, xa:s:8
3719        s_mov_b32 sa[2], s4
3720        s_mov_b32 sa[3], s5
3721        s_mov_b32 sa[4], s6
3722        s_mov_b32 sa[5], s7
3723        s_mov_b32 xa[0], s4
3724        .cf_cjump aa0, aa1, aa2, aa3
3725        s_setpc_b64 s[0:1]
3726       
3727loop:   s_xor_b32 sa[2], sa[2], sa[7]
3728        s_xor_b32 xa[0], xa[0], xa[7]
3729       
3730l1:     s_xor_b32 sa[3], sa[3], sa[7]
3731        s_xor_b32 xa[0], xa[0], xa[7]
3732       
3733l2:     s_xor_b32 sa[4], sa[4], sa[7]
3734        s_xor_b32 xa[0], xa[0], xa[7]
3735
3736l3:     s_xor_b32 sa[5], sa[5], sa[7]
3737        s_xor_b32 xa[0], xa[0], xa[7]
3738        s_cbranch_scc0 loop
3739       
3740        s_endpgm
3741       
3742aa0:    s_xor_b32 sa[5], sa[5], sa[7]
3743        s_xor_b32 xa[0], xa[0], xa[7]
3744        s_branch loop
3745
3746aa1:    s_xor_b32 sa[2], sa[2], sa[7]
3747        s_xor_b32 xa[0], xa[0], xa[7]
3748        s_branch l1
3749
3750aa2:    s_xor_b32 sa[3], sa[3], sa[7]
3751        s_xor_b32 xa[0], xa[0], xa[7]
3752        s_branch l2
3753
3754aa3:    s_xor_b32 sa[4], sa[4], sa[7]
3755        s_xor_b32 xa[0], xa[0], xa[7]
3756        s_branch l3
3757)ffDXD",
3758        {
3759            {   // block 0 - start
3760                0, 24,
3761                { { 1, false }, { 6, false }, { 7, false }, { 8, false }, { 9, false } },
3762                {
3763                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, true) },
3764                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, true) },
3765                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
3766                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
3767                    { { "", 6 }, SSAInfo(0, 0, 0, 0, 0, true) },
3768                    { { "", 7 }, SSAInfo(0, 0, 0, 0, 0, true) },
3769                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
3770                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
3771                    { { "sa", 4 }, SSAInfo(0, 1, 1, 1, 1, false) },
3772                    { { "sa", 5 }, SSAInfo(0, 1, 1, 1, 1, false) },
3773                    { { "xa", 0 }, SSAInfo(0, 1, 1, 1, 1, false) }
3774                }, false, false, false },
3775            {   // block 1 - loop
3776                24, 32,
3777                { },
3778                {
3779                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
3780                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3781                    { { "xa", 0 }, SSAInfo(1, 2, 2, 2, 1, true) },
3782                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3783                }, false, false, false },
3784            {   // block 2 - l1
3785                32, 40,
3786                { },
3787                {
3788                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) },
3789                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3790                    { { "xa", 0 }, SSAInfo(2, 3, 3, 3, 1, true) },
3791                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3792                }, false, false, false },
3793            {   // block 3 - l2
3794                40, 48,
3795                { },
3796                {
3797                    { { "sa", 4 }, SSAInfo(1, 2, 2, 2, 1, true) },
3798                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3799                    { { "xa", 0 }, SSAInfo(3, 4, 4, 4, 1, true) },
3800                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3801                }, false, false, false },
3802            {   // block 4 - l3
3803                48, 60,
3804                { { 1, false }, { 5, false } },
3805                {
3806                    { { "sa", 5 }, SSAInfo(1, 2, 2, 2, 1, true) },
3807                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3808                    { { "xa", 0 }, SSAInfo(4, 5, 5, 5, 1, true) },
3809                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3810                }, false, false, false },
3811            {   // block 5 - end
3812                60, 64,
3813                { },
3814                { }, false, false, true },
3815            {   // block 6 - aa0
3816                64, 76,
3817                { { 1, false } },
3818                {
3819                    { { "sa", 5 }, SSAInfo(1, 3, 3, 3, 1, true) },
3820                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3821                    { { "xa", 0 }, SSAInfo(1, 6, 6, 6, 1, true) },
3822                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3823                }, false, false, true },
3824            {   // block 7 - aa1
3825                76, 88,
3826                { { 2, false } },
3827                {
3828                    { { "sa", 2 }, SSAInfo(1, 3, 3, 3, 1, true) },
3829                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3830                    { { "xa", 0 }, SSAInfo(1, 7, 7, 7, 1, true) },
3831                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3832                }, false, false, true },
3833            {   // block 9 - aa2
3834                88, 100,
3835                { { 3, false } },
3836                {
3837                    { { "sa", 3 }, SSAInfo(1, 3, 3, 3, 1, true) },
3838                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3839                    { { "xa", 0 }, SSAInfo(1, 8, 8, 8, 1, true) },
3840                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3841                }, false, false, true },
3842            {   // block 10 - aa3
3843                100, 112,
3844                { { 4, false } },
3845                {
3846                    { { "sa", 4 }, SSAInfo(1, 3, 3, 3, 1, true) },
3847                    { { "sa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3848                    { { "xa", 0 }, SSAInfo(1, 9, 9, 9, 1, true) },
3849                    { { "xa", 7 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
3850                }, false, false, true }
3851        },
3852        {   // SSA replaces
3853            { { "sa", 2 }, { { 2, 1 }, { 3, 1 } } },
3854            { { "sa", 3 }, { { 2, 1 }, { 3, 1 } } },
3855            { { "sa", 4 }, { { 2, 1 }, { 3, 1 } } },
3856            { { "sa", 5 }, { { 2, 1 }, { 3, 1 } } },
3857            { { "xa", 0 }, { { 5, 1 }, { 6, 1 }, { 7, 2 }, { 8, 3 }, { 9, 4 } } }
3858        },
3859        true, ""
3860    },
3861#if 0
3862    {   // 30 - routine with loop
3863        R"ffDXD(.regvar sa:s:8, va:v:8, xa:s:8
3864        s_mov_b32 sa[2], s4
3865        s_mov_b32 sa[3], s5
3866        s_mov_b32 sa[4], s6
3867        s_mov_b32 sa[5], s7
3868       
3869        .cf_call routine
3870        s_swappc_b64 s[0:1], s[2:3]
3871       
3872        s_xor_b32 sa[5], sa[5], sa[0]
3873        s_xor_b32 sa[2], sa[2], sa[0]
3874       
3875        .cf_call routine
3876        s_swappc_b64 s[0:1], s[2:3]
3877       
3878        s_endpgm
3879       
3880routine:
3881        s_add_u32 sa[2], sa[2], sa[0]
3882        s_add_u32 sa[3], sa[3], sa[1]
3883       
3884loop0:
3885        s_add_u32 sa[4], sa[3], sa[0]
3886        s_add_u32 sa[5], sa[3], sa[5]
3887        s_cbranch_scc1 j1
3888       
3889j0:     s_add_u32 sa[2], sa[3], sa[0]
3890        s_branch loopend
3891
3892j1:     s_add_u32 sa[5], sa[2], sa[0]
3893
3894loopend:
3895        s_add_u32 sa[5], sa[5], sa[1]
3896        s_cbranch_scc0 loop0
3897       
3898        s_add_u32 sa[5], sa[5], sa[0]
3899        s_add_u32 sa[3], sa[3], sa[1]
3900        .cf_ret
3901        s_setpc_b64 s[0:1]
3902)ffDXD",
3903        {
3904            {   // block 0 - start
3905                0, 20,
3906                { { 3, true } },
3907                {
3908                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
3909                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
3910                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
3911                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
3912                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
3913                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
3914                    { { "", 6 }, SSAInfo(0, 0, 0, 0, 0, true) },
3915                    { { "", 7 }, SSAInfo(0, 0, 0, 0, 0, true) },
3916                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
3917                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) },
3918                    { { "sa", 4 }, SSAInfo(0, 1, 1, 1, 1, false) },
3919                    { { "sa", 5 }, SSAInfo(0, 1, 1, 1, 1, false) }
3920                }, true, false, false },
3921            {   // block 1 - before second call
3922                20, 32,
3923                { { 3, true } },
3924                {
3925                    { { "", 0 }, SSAInfo(0, 0, 0, 0, 0, false) },
3926                    { { "", 1 }, SSAInfo(0, 0, 0, 0, 0, false) },
3927                    { { "", 2 }, SSAInfo(0, 0, 0, 0, 0, true) },
3928                    { { "", 3 }, SSAInfo(0, 0, 0, 0, 0, true) },
3929                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3930                    { { "sa", 2 }, SSAInfo(2, 4, 4, 4, 1, true) },
3931                    { { "sa", 5 }, SSAInfo(2, 6, 6, 6, 1, true) }
3932                }, true, false, false },
3933            {   // block 2 - end
3934                32, 36,
3935                { },
3936                { }, false, false, true },
3937            {   // block 3 - routine
3938                36, 44,
3939                { },
3940                {
3941                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3942                    { { "sa", 1 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3943                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
3944                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, true) }
3945                }, false, false, false },
3946            {   // block 4 - loop
3947                44, 56,
3948                { { 5, false }, { 6, false } },
3949                {
3950                    { { "sa", 0 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) },
3951                    { { "sa", 3 }, SSAInfo(2, SIZE_MAX, 3, SIZE_MAX, 0, true) },