<font><font>Hi all,<br>
<br>
I'm using LLVM 3.0, for which I've filed following bug <a href="https://webmail-eu.st.com/owa/redir.aspx?C=f2882890c0064e71ba4c8238dc7fd399&URL=http%3a%2f%2fllvm.org%2fbugs%2fshow_bug.cgi%3fid%3d12130" target="_blank">http://llvm.org/bugs/show_bug.cgi?id=12130</a>.<br>

I'm trying to solve this problem by myself digging into LLVM sources.<br>
It seems that problem that I'm experiencing is related to presence or absence of NSW attribute on a 'mul'.<br>
Considering following code:<br>
<br>
<br>
define void @t2(double* %x) {<br>
L.entry:<br>
  %a = alloca [2 x i64], align 4<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 = bitcast double* %2 to i8*<br>
  %4 = load i64* %0<br>
  %5 = sub i64 %4, 2<br>
  %6 = trunc i64 %5 to i32<br>
  %7 = mul i32 %6, 8                                       ; HERE is problematic line #1<br>
  %8 = getelementptr i8* %3, i32 %7<br>
  %9 = bitcast i8* %8 to double*<br>
  %10 = load double* %9<br>
  %11 = bitcast double* %x to i8*<br>
  %12 = getelementptr i8* %11, i32 8<br>
  %13 = bitcast i8* %12 to double*<br>
  store double %10, double* %13<br>
  ret void<br>
}<br>
<br>
If I use opt has follows:<br>
<br>
opt -instcombine trb.ll -S -o trb.opt.ll<br>
<br>
I've got following code generated:<br>
<br>
; ModuleID = 'trb.ll'<br>
<br>
define void @t2(double* %x) {<br>
L.entry:<br>
  %a = alloca [2 x i64], align 4<br>
  %0 = getelementptr inbounds [2 x i64]* %a, i32 0, i32 0<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 i8*<br>
  %3 = load i64* %0<br>
  %4 = add i64 %3, 536870910                   ; Problematic line #2<br>
  %5 = trunc i64 %4 to i32<br>
  %6 = shl i32 %5, 3<br>
  %7 = getelementptr i8* %2, i32 %6<br>
  %8 = bitcast i8* %7 to double*<br>
  %9 = load double* %8<br>
  %10 = bitcast double* %x to i8*<br>
  %11 = getelementptr i8* %10, i32 8<br>
  %12 = bitcast i8* %11 to double*<br>
  store double %9, double* %12<br>
  ret void<br>
}<br>
<br>
If I replace on problematic line  #1 %7 = mul i32 %6, 8 by %7 = mul nsw i32 %6 then opt generates:<br>
<br>
; ModuleID = 'trb.ll'<br>
<br>
define void @t2(double* %x) {<br>
L.entry:<br>
  %a = alloca [2 x i64], align 4<br>
  %0 = getelementptr inbounds [2 x i64]* %a, i32 0, i32 0<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 i8*<br>
  %3 = load i64* %0<br>
  %4 = add i64 %3, 4294967294<br>
  %5 = trunc i64 %4 to i32<br>
  %6 = shl nsw i32 %5, 3<br>
  %7 = getelementptr i8* %2, i32 %6<br>
  %8 = bitcast i8* %7 to double*<br>
  %9 = load double* %8<br>
  %10 = bitcast double* %x to i8*<br>
  %11 = getelementptr i8* %10, i32 8<br>
  %12 = bitcast i8* %11 to double*<br>
  store double %9, double* %12<br>
  ret void<br>
}<br>
<br>
Digging into the source I understood that 'sub' is turned into an 'add' 
with 2-complemented value, 'mul' is turned into a shift and shit 
operation has been propagated to 2-comp constant to clear highest 3 bits
 when nsw is not present. To me this transformation seems invalid, can 
someone points me to where it occurs. Problem with such a transformation
 is that if I specify datalayout for target then in GVN it got further 
optimized into:<br>
<br>
define void @t2(double* nocapture %x) nounwind {<br>
L.entry:<br>
  %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>
  %1 = getelementptr [2 x i64]* %a, i32 0, i32 1<br>
  store i64 5, i64* %1, align 8<br>
  %2 = getelementptr [2 x i64]* %a, i32 0, i32 536870913<br>
  %3 = bitcast i64* %2 to double*<br>
  %4 = getelementptr double* %x, i32 1<br>
  store double undef, double* %4, align 4<br>
  ret void<br>
}<br>
<br>
Thus marking final store as 'undef' value which if not correct if pointer arithmetic is 32-bit since 536870913*8%2^32 = 8.<br>
<br>
Thanks for your help <br>
Best Regards<br>
Seb</font></font>