[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-bugs-dist
Subject:    [valgrind] [Bug 330617] New: ppc false positive conditional jump depends on uninitialised value
From:       Hal Finkel <hfinkel () anl ! gov>
Date:       2014-01-31 17:18:28
Message-ID: bug-330617-17878 () http ! bugs ! kde ! org/
[Download RAW message or body]

https://bugs.kde.org/show_bug.cgi?id=330617

            Bug ID: 330617
           Summary: ppc false positive conditional jump depends on
                    uninitialised value
    Classification: Unclassified
           Product: valgrind
           Version: 3.9.0
          Platform: Compiled Sources
                OS: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: NOR
         Component: memcheck
          Assignee: jseward@acm.org
          Reporter: hfinkel@anl.gov

valgrind reports a false-positive conditional jump dependence on an
uninitialized value in the function ._ZN4llvm7APFloat6assignERKS0_; I've
simplified and annotated some assembly code below, but first, I think it is
easier to understand the underlying problem in terms of the LLVM IR
transformation being performed (which I've also annotated):

As part of the optimization pipeline, LLVM transforms this function:

define linkonce_odr hidden zeroext i1
@_ZNK4llvm7APFloat10isInfinityEv(%"class.llvm::APFloat"* %this) #0 align 2 {
entry:
  %category = getelementptr inbounds %"class.llvm::APFloat"* %this, i32 0, i32
3
  %bf.load = load i8* %category, align 2   ; load some byte (when executed, the
lower 4 bits are undefined)
  %bf.lshr = lshr i8 %bf.load, 5                   ; shift right by 5 (to
isolate the upper three bits)
  %bf.cast = zext i8 %bf.lshr to i32           ; zero extend the result
  %cmp = icmp eq i32 %bf.cast, 0            ; compare to zero
  ret i1 %cmp
}

into this function:

define linkonce_odr hidden zeroext i1
@_ZNK4llvm7APFloat10isInfinityEv(%"class.llvm::APFloat"* %this) #0 align 2 {
entry:
  %category = getelementptr inbounds %"class.llvm::APFloat"* %this, i64 0, i32
3
  %bf.load = load i8* %category, align 2 ; loading some byte  (when executed,
the lower 4 bits are undefined)
  %cmp = icmp ult i8 %bf.load, 32           ; this is equivalent to asking if
the upper three bits are zero
  ret i1 %cmp
}

This code is isolating a bit field, stored as the upper three bits in some
byte, and comparing them to zero. The optimization eliminates the shift by
instead comparing the total byte value to 32. Even though the lower 4 bits are
undefined, their value does not affect the result of the comparison (because
only the upper defined bits control whether the value is less than 32 or not).

In assembly, in a context similar to that in the real code, looks like this:

# BB#0:                                 # %entry
        lbz 5, 18(4)
        lbz 6, 18(3)
        rlwinm 5, 5, 0, 27, 27   <--- isolate rhs sign bit
        rlwinm 6, 6, 0, 28, 26   <--- zero out this sign bit
        rlwimi 6, 5, 0, 27, 27   <--- insert rhs sign bit into this
        stb 6, 18(3)             <--- store result
        rlwinm 5, 6, 0, 27, 31   <--- isolate bits [27,31] of this ([24,27] are
defined, [28,31] are undefined)
        lbz 12, 18(4)
        rlwinm 4, 12, 0, 0, 26   <--- isolate bits [0,26] from rhs, all are
defined (only [24,26] matter, == category)
        rlwimi 4, 5, 0, 27, 31   <--- insert bits [27,31] of this (of which
[28,31] are undefined) into above
        rlwinm 5, 4, 0, 24, 31   <--- zero out [0,23] for comparison, this
leaves bits [24,31] of which [28,31] are undefined
        stb 4, 18(3)
        cmplwi 0, 5, 32           <--- valgrind incorrectly complains about
this jump!
        blt 0, .LBB0_2

In the annotations, I'm using IBM's convention for bit numbering. Even though
there are undefined bits in r5 when 'cmplwi 0, 5, 32' is executed, not *all* of
the resulting condition-register bits are undefined, and the 'blt 0, .LBB0_2'
does not depend on any of those undefined bits.


Reproducible: Always

Steps to Reproduce:
1. Download and compile trunk LLVM/Clang with itself using -O3 -mcpu=ppc64
2. Run the APFloat unit test under valgrind (APFloatTest.next in particular)
Actual Results:  
==2394== Conditional jump or move depends on uninitialised value(s)
==2394==    at 0x10290070: llvm::APFloat::assign(llvm::APFloat const&) (in
build.stage2/unittests/ADT/Release+Asserts/ADTTests)
==2394==    by 0x1029048B: llvm::APFloat::operator=(llvm::APFloat const&) (in
build.stage2/unittests/ADT/Release+Asserts/ADTTests)
==2394==    by 0x1008CC6F: (anonymous
namespace)::APFloatTest_next_Test::TestBody() (in
build.stage2/unittests/ADT/Release+Asserts/ADTTests)
...

Expected Results:  
This is a false positive as explained above.

-- 
You are receiving this mail because:
You are watching all bug changes.
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic