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;
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 */
* 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)
{
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 */
if (irfun->builtin)
return true;
+ /*
+ * If there is no definition and the thing is eraseable, we can ignore
+ * outputting the function to begin with.
+ */
+ if (global->flags & IR_FLAG_ERASEABLE && irfun->code_function_def < 0) {
+ return true;
+ }
+
if (irfun->code_function_def < 0) {
irerror(irfun->context, "`%s`: IR global wasn't generated, failed to access function-def", irfun->name);
return false;
{
pushdef = true;
+ /*
+ * if we're eraseable and the function isn't referenced ignore outputting
+ * the function.
+ */
+ if (global->flags & IR_FLAG_ERASEABLE && vec_size(global->reads) == 0) {
+ return true;
+ }
+
if (OPTS_OPTIMIZATION(OPTIM_STRIP_CONSTANT_NAMES) &&
!(global->flags & IR_FLAG_INCLUDE_DEF) &&
(global->name[0] == '#' || global->cvq == CV_CONST))