nv50/ir: fix emission of cas without a destination
authorIlia Mirkin <imirkin@alum.mit.edu>
Sat, 27 Feb 2021 23:24:44 +0000 (18:24 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sun, 11 Apr 2021 16:31:22 +0000 (12:31 -0400)
We were previously dumping $r127 in there. This has a bad effect on
nv50, so make sure we allocate an actual register for it, even if
there's nothing using the result.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Acked-by: Pierre Moreau <dev@pmoreau.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9299>

src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp

index 6da706b..9120f99 100644 (file)
@@ -3928,7 +3928,10 @@ DeadCodeElim::visit(BasicBlock *bb)
          if (i->op == OP_ATOM ||
              i->op == OP_SUREDP ||
              i->op == OP_SUREDB) {
-            i->setDef(0, NULL);
+            const Target *targ = prog->getTarget();
+            if (targ->getChipset() >= NVISA_GF100_CHIPSET ||
+                i->subOp != NV50_IR_SUBOP_ATOM_CAS)
+               i->setDef(0, NULL);
             if (i->op == OP_ATOM && i->subOp == NV50_IR_SUBOP_ATOM_EXCH) {
                i->cache = CACHE_CV;
                i->op = OP_STORE;
index 20c6aca..6a6ad01 100644 (file)
@@ -2574,6 +2574,13 @@ RegAlloc::InsertConstraintsPass::visit(BasicBlock *bb)
           i->op == OP_MERGE ||
           i->op == OP_SPLIT) {
          constrList.push_back(i);
+      } else
+      if (i->op == OP_ATOM && i->subOp == NV50_IR_SUBOP_ATOM_CAS &&
+          targ->getChipset() < 0xc0) {
+         // Like a hazard, but for a def.
+         Instruction *nop = new_Instruction(func, OP_NOP, i->dType);
+         nop->setSrc(0, i->getDef(0));
+         i->bb->insertAfter(i, nop);
       }
    }
    return true;