summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarol Herbst <[email protected]>2018-06-28 18:55:00 +0200
committerKarol Herbst <[email protected]>2018-07-07 20:32:33 +0200
commitde139787332eb83381d7b5ed794d834f44f2ac45 (patch)
tree3476ea065dcd78b1266082206697fa7254d4fd60 /src
parentf2cc694d8ee067467c946999138637b00a7a6158 (diff)
nv50/ir: fix Instruction::isActionEqual for PHI instructions
phi instructions don't have the same results by simply having the same sources. They need to be inside the same BasicBlock or share an equal condition resulting into a path through the shader selecting equal sources as well. short example: cond = ...; const0 = 0; const1 = 1; if (cond) { ssa_1 = const0; } else { ssa_2 = const1; } ssa_3 = phi ssa_1 ssa_2; if (!cond) { ssa_4 = const0; } else { ssa_5 = const1; } ssa_6 = phi ssa_4 ssa_5; allthough both phis actually have sources with equal results, merging them would be wrong due to having a different condition selecting which source to take. For now we also stick an assert into GlobalCSE, because it should never end up having to merge phi instructions. Reviewed-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
index e0faf8501bf..520cbee7c1a 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
@@ -3472,6 +3472,11 @@ Instruction::isActionEqual(const Instruction *that) const
} else
if (this->asFlow()) {
return false;
+ } else
+ if (this->op == OP_PHI && this->bb != that->bb) {
+ /* TODO: we could probably be a bit smarter here by following the
+ * control flow, but honestly, it is quite painful to check */
+ return false;
} else {
if (this->ipa != that->ipa ||
this->lanes != that->lanes ||
@@ -3568,6 +3573,7 @@ GlobalCSE::visit(BasicBlock *bb)
break;
}
if (!phi->srcExists(s)) {
+ assert(ik->op != OP_PHI);
Instruction *entry = bb->getEntry();
ik->bb->remove(ik);
if (!entry || entry->op != OP_JOIN)