From f10161e477af21eb6723129c3f525a4b5126a973 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 5 Sep 2014 23:52:45 +0200 Subject: nv50/ir/util: fix BitSet issues BitSet::allocate() is being used with the expectation that it would leave the bitfield untouched if its size hasn't changed, however, the function always zeroed the last word, which led to obscure bugs with live set computation. This also fixes BitSet::resize(), which was broken, but luckily not being used. Cc: "10.2 10.3" Reviewed-by: Ilia Mirkin (cherry picked from commit b9f9e3ce03dbd8d044a72a00e1e8856a500b5f72) --- src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp | 4 ++++ src/gallium/drivers/nouveau/codegen/nv50_ir_util.cpp | 8 +++++--- src/gallium/drivers/nouveau/codegen/nv50_ir_util.h | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp index b2840814424..f2a8b551407 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp @@ -1654,6 +1654,10 @@ RegAlloc::execFunc() ret && i <= func->loopNestingBound; sequence = func->cfg.nextSequence(), ++i) ret = buildLiveSets(BasicBlock::get(func->cfg.getRoot())); + // reset marker + for (ArrayList::Iterator bi = func->allBBlocks.iterator(); + !bi.end(); bi.next()) + BasicBlock::get(bi)->liveSet.marker = false; if (!ret) break; func->orderInstructions(this->insns); diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_util.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_util.cpp index 895977710ca..d26acb304bc 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_util.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_util.cpp @@ -254,7 +254,9 @@ bool BitSet::resize(unsigned int nBits) return false; } if (n > p) - memset(&data[4 * p + 4], 0, (n - p) * 4); + memset(&data[p], 0, (n - p) * 4); + if (nBits < size && (nBits % 32)) + data[(nBits + 31) / 32 - 1] &= (1 << (nBits % 32)) - 1; size = nBits; return true; @@ -274,8 +276,8 @@ bool BitSet::allocate(unsigned int nBits, bool zero) if (zero) memset(data, 0, (size + 7) / 8); else - if (nBits) - data[(size + 31) / 32 - 1] = 0; // clear unused bits (e.g. for popCount) + if (size % 32) // clear unused bits (e.g. for popCount) + data[(size + 31) / 32 - 1] &= (1 << (size % 32)) - 1; return data; } diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_util.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_util.h index a4ea9d981e0..fa2c4804a42 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_util.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_util.h @@ -484,6 +484,7 @@ public: FREE(data); } + // allocate will keep old data iff size is unchanged bool allocate(unsigned int nBits, bool zero); bool resize(unsigned int nBits); // keep old data, zero additional bits -- cgit v1.2.3