From: Wolfgang Bumiller Date: Sun, 15 Sep 2019 08:07:06 +0000 (+0200) Subject: ir: fix generation of multi-op vinstrs X-Git-Tag: xonotic-v0.8.5~14 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=2d4a054440e9fdf12edc202188ae4ea2e4ce90b5 ir: fix generation of multi-op vinstrs Do not assume that the destination is a temporary location, as our peephole optimizer will break this. For example, the following IR code (generated via from `x ^= gety()`): (0) binst6 <- BITXOR x, call5 (0) x <- STORE_F binst6 after peephole optimization becomes: (7) x <- BITXOR x, call5 Therefore we cannot assume that the output of the virtual xor instruction can be utilized as a temporary value. BITXOR becomes `(x | y) - (x & y)`, which would wrongly be generated as: x = x | y; temp0 = x & y; x = x - temp0; While this particular case can be fixed by using temp0 first and then x, the cross-product case would not be so simple. Signed-off-by: Wolfgang Bumiller Fixes #190 --- diff --git a/ir.cpp b/ir.cpp index 8388aab..0f7989f 100644 --- a/ir.cpp +++ b/ir.cpp @@ -2515,7 +2515,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc stmt.opcode = INSTR_BITOR; stmt.o1.s1 = instr->_m_ops[1]->codeAddress(); stmt.o2.s1 = instr->_m_ops[2]->codeAddress(); - stmt.o3.s1 = instr->_m_ops[0]->codeAddress(); + stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress(); code_push_statement(code, &stmt, instr->m_context); stmt.opcode = INSTR_BITAND; stmt.o1.s1 = instr->_m_ops[1]->codeAddress(); @@ -2523,7 +2523,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc stmt.o3.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress(); code_push_statement(code, &stmt, instr->m_context); stmt.opcode = INSTR_SUB_F; - stmt.o1.s1 = instr->_m_ops[0]->codeAddress(); + stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress(); stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress(); stmt.o3.s1 = instr->_m_ops[0]->codeAddress(); code_push_statement(code, &stmt, instr->m_context); @@ -2575,7 +2575,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc stmt.opcode = INSTR_BITOR; stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j; stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + j; - stmt.o3.s1 = instr->_m_ops[0]->codeAddress() + j; + stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress() + j; code_push_statement(code, &stmt, instr->m_context); stmt.opcode = INSTR_BITAND; stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j; @@ -2584,7 +2584,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc code_push_statement(code, &stmt, instr->m_context); } stmt.opcode = INSTR_SUB_V; - stmt.o1.s1 = instr->_m_ops[0]->codeAddress(); + stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress(); stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress(); stmt.o3.s1 = instr->_m_ops[0]->codeAddress(); code_push_statement(code, &stmt, instr->m_context); @@ -2632,7 +2632,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc stmt.opcode = INSTR_BITOR; stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j; stmt.o2.s1 = instr->_m_ops[2]->codeAddress(); - stmt.o3.s1 = instr->_m_ops[0]->codeAddress() + j; + stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress() + j; code_push_statement(code, &stmt, instr->m_context); stmt.opcode = INSTR_BITAND; stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j; @@ -2641,7 +2641,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc code_push_statement(code, &stmt, instr->m_context); } stmt.opcode = INSTR_SUB_V; - stmt.o1.s1 = instr->_m_ops[0]->codeAddress(); + stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress(); stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress(); stmt.o3.s1 = instr->_m_ops[0]->codeAddress(); code_push_statement(code, &stmt, instr->m_context); @@ -2655,7 +2655,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc for (j = 0; j < 3; ++j) { stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + (j + 1) % 3; stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + (j + 2) % 3; - stmt.o3.s1 = instr->_m_ops[0]->codeAddress() + j; + stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress() + j; code_push_statement(code, &stmt, instr->m_context); stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + (j + 2) % 3; stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + (j + 1) % 3; @@ -2663,7 +2663,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc code_push_statement(code, &stmt, instr->m_context); } stmt.opcode = INSTR_SUB_V; - stmt.o1.s1 = instr->_m_ops[0]->codeAddress(); + stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress(); stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress(); stmt.o3.s1 = instr->_m_ops[0]->codeAddress(); code_push_statement(code, &stmt, instr->m_context);