[LLVMbugs] [Bug 23115] New: LLVM opt and ordering of floating point conversions with potential overflow

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Fri Apr 3 10:11:17 PDT 2015


https://llvm.org/bugs/show_bug.cgi?id=23115

            Bug ID: 23115
           Summary: LLVM opt and ordering of floating point conversions
                    with potential overflow
           Product: new-bugs
           Version: 3.5
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: matt.davis at pgroup.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Hello,

I found a potential reordering of instructions produced by llvm's optimizer,
that is unfavorable to floating point expressions.

Our compiler will unroll the loop in the case that we are examining.  With that
said, the llvm code we intentionally generate is the following:

OpenACC c code:

int useVLA (int useacc, long size,const int n1, float avla[n1])
{
#pragma acc kernels pcopy(avla[0:n1]) if (useacc)
{
#pragma acc loop independent
    for (int i=0; i < n1; ++i1) {
        avla[i] = (float) (1) + (float) (i + 1) ;
    }
} 

The code I care about is specifically the ordering of the integer additions and
float conversion:
    (float)(1) + (float)(i + 1)

What we generate as llvm (and this is correct):
    %16 load i32* %.ndi0002.addr, align 4, !dbg !28
    %17 = add i32 %16, 1, !dbg !28
    %18 = sitofp i32 %17 to float, !dbg !28
    %19 = load float* %.r1.0018.addr, align 4, !dbg !28
    %20 = fadd float %18, %19, !dbg !28
    %21 = load i8** %.G0001.addr, align 8, !dbg !28
    %22 = getelementptr i8* %21, i64 -28, !dbg !28
    %23 = bitcast i8* %22 to float*, !dbg !28
    store float %20, float* %23, align 4, !dbg !28

%16 and %17 perform the integer add for (i + 1).
%18 converts the result to a single precision float.
%19 loads a constant (this is fine) as a floating point 
%20 - %23 perform the floating point addition and store into the array.

That is fine.  However, after llvm optimization, opt generates the transformed
code:
    %13 = or i32 %.ndi0002.addr.0, 1, !dbg !14 
    %addconv = add nsw i32 %13, 1, !dbg !14
    %14 = sitofp i32 %addconv to float, !dbg !14
    %15 = getelementptr i8* %.G0001.addr.0, i64 -28, !dbg !14
    %16 = bitcast i8* %15 to float*, !dbg !14
    store float %14, float* %16, align 4, !dbg !14    

%13 and the %addconv perform the (i + 1) + 1  and then convert that combined
result as a single precision float.  Ideally, to avoid overflow, we wanted the
semantics similar to the original llvm code in the previous example, whereby we
perform  i + 1 and then convert to float, and fadd that result to a floating
point value of 1.0.

This seems to happen when we use the following optimizations: -sroa and
-instcombine

Thanks,

-Matt

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150403/a298e93f/attachment.html>


More information about the llvm-bugs mailing list