[LLVMbugs] [Bug 6429] New: segfault on x86_64: ucomisd takes bad address for comparison with 0.0

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Fri Feb 26 01:42:41 PST 2010


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

           Summary: segfault on x86_64: ucomisd takes bad address for
                    comparison with 0.0
           Product: new-bugs
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P5
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: karrenberg at cs.uni-saarland.de
                CC: llvmbugs at cs.uiuc.edu


seems like I stumbled upona bug in x86_64 codegen in the latest svn trunk.
The problem did not appear in the last revision I used (r95086).

My C source looks like this:

#include <stdio.h>

int main(int argc, char** argv) {
    double a[2] = {1.14, 3.134};

    printf("unknown side-effect\n");
    for (unsigned i=0; i<2; ++i) {
        const double bad = a[i] / (a[i] == 0.0f ? 0.00001f : a[i]);
        printf("%f\n", bad);
    }
    return 0;
}

the expected output here is the following (e.g. gcc 4.4.1 or icc 11.1):
unknown side-effect
1.000000
1.000000

compile with llvm-gcc:
llvm-gcc -o test.bc -c -emit-llvm -Wall test.cpp

'lli test.bc' produces the following output:
unknown side-effect
0  lli             0x0000000000b8396f
1  lli             0x0000000000b8415d
2  libpthread.so.0 0x00007fdd88cc1190
3  libpthread.so.0 0x00007fdd8903b0c5
Stack dump:
0.      Program arguments: lli test.bc
Segmentation fault

gdb says it crashes at the double-comparison with 0, which seems obvious
looking at the address:
0x00007ffff7f4b094 <main+124>:  ucomisd 0xffffffffffffff73,%xmm0

part of the disassembly between the two printfs:
0x00007ffff7f4b05d <main+69>:   callq  *%rax
0x00007ffff7f4b05f <main+71>:   movl   $0x0,0xc(%rsp)
0x00007ffff7f4b067 <main+79>:   mov    $0x7ffff7fd9034,%rbx
0x00007ffff7f4b071 <main+89>:   mov    $0x7ffff6ef4b50,%r14
0x00007ffff7f4b07b <main+99>:   mov    $0x3ee4f8b580000000,%r15
0x00007ffff7f4b085 <main+109>:  jmpq   0x7ffff7f4b0dc <main+196>
0x00007ffff7f4b08a <main+114>:  mov    0xc(%rsp),%eax
0x00007ffff7f4b08e <main+118>:  movsd  0x10(%rsp,%rax,8),%xmm0
0x00007ffff7f4b094 <main+124>:  ucomisd 0xffffffffffffff73,%xmm0
0x00007ffff7f4b09d <main+133>:  setnp  %al
0x00007ffff7f4b0a0 <main+136>:  sete   %cl
0x00007ffff7f4b0a3 <main+139>:  test   %al,%cl
0x00007ffff7f4b0a5 <main+141>:  jne    0x7ffff7f4b0c0 <main+168>
0x00007ffff7f4b0ab <main+147>:  mov    0xc(%rsp),%eax
0x00007ffff7f4b0af <main+151>:  movsd  0x10(%rsp,%rax,8),%xmm1
0x00007ffff7f4b0b5 <main+157>:  movsd  %xmm1,0x20(%rsp)
0x00007ffff7f4b0bb <main+163>:  jmpq   0x7ffff7f4b0c5 <main+173>
0x00007ffff7f4b0c0 <main+168>:  mov    %r15,0x20(%rsp)
0x00007ffff7f4b0c5 <main+173>:  divsd  0x20(%rsp),%xmm0
0x00007ffff7f4b0cb <main+179>:  movsd  %xmm0,(%rsp)
0x00007ffff7f4b0d0 <main+184>:  mov    %rbx,%rdi
0x00007ffff7f4b0d3 <main+187>:  mov    $0x1,%al
0x00007ffff7f4b0d5 <main+189>:  callq  *%r14

the same happens when compiling with llvm-gcc and any optimization flag as well
as with clang -O0.
compiling with clang -O1 to -O3 works fine, though, so I guess it is something
in the generated bitcode, which looks like this for llvm-gcc -O3:

; ModuleID = 'test.bc'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"

@.str = private constant [20 x i8] c"unknown side-effect\00", align 1 ; <[20 x
i8]*> [#uses=1]
@.str1 = private constant [4 x i8] c"%f\0A\00", align 1 ; <[4 x i8]*> [#uses=1]

define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
bb.nph:
  %a = alloca [2 x double], align 8               ; <[2 x double]*> [#uses=3]
  %0 = getelementptr inbounds [2 x double]* %a, i64 0, i64 0 ; <double*>
[#uses=1]
  store double 1.140000e+00, double* %0, align 8
  %1 = getelementptr inbounds [2 x double]* %a, i64 0, i64 1 ; <double*>
[#uses=1]
  store double 3.134000e+00, double* %1, align 8
  %2 = call i32 @puts(i8* getelementptr inbounds ([20 x i8]* @.str, i64 0, i64
0)) ; <i32> [#uses=0]
  br label %bb

bb:                                               ; preds = %bb3.bb_crit_edge,
%bb.nph
  %3 = phi double [ 1.140000e+00, %bb.nph ], [ %.pre, %bb3.bb_crit_edge ] ;
<double> [#uses=3]
  %indvar = phi i64 [ 1, %bb.nph ], [ %phitmp, %bb3.bb_crit_edge ] ; <i64>
[#uses=3]
  %4 = fcmp une double %3, 0.000000e+00           ; <i1> [#uses=1]
  %iftmp.2.0 = select i1 %4, double %3, double 0x3EE4F8B580000000 ; <double>
[#uses=1]
  %5 = fdiv double %3, %iftmp.2.0                 ; <double> [#uses=1]
  %6 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([4 x
i8]* @.str1, i64 0, i64 0), double %5) ; <i32> [#uses=0]
  %exitcond = icmp eq i64 %indvar, 2              ; <i1> [#uses=1]
  br i1 %exitcond, label %bb5, label %bb3.bb_crit_edge

bb3.bb_crit_edge:                                 ; preds = %bb
  %scevgep.phi.trans.insert = getelementptr [2 x double]* %a, i64 0, i64
%indvar ; <double*> [#uses=1]
  %.pre = load double* %scevgep.phi.trans.insert, align 8 ; <double> [#uses=1]
  %phitmp = add i64 %indvar, 1                    ; <i64> [#uses=1]
  br label %bb

bb5:                                              ; preds = %bb
  ret i32 0
}

declare i32 @puts(i8* nocapture) nounwind

declare i32 @printf(i8* noalias nocapture, ...) nounwind



this is what clang -O3 builds:

; ModuleID = 'test.bc'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"

@_ZZ4mainE1a = internal constant [2 x double] [double 1.140000e+00, double
3.134000e+00], align 8 ; <[2 x double]*> [#uses=1]
@.str1 = private constant [4 x i8] c"%f\0A\00"    ; <[4 x i8]*> [#uses=1]
@str = internal constant [20 x i8] c"unknown side-effect\00" ; <[20 x i8]*>
[#uses=1]

define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
bb.nph:
  %puts = tail call i32 @puts(i8* getelementptr inbounds ([20 x i8]* @str, i64
0, i64 0)) ; <i32> [#uses=0]
  br label %for.body

for.body:                                         ; preds = %for.body, %bb.nph
  %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ] ; <i64>
[#uses=2]
  %arrayidx15 = getelementptr [2 x double]* @_ZZ4mainE1a, i64 0, i64 %indvar ;
<double*> [#uses=1]
  %tmp5 = load double* %arrayidx15                ; <double> [#uses=2]
  %div = fdiv double %tmp5, %tmp5                 ; <double> [#uses=1]
  %call18 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x
i8]* @.str1, i64 0, i64 0), double %div) ; <i32> [#uses=0]
  %indvar.next = add i64 %indvar, 1               ; <i64> [#uses=2]
  %exitcond = icmp eq i64 %indvar.next, 2         ; <i1> [#uses=1]
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %for.body
  ret i32 0
}

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

declare i32 @puts(i8* nocapture) nounwind

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