[LLVMbugs] [Bug 1742] New: invalid code generation on x86 with SSE enabled

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Fri Oct 26 09:54:45 PDT 2007


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

           Summary: invalid code generation on x86 with SSE enabled
           Product: new-bugs
           Version: unspecified
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Keywords: miscompilation
          Severity: critical
          Priority: P2
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: tomas.l.olsen at gmail.com
                CC: llvmbugs at cs.uiuc.edu


The following .ll does not work as expected. Instead of printing 36 it prints
nan.

target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:8"
target triple = "i686-unknown-linux-gnu"
    %"1e1C" = type { double, double }
@"1e1C__initZ" = constant %"1e1C" zeroinitializer        ; <%"1e1C"*> [#uses=2]
@stringliteral = internal constant [4 x i8] c"%f\0A\00"        ; <[4 x i8]*>
[#uses=1]

define fastcc double @_D1e1C3dotMFKS1e1CZd(%"1e1C"* %this, %"1e1C"* %b) {
entry:
    %tmp = getelementptr %"1e1C"* %this, i32 0, i32 0        ; <double*>
[#uses=1]
    %tmp1 = getelementptr %"1e1C"* %b, i32 0, i32 0        ; <double*>
[#uses=1]
    %tmp2 = load double* %tmp        ; <double> [#uses=1]
    %tmp3 = load double* %tmp1        ; <double> [#uses=1]
    %tmp4 = mul double %tmp2, %tmp3        ; <double> [#uses=1]
    %tmp5 = getelementptr %"1e1C"* %this, i32 0, i32 1        ; <double*>
[#uses=1]
    %tmp6 = getelementptr %"1e1C"* %b, i32 0, i32 1        ; <double*>
[#uses=1]
    %tmp7 = load double* %tmp5        ; <double> [#uses=1]
    %tmp8 = load double* %tmp6        ; <double> [#uses=1]
    %tmp9 = mul double %tmp7, %tmp8        ; <double> [#uses=1]
    %tmp10 = add double %tmp4, %tmp9        ; <double> [#uses=1]
    ret double %tmp10
}

define fastcc i32 @_Dmain() {
entry:
    %a = alloca %"1e1C"        ; <%"1e1C"*> [#uses=4]
    %b = alloca %"1e1C"        ; <%"1e1C"*> [#uses=4]
    %d = alloca double        ; <double*> [#uses=3]
    %tmp = bitcast %"1e1C"* %a to i8*        ; <i8*> [#uses=1]
    %tmp1 = bitcast %"1e1C"* @"1e1C__initZ" to i8*        ; <i8*> [#uses=1]
    call void @llvm.memcpy.i32( i8* %tmp, i8* %tmp1, i32 16, i32 0 )
    %tmp2 = bitcast %"1e1C"* %b to i8*        ; <i8*> [#uses=1]
    %tmp3 = bitcast %"1e1C"* @"1e1C__initZ" to i8*        ; <i8*> [#uses=1]
    call void @llvm.memcpy.i32( i8* %tmp2, i8* %tmp3, i32 16, i32 0 )
    %tmp4 = getelementptr %"1e1C"* %a, i32 0, i32 0        ; <double*>
[#uses=1]
    store double 2.000000e+00, double* %tmp4
    %tmp5 = getelementptr %"1e1C"* %a, i32 0, i32 1        ; <double*>
[#uses=1]
    store double 6.000000e+00, double* %tmp5
    %tmp6 = getelementptr %"1e1C"* %b, i32 0, i32 0        ; <double*>
[#uses=1]
    store double 3.000000e+00, double* %tmp6
    %tmp7 = getelementptr %"1e1C"* %b, i32 0, i32 1        ; <double*>
[#uses=1]
    store double 5.000000e+00, double* %tmp7
    %tmp8 = call double @_D1e1C3dotMFKS1e1CZd( %"1e1C"* %a, %"1e1C"* %b )      
 ; <double> [#uses=1]
    store double %tmp8, double* %d
    %tmp9 = load double* %d        ; <double> [#uses=1]
    %tmp10 = call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]*
@stringliteral, i32 0, i32 0), double %tmp9 )        ; <i32> [#uses=0]
    ret i32 0
}

declare void @llvm.memcpy.i32(i8*, i8*, i32, i32)

declare i32 @printf(i8*, ...)

define i32 @main(i32, i8**, i8**) {
entry:
    %ret = call fastcc i32 @_Dmain( )        ; <i32> [#uses=1]
    ret i32 %ret
}

Following is a paste of the IRC chat I had with baldrick after finding the
problem:

<baldrick> lindquist: if I turn off SSE then I get 36
<baldrick> lindquist: the interesting thing is that _D1e1C3dotMFKS1e1CZd
returns 36 in xmm0
<baldrick> so somehow it's not getting printed right!
<baldrick> p $xmm0
<baldrick> v2_double = {36, 0}
<baldrick> (from the debugger, after returning from the subroutine)
<baldrick> 0x0804843f <_Dmain+159>:        fstpl  0x10(%esp)
<baldrick> 0x08048443 <_Dmain+163>:        movsd  0x10(%esp),%xmm0
<baldrick> lindquist: I've got to go, but anyway here's the problem:
<baldrick> _D1e1C3dotMFKS1e1CZd returns the result in xmm0
<baldrick> the above two lines correspond to
<baldrick> store double %tmp8, double* %d
<baldrick> and
<baldrick> %tmp9 = load double* %d
<baldrick> but it's not storing xmm0 to the stack, it's storing the value on
the x86 floating point stack!  (Which hasn't been used because we are using SSE
here)
<baldrick> lindquist: so it seems to me that some x86 code is confused, and
hasn't realised that the return value was in an SSE register and not on the
floating point stack
<baldrick> lindquist: this is a bad bug, please report it
<lindquist> baldrick, I will. thank you for clearing things up for me


-- 
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