[LLVMdev] Is it an opt bug ?

Duncan Sands baldrick at free.fr
Wed Feb 29 01:30:36 PST 2012


Hi Seb,

> Indeed, I made same experiment as you and concluded that it might be a BUG.

I don't think the issue I noticed is a bug after all, see below.

> 2012/2/28 Duncan Sands <baldrick at free.fr <mailto:baldrick at free.fr>>
>
>     Hi Seb, I think it is an opt bug.  If you run opt at -O1 then you get:
>
>     define void @t2(double* nocapture %x) nounwind {
>     L.entry:
>        %a = alloca [2 x i64], align 8
>        %0 = getelementptr inbounds [2 x i64]* %a, i32 0, i32 0
>        store i64 3, i64* %0, align 8
>        %1 = getelementptr [2 x i64]* %a, i32 0, i32 1
>        store i64 5, i64* %1, align 8
>        %2 = bitcast [2 x i64]* %a to double*
>        %3 = load double* %2, align 8
>        store double %3, double* %x, align 4
>        %4 = load i64* %0, align 8
>        %5 = add i64 %4, 536870910

This add is adding -2, but with some funny values in bits 29 and up.

>        %6 = trunc i64 %5 to i32
>        %7 = getelementptr [2 x i64]* %a, i32 0, i32 %6

This getelementptr results in %6 being multiplied by 8.  That causes the
funny values at the top of the add to be shifted off.  I.e. the final
answer should be correct.

Ciao, Duncan.

>        %8 = bitcast i64* %7 to double*
>        %9 = load double* %8, align 8
>        %10 = getelementptr double* %x, i32 1
>        store double %9, double* %10, align 4
>        ret void
>     }
>
>     Notice "%5 = add i64 %4, 536870910".  This is presumably trying to subtract 2,
>     but this doesn't seem to be the same as subtracting 2 even after the truncate
>     to 32 bits.
>
>     This then causes a load from a wild stack location later.  Probably at a higher
>     optimization level this is recognized as an undefined operation causing code
>     after it to be removed, including the final store.
>
>     Ciao, Duncan.
>
>
>     On 28/02/12 14:58, Seb wrote:
>      > Hi all,
>      >
>      > I'm looking at following code snippet:
>      >
>      > void t2(double *x)
>      > {
>      >        long long a[2];
>      >        a[0] = 3;
>      >        a[1] = 5;
>      >        *x = * ((double *) a);
>      >        *(x+1) = * ((double *) &a[a[0]-2]);
>      > }
>      >
>      > I use generate LLVM code using my own front-end that looks like:
>      >
>      >
>      > ; ModuleID = 'jb.c'
>      > 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:64-f80:32:32-n8:16:32"
>      > target triple = "i386-pc-linux-gnu"
>      > define void @t2(double* %x) {
>      > L.entry:
>      >      %a = alloca [2 x i64], align 4
>      >
>      >      %x.addr = alloca double*
>      >      store double* %x, double** %x.addr
>      >      %0 = bitcast [2 x i64]* %a to i64*
>      >      store i64 3, i64* %0
>      >      %1 = getelementptr [2 x i64]* %a, i32 0, i32 1
>      >      store i64 5, i64* %1
>      >      %2 = bitcast [2 x i64]* %a to double*
>      >      %3 = load double* %2
>      >      %4 = load double** %x.addr
>      >      store double %3, double* %4
>      >      %5 = bitcast [2 x i64]* %a to double*
>      >      %6 = bitcast double* %5 to i8*
>      >      %7 = bitcast [2 x i64]* %a to i64*
>      >      %8 = load i64* %7
>      >      %9 = sub i64 %8, 2
>      >      %10 = trunc i64 %9 to i32
>      >      %11 = mul i32 %10, 8
>      >      %12 = getelementptr i8* %6, i32 %11
>      >      %13 = bitcast i8* %12 to double*
>      >      %14 = load double* %13
>      >      %15 = load double** %x.addr
>      >      %16 = bitcast double* %15 to i8*
>      >      %17 = getelementptr i8* %16, i32 8
>      >      %18 = bitcast i8* %17 to double*
>      >      store double %14, double* %18
>      >      ret void
>      > }
>      >
>      > when I use LLVM opt on this .ll file I've got:
>      >
>      > ; ModuleID = 'jb.ll'
>      > 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:64-f80:32:32-n8:16:32"
>      > target triple = "i386-pc-linux-gnu"
>      >
>      > define void @t2(double* nocapture %x) nounwind {
>      > L.entry:
>      >    store double 1.482197e-323, double* %x, align 4
>      >    ret void
>      > }
>      >
>      > Now if I use clang -O2 I've got following llvm file:
>      >
>      > ; ModuleID = 'jb.clang.ll'
>      > 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:64-f80:32:32-n8:16:32"
>      > target triple = "i386-unknown-linux-gnu"
>      >
>      > define void @t2(double* nocapture %x) nounwind {
>      >    store double 1.482197e-323, double* %x, align 4, !tbaa !0
>      >    %1 = getelementptr inbounds double* %x, i32 1
>      >    store double 2.470328e-323, double* %1, align 4, !tbaa !0
>      >    ret void
>      > }
>      >
>      > !0 = metadata !{metadata !"double", metadata !1}
>      > !1 = metadata !{metadata !"omnipotent char", metadata !2}
>      > !2 = metadata !{metadata !"Simple C/C++ TBAA", null}
>      >
>      > Which is what I was expecting, to me it seems that there is a bug in LLVM
>     opt,
>      > is it the case ?
>      >
>      > Thanks for your answer
>      > Best Regards
>      > Seb
>      >
>      >
>      > _______________________________________________
>      > LLVM Developers mailing list
>      > LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu> http://llvm.cs.uiuc.edu
>      > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>     _______________________________________________
>     LLVM Developers mailing list
>     LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu> http://llvm.cs.uiuc.edu
>     http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>




More information about the llvm-dev mailing list