Hi Duncan,<br><br>Indeed, I made same experiment as you and concluded that it might be a BUG.<br>Shall I submit it to llvm bug tracking support ?<br>Do you think there could be a work-around ?<br>Thanks for your quick answer.<br>
<br>Best Regards<br>Seb<br><br><div class="gmail_quote">2012/2/28 Duncan Sands <span dir="ltr"><<a href="mailto:baldrick@free.fr">baldrick@free.fr</a>></span><br><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Hi Seb, I think it is an opt bug. If you run opt at -O1 then you get:<br>
<div class="im"><br>
define void @t2(double* nocapture %x) nounwind {<br>
L.entry:<br>
</div> %a = alloca [2 x i64], align 8<br>
%0 = getelementptr inbounds [2 x i64]* %a, i32 0, i32 0<br>
store i64 3, i64* %0, align 8<br>
<div class="im"> %1 = getelementptr [2 x i64]* %a, i32 0, i32 1<br>
</div> store i64 5, i64* %1, align 8<br>
<div class="im"> %2 = bitcast [2 x i64]* %a to double*<br>
</div> %3 = load double* %2, align 8<br>
store double %3, double* %x, align 4<br>
%4 = load i64* %0, align 8<br>
%5 = add i64 %4, 536870910<br>
%6 = trunc i64 %5 to i32<br>
%7 = getelementptr [2 x i64]* %a, i32 0, i32 %6<br>
%8 = bitcast i64* %7 to double*<br>
%9 = load double* %8, align 8<br>
%10 = getelementptr double* %x, i32 1<br>
store double %9, double* %10, align 4<br>
ret void<br>
}<br>
<br>
Notice "%5 = add i64 %4, 536870910". This is presumably trying to subtract 2,<br>
but this doesn't seem to be the same as subtracting 2 even after the truncate<br>
to 32 bits.<br>
<br>
This then causes a load from a wild stack location later. Probably at a higher<br>
optimization level this is recognized as an undefined operation causing code<br>
after it to be removed, including the final store.<br>
<br>
Ciao, Duncan.<br>
<div><div class="h5"><br>
<br>
On 28/02/12 14:58, Seb wrote:<br>
> Hi all,<br>
><br>
> I'm looking at following code snippet:<br>
><br>
> void t2(double *x)<br>
> {<br>
> long long a[2];<br>
> a[0] = 3;<br>
> a[1] = 5;<br>
> *x = * ((double *) a);<br>
> *(x+1) = * ((double *) &a[a[0]-2]);<br>
> }<br>
><br>
> I use generate LLVM code using my own front-end that looks like:<br>
><br>
><br>
> ; ModuleID = 'jb.c'<br>
> target datalayout =<br>
> "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"<br>
> target triple = "i386-pc-linux-gnu"<br>
> define void @t2(double* %x) {<br>
> L.entry:<br>
> %a = alloca [2 x i64], align 4<br>
><br>
> %x.addr = alloca double*<br>
> store double* %x, double** %x.addr<br>
> %0 = bitcast [2 x i64]* %a to i64*<br>
> store i64 3, i64* %0<br>
> %1 = getelementptr [2 x i64]* %a, i32 0, i32 1<br>
> store i64 5, i64* %1<br>
> %2 = bitcast [2 x i64]* %a to double*<br>
> %3 = load double* %2<br>
> %4 = load double** %x.addr<br>
> store double %3, double* %4<br>
> %5 = bitcast [2 x i64]* %a to double*<br>
> %6 = bitcast double* %5 to i8*<br>
> %7 = bitcast [2 x i64]* %a to i64*<br>
> %8 = load i64* %7<br>
> %9 = sub i64 %8, 2<br>
> %10 = trunc i64 %9 to i32<br>
> %11 = mul i32 %10, 8<br>
> %12 = getelementptr i8* %6, i32 %11<br>
> %13 = bitcast i8* %12 to double*<br>
> %14 = load double* %13<br>
> %15 = load double** %x.addr<br>
> %16 = bitcast double* %15 to i8*<br>
> %17 = getelementptr i8* %16, i32 8<br>
> %18 = bitcast i8* %17 to double*<br>
> store double %14, double* %18<br>
> ret void<br>
> }<br>
><br>
> when I use LLVM opt on this .ll file I've got:<br>
><br>
> ; ModuleID = 'jb.ll'<br>
> target datalayout =<br>
> "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"<br>
> target triple = "i386-pc-linux-gnu"<br>
><br>
> define void @t2(double* nocapture %x) nounwind {<br>
> L.entry:<br>
> store double 1.482197e-323, double* %x, align 4<br>
> ret void<br>
> }<br>
><br>
> Now if I use clang -O2 I've got following llvm file:<br>
><br>
> ; ModuleID = 'jb.clang.ll'<br>
> target datalayout =<br>
> "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"<br>
> target triple = "i386-unknown-linux-gnu"<br>
><br>
> define void @t2(double* nocapture %x) nounwind {<br>
> store double 1.482197e-323, double* %x, align 4, !tbaa !0<br>
> %1 = getelementptr inbounds double* %x, i32 1<br>
> store double 2.470328e-323, double* %1, align 4, !tbaa !0<br>
> ret void<br>
> }<br>
><br>
> !0 = metadata !{metadata !"double", metadata !1}<br>
> !1 = metadata !{metadata !"omnipotent char", metadata !2}<br>
> !2 = metadata !{metadata !"Simple C/C++ TBAA", null}<br>
><br>
> Which is what I was expecting, to me it seems that there is a bug in LLVM opt,<br>
> is it the case ?<br>
><br>
> Thanks for your answer<br>
> Best Regards<br>
> Seb<br>
><br>
><br>
</div></div>> _______________________________________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</blockquote></div><br>