namespace aco {
+#ifndef NDEBUG
+void perfwarn(Program *program, bool cond, const char *msg, Instruction *instr)
+{
+ if (cond) {
+ char *out;
+ size_t outsize;
+ FILE *memf = open_memstream(&out, &outsize);
+
+ fprintf(memf, "%s: ", msg);
+ aco_print_instr(instr, memf);
+ fclose(memf);
+
+ aco_perfwarn(program, out);
+ free(out);
+
+ if (debug_flags & DEBUG_PERFWARN)
+ exit(1);
+ }
+}
+#endif
+
/**
* The optimizer works in 4 phases:
* (1) The first pass collects information for each ssa-def,
bool parse_base_offset(opt_ctx &ctx, Instruction* instr, unsigned op_index, Temp *base, uint32_t *offset, bool prevent_overflow)
{
- if (prevent_overflow)
- return false; //TODO
-
Operand op = instr->operands[op_index];
if (!op.isTemp())
default:
return false;
}
+ if (prevent_overflow && !add_instr->definitions[0].isNUW())
+ return false;
if (add_instr->usesModifiers())
return false;
ASSERTED bool all_const = false;
for (Operand& op : instr->operands)
all_const = all_const && (!op.isTemp() || ctx.info[op.tempId()].is_constant_or_literal(32));
- perfwarn(all_const, "All instruction operands are constant", instr.get());
+ perfwarn(ctx.program, all_const, "All instruction operands are constant", instr.get());
}
for (unsigned i = 0; i < instr->operands.size(); i++)
unsigned bits = get_operand_size(instr, i);
if (info.is_constant(bits) && alu_can_accept_constant(instr->opcode, i)) {
Operand op = get_constant_op(ctx, info, bits);
- perfwarn(instr->opcode == aco_opcode::v_cndmask_b32 && i == 2, "v_cndmask_b32 with a constant selector", instr.get());
+ perfwarn(ctx.program, instr->opcode == aco_opcode::v_cndmask_b32 && i == 2, "v_cndmask_b32 with a constant selector", instr.get());
if (i == 0 || instr->opcode == aco_opcode::v_readlane_b32 || instr->opcode == aco_opcode::v_writelane_b32) {
instr->operands[i] = op;
continue;
new_instr->operands.back() = Operand(base);
if (!smem->definitions.empty())
new_instr->definitions[0] = smem->definitions[0];
- new_instr->can_reorder = smem->can_reorder;
- new_instr->barrier = smem->barrier;
+ new_instr->sync = smem->sync;
new_instr->glc = smem->glc;
new_instr->dlc = smem->dlc;
new_instr->nv = smem->nv;
instr->opcode == aco_opcode::v_sub_f16 ||
instr->opcode == aco_opcode::v_subrev_f16;
if (mad16 || mad32) {
- bool need_fma = mad32 ? block.fp_mode.denorm32 != 0 :
+ bool need_fma = mad32 ? (block.fp_mode.denorm32 != 0 || ctx.program->chip_class >= GFX10_3) :
(block.fp_mode.denorm16_64 != 0 || ctx.program->chip_class >= GFX10);
if (need_fma && instr->definitions[0].isPrecise())
return;