From: Rudolf Polzer Date: Mon, 26 Aug 2013 08:43:30 +0000 (+0200) Subject: Fix aliasing. X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=d4ed8f2802afa8add0461fd6538b8500054b1a23;p=xonotic%2Fgmqcc.git Fix aliasing. --- diff --git a/ir.c b/ir.c index 6ffe959..f73e5c0 100644 --- a/ir.c +++ b/ir.c @@ -628,6 +628,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. */ if (OPTS_FLAG(LEGACY_VECTOR_MATHS)) { if (oper->opcode == INSTR_MUL_VF && oper->_ops[2]->memberof == oper->_ops[1]) continue; @@ -635,6 +636,12 @@ static bool ir_function_pass_peephole(ir_function *self) 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; + value = oper->_ops[0]; /* only do it for SSA values */ @@ -2487,8 +2494,12 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed) } } - /* TODO(divVerent) what does this do? */ - if (instr->opcode == INSTR_MUL_VF) + /* These operations need a special case as they can break when using + * same source and destination operand otherwise, as the engine may + * read the source multiple times. */ + if (instr->opcode == INSTR_MUL_VF || + instr->opcode == VINSTR_BITAND_VF || + instr->opcode == VINSTR_BITOR_VF) { value = instr->_ops[2]; /* the float source will get an additional lifetime */