diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp index d36c853..be4bd9f 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp @@ -1709,6 +1709,18 @@ value_cmp(ValueRef *a, ValueRef *b) { return ai->serial < bi->serial; } +static bool +self_mov(Instruction *i) { + if (i->op != OP_MOV) + return false; + LValue *a = i->getDef(0)->asLValue(); + LValue *b = i->getSrc(0)->asLValue(); + if (a == NULL || a->reg.file != FILE_GPR || + b == NULL || b->reg.file != FILE_GPR) + return false; + return a->join == b->join; +} + // For each value that is to be spilled, go through all its definitions. // A value can have multiple definitions if it has been coalesced before. // For each definition, first go through all its uses and insert an unspill @@ -1754,7 +1766,7 @@ SpillCodeInserter::run(const std::list& lst) ValueRef *u = *it; Instruction *usei = u->getInsn(); assert(usei); - if (usei->isPseudo()) { + if (usei->isPseudo() || self_mov(usei)) { tmp = (slot->reg.file == FILE_MEMORY_LOCAL) ? NULL : slot; last = NULL; } else { @@ -1766,7 +1778,7 @@ SpillCodeInserter::run(const std::list& lst) } assert(defi); - if (defi->isPseudo()) { + if (defi->isPseudo() || self_mov(defi)) { d = lval->defs.erase(d); --d; if (slot->reg.file == FILE_MEMORY_LOCAL)