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.

Reply via email to