if (!definition.isTemp()) {
continue;
}
+ if ((definition.isFixed() || definition.hasHint()) && definition.physReg() == vcc)
+ program->needs_vcc = true;
const Temp temp = definition.getTemp();
size_t n = 0;
for (unsigned i = 0; i < insn->operands.size(); ++i)
{
Operand& operand = insn->operands[i];
- if (!operand.isTemp()) {
+ if (!operand.isTemp())
continue;
- }
+ if (operand.isFixed() && operand.physReg() == vcc)
+ program->needs_vcc = true;
const Temp temp = operand.getTemp();
const bool inserted = temp.is_linear()
? live_sgprs.insert(temp).second
assert(is_phi(insn));
assert(insn->definitions.size() == 1 && insn->definitions[0].isTemp());
Definition& definition = insn->definitions[0];
+ if ((definition.isFixed() || definition.hasHint()) && definition.physReg() == vcc)
+ program->needs_vcc = true;
const Temp temp = definition.getTemp();
size_t n = 0;
: block->linear_preds;
for (unsigned i = 0; i < preds.size(); ++i) {
Operand &operand = insn->operands[i];
- if (!operand.isTemp()) {
+ if (!operand.isTemp())
continue;
- }
+ if (operand.isFixed() && operand.physReg() == vcc)
+ program->needs_vcc = true;
/* check if we changed an already processed block */
const bool inserted = live_temps[preds[i]].insert(operand.getTemp()).second;
if (inserted) {
std::vector<uint16_t> phi_sgpr_ops(program->blocks.size());
RegisterDemand new_demand;
+ program->needs_vcc = false;
+
/* this implementation assumes that the block idx corresponds to the block's position in program->blocks vector */
for (Block& block : program->blocks)
worklist.insert(block.index);
if ((op.getTemp().type() == RegType::vgpr && op.physReg() + op.size() > 256 + program->config->num_vgprs) ||
(op.getTemp().type() == RegType::sgpr && op.physReg() + op.size() > program->config->num_sgprs && op.physReg() < program->sgpr_limit))
err |= ra_fail(output, loc, assignments.at(op.tempId()).firstloc, "Operand %d has an out-of-bounds register assignment", i);
+ if (op.physReg() == vcc && !program->needs_vcc)
+ err |= ra_fail(output, loc, Location(), "Operand %d fixed to vcc but needs_vcc=false", i);
if (!assignments[op.tempId()].firstloc.block)
assignments[op.tempId()].firstloc = loc;
if (!assignments[op.tempId()].defloc.block)
if ((def.getTemp().type() == RegType::vgpr && def.physReg() + def.size() > 256 + program->config->num_vgprs) ||
(def.getTemp().type() == RegType::sgpr && def.physReg() + def.size() > program->config->num_sgprs && def.physReg() < program->sgpr_limit))
err |= ra_fail(output, loc, assignments.at(def.tempId()).firstloc, "Definition %d has an out-of-bounds register assignment", i);
+ if (def.physReg() == vcc && !program->needs_vcc)
+ err |= ra_fail(output, loc, Location(), "Definition %d fixed to vcc but needs_vcc=false", i);
if (!assignments[def.tempId()].firstloc.block)
assignments[def.tempId()].firstloc = loc;
assignments[def.tempId()].defloc = loc;