1 /*
2 * Copyright 2024 Alyssa Rosenzweig
3 * Copyright 2022 Collabora, Ltd.
4 * SPDX-License-Identifier: MIT
5 */
6
7 #include "agx_builder.h"
8 #include "agx_compiler.h"
9 #include "agx_test.h"
10
11 #include <gtest/gtest.h>
12
13 static void
pass(agx_context * ctx)14 pass(agx_context *ctx)
15 {
16 agx_repair_ssa(ctx);
17 agx_reindex_ssa(ctx);
18 }
19
20 #define CASE(instr) \
21 INSTRUCTION_CASE( \
22 { \
23 bool repaired = false; \
24 instr \
25 }, \
26 { \
27 bool repaired = true; \
28 instr \
29 }, \
30 pass)
31
32 class RepairSSA : public testing::Test {
33 protected:
RepairSSA()34 RepairSSA()
35 {
36 mem_ctx = ralloc_context(NULL);
37 }
38
~RepairSSA()39 ~RepairSSA()
40 {
41 ralloc_free(mem_ctx);
42 }
43
44 void *mem_ctx;
45 };
46
47 static agx_index
agx_phi_2(agx_builder * b,agx_index x,agx_index y)48 agx_phi_2(agx_builder *b, agx_index x, agx_index y)
49 {
50 agx_index idx = agx_temp(b->shader, x.size);
51 agx_instr *phi = agx_phi_to(b, idx, 2);
52 phi->src[0] = x;
53 phi->src[1] = y;
54 return idx;
55 }
56
TEST_F(RepairSSA,Local)57 TEST_F(RepairSSA, Local)
58 {
59 CASE({
60 agx_index x = agx_mov_imm(b, AGX_SIZE_32, 0xcafe);
61 agx_index y = agx_mov_imm(b, AGX_SIZE_32, 0xefac);
62
63 if (repaired) {
64 agx_unit_test(b, agx_fadd(b, y, x));
65 } else {
66 agx_fadd_to(b, x, y, x);
67 agx_unit_test(b, x);
68 }
69 });
70 }
71
72 /* A
73 * / \
74 * B C
75 * \ /
76 * D
77 */
TEST_F(RepairSSA,IfElse)78 TEST_F(RepairSSA, IfElse)
79 {
80 CASE({
81 agx_block *A = agx_start_block(b->shader);
82 agx_block *B = agx_test_block(b->shader);
83 agx_block *C = agx_test_block(b->shader);
84 agx_block *D = agx_test_block(b->shader);
85
86 agx_block_add_successor(A, B);
87 agx_block_add_successor(A, C);
88
89 agx_block_add_successor(B, D);
90 agx_block_add_successor(C, D);
91
92 b->cursor = agx_after_block(B);
93 agx_index x = agx_mov_imm(b, 32, 0xcafe);
94 agx_index y = agx_mov_imm(b, 32, 0xbade);
95
96 b->cursor = agx_after_block(C);
97 agx_index x2 = repaired ? agx_temp(b->shader, AGX_SIZE_32) : x;
98 agx_mov_imm_to(b, x2, 0xefac);
99 agx_index y2 = agx_mov_imm(b, 32, 0xbade);
100
101 b->cursor = agx_after_block(D);
102 if (repaired)
103 x = agx_phi_2(b, x, x2);
104
105 agx_index y3 = agx_phi_2(b, y, y2);
106 agx_unit_test(b, agx_fadd(b, x, y3));
107 });
108 }
109