[LLVMbugs] [Bug 12319] New: The x86 backend can introduce branches that depend on uninitialized values

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Mar 20 17:34:32 PDT 2012


http://llvm.org/bugs/show_bug.cgi?id=12319

             Bug #: 12319
           Summary: The x86 backend can introduce branches that depend on
                    uninitialized values
           Product: libraries
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Backend: X86
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: rafael.espindola at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified


At mozilla it is common to see code that looks like

void f(void);
void g(void);
_Bool h(int *a, int *b);
void test() {
  int a, b;
  if (!h(&a, &b) || a == 42 || b == 33)
    f();
  else
    g();
}

The idea is that function h should make sure it initializes a and b *when it
returns true*. Clang + IL optimizations produce

--------------------------
define void @test() nounwind uwtable {
entry:
  %a = alloca i32, align 4
  %b = alloca i32, align 4
  %call = call zeroext i1 @h(i32* %a, i32* %b) nounwind
  %call.not = xor i1 %call, true
  %0 = load i32* %a, align 4, !tbaa !0
  %cmp = icmp eq i32 %0, 42
  %or.cond = or i1 %cmp, %call.not
  %1 = load i32* %b, align 4, !tbaa !0
  %cmp2 = icmp eq i32 %1, 33
  %or.cond3 = or i1 %or.cond, %cmp2
  br i1 %or.cond3, label %if.then, label %if.else
if.then:
  call void @f() nounwind
  br label %if.end
if.else:
  call void @g() nounwind
  br label %if.end
if.end
  ret void
}
------------------------------

Which is fine, since the branch will never depend on an uninitialized value
unless there is a bug in h. The problem is that the x86 backend splits the BB:

----------------------------------------------
    callq    h
    cmpl    $42, 4(%rsp)
    je    .LBB0_3
    xorb    $1, %al
    testb    %al, %al
    jne    .LBB0_3
        ...
---------------------------------------------

Now the first branch is using a potentially uninitialized value. The full
function behavior stays the same: if the value is uninitialized then h returned
false and we will end up branching to .LBB0_3 anyway.

The problem is that valgrind reports an invalid use as soon as it sees the
first branch.

Any ideas on how to fix this? Changing the optimization to first check
expressions that don't access memory would fix this example, but any splitting
can introduce an uninitialized use for a given example.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list