https://bugs.kde.org/show_bug.cgi?id=523434
Mark Wielaard <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|ASSIGNED |RESOLVED Resolution|--- |FIXED --- Comment #13 from Mark Wielaard <[email protected]> --- commit 118a1fb2e7d2fca7a4f682827e531aebb66065bb Author: Vassil Vassilev <[email protected]> Date: Sat Oct 17 08:02:07 2026 +0000 Memcheck: compute unsigned ordered comparisons exactly Memcheck's shadow rule for unsigned ordered comparisons (Iop_CmpLT{32,64}U / Iop_CmpLE{32,64}U) is PCast(UifU(vx, vy)): the result is undefined if any input bit is undefined. This is sound but too coarse for a very common idiom: testing a bitfield that shares its storage word with bits no constructor has written. clang lowers such a test, e.g. `(word >> 48) != 0` for a 16-bit subfield at bit offset 48, to the unsigned compare `word >=u (1<<48)`. The constant has 48 trailing zero bits, so no undefined low bit of `word` can change the result. Memcheck nonetheless reports "Conditional jump or move depends on uninitialised value(s)". With clang 22.1.8 on x86_64, compiling `int main(){ return 0; }` at -O2 reports one such error in clang::FunctionProtoType::FunctionProtoType, so every compilation fails under --error-exitcode. See https://bugs.kde.org/show_bug.cgi?id=523434 and llvm/llvm-project#194147. --expensive-definedness-checks did not help: Memcheck always used the cheap rule for these comparisons. Add an exact interpretation, expensiveCmpLTorLEU, that bounds each operand by the two extremal instantiations of its undefined bits and reports undefined only when both outcomes are reachable: xmax = x | vx xmin = xmax ^ vx (= x & ~vx) ymax = y | vy ymin = ymax ^ vy x <u y undefined iff (xmin <u ymax) && (ymin <=u xmax) x <=u y undefined iff (xmin <=u ymax) && (ymin <u xmax) It costs 7 IROps. It is a new detail level, dl_CmpLTU_CmpLEU, used with --expensive-definedness-checks=yes, and by default (auto) on x86 and amd64, the same way as the existing CmpEQ/CmpNE rules, since it is LLVM-optimised code on those targets that triggers the false reports. Checked against a brute-force oracle over all 4-bit operand and undefined-mask combinations: 65536 cases each for LT and LE, no mismatches. Add memcheck/tests/amd64/partial_bitfield_cmp. It uses inline asm so that the compares do not depend on the compiler, and covers 64- and 32-bit compares with jae and ja: four cases that must not complain and two where the undefined bits do decide the result and that must still complain. The 32-bit jae case compares with 0x30000: with 0x10000, VEX turns that compare into a shift and an equality test, which does not exercise this rule. vbit-test runs with --expensive-definedness-checks=yes and expected the cheap result for these ops. Give it the exact expectation, UNDEF_CMP_LT_U and UNDEF_CMP_LE_U, computed from the operand bounds like the existing exact Add/Sub expectation. Update the manual entry for --expensive-definedness-checks. -- You are receiving this mail because: You are watching all bug changes.
