From: Rudolf Polzer Date: Tue, 27 Aug 2013 10:27:20 +0000 (+0200) Subject: Fix XOR maths for overlapping inputs by setting the lifetimes correctly. X-Git-Tag: 0.3.5~136 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=abfe98ce8abc17f201c95b4bf0a8b938e2eae671;p=xonotic%2Fgmqcc.git Fix XOR maths for overlapping inputs by setting the lifetimes correctly. Signed-off-by: Rudolf Polzer --- diff --git a/ir.c b/ir.c index 56c91e5..7a04e3b 100644 --- a/ir.c +++ b/ir.c @@ -642,7 +642,7 @@ static bool ir_function_pass_peephole(ir_function *self) if (!instr_is_operation(oper->opcode)) continue; - /* Old engine's mul for vector+float cannot deal with aliased inputs. */ + /* Don't change semantics of MUL_VF in engines where these may not alias. */ if (OPTS_FLAG(LEGACY_VECTOR_MATHS)) { if (oper->opcode == INSTR_MUL_VF && oper->_ops[2]->memberof == oper->_ops[1]) continue; @@ -650,18 +650,6 @@ static bool ir_function_pass_peephole(ir_function *self) continue; } - /* Emulated bitxor cannot deal with aliased inputs. */ - if (oper->opcode == VINSTR_BITXOR && oper->_ops[2]->memberof == oper->_ops[1]) - continue; - - /* Emulated bitand/bitor for vector+float cannot deal with aliased inputs. */ - if (oper->opcode == VINSTR_BITAND_VF && oper->_ops[2]->memberof == oper->_ops[1]) - continue; - if (oper->opcode == VINSTR_BITOR_VF && oper->_ops[2]->memberof == oper->_ops[1]) - continue; - if (oper->opcode == VINSTR_BITXOR_VF && oper->_ops[2]->memberof == oper->_ops[1]) - continue; - value = oper->_ops[0]; /* only do it for SSA values */ @@ -2526,9 +2514,9 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed) * same source and destination operand otherwise, as the engine may * read the source multiple times. */ if (instr->opcode == INSTR_MUL_VF || - instr->opcode == VINSTR_BITXOR || instr->opcode == VINSTR_BITAND_VF || instr->opcode == VINSTR_BITOR_VF || + instr->opcode == VINSTR_BITXOR || instr->opcode == VINSTR_BITXOR_VF || instr->opcode == VINSTR_BITXOR_V) { @@ -2539,7 +2527,12 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed) if (value->memberof && ir_value_life_merge(value->memberof, instr->eid+1)) *changed = true; } - else if (instr->opcode == INSTR_MUL_FV || instr->opcode == INSTR_LOAD_V) + + if (instr->opcode == INSTR_MUL_FV || + instr->opcode == INSTR_LOAD_V || + instr->opcode == VINSTR_BITXOR || + instr->opcode == VINSTR_BITXOR_VF || + instr->opcode == VINSTR_BITXOR_V) { value = instr->_ops[1]; /* the float source will get an additional lifetime */