Interesting optimization failure.

Hi,

I have been working on using arrays and structs as first class objects.

I have this small function:

int main()
{
     char ar[10] = "12";
     return ar[4];
}

If I compile with -O1 I get this bitcode:

; ModuleID = 't0011.bc'
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-s0:0:64-f80:32:32"
target triple = "i686-pc-linux-gnu"

define i32 @main() {
entry:
         %retval = alloca i32 ; <i32*> [#uses=3]
         store i32 0, i32* %retval
         %ar = alloca [10 x i8] ; <[10 x i8]*> [#uses=2]
         store [10 x i8] c"12\00\00\00\00\00\00\00\00", [10 x i8]* %ar
         getelementptr [10 x i8]* %ar, i32 0, i32 4 ; <i8*>:0 [#uses=1]
         load i8* %0 ; <i8>:1 [#uses=1]
         sext i8 %1 to i32 ; <i32>:2 [#uses=1]
         store i32 %2, i32* %retval
         br label %return

return: ; preds = %entry
         load i32* %retval ; <i32>:3 [#uses=1]
         ret i32 %3
}

i.e. it returns ar[4].

If I compile with -O2 I get:
; ModuleID = 't0011.bc'
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-s0:0:64-f80:32:32"
target triple = "i686-pc-linux-gnu"

define i32 @main() nounwind {
entry:
         ret i32 49
}

i.e. it returns ar[0]!

One of the standard compile optimization passes is acting up. Any hints?

-Rich

Hi Richard,

I have been working on using arrays and structs as first class objects.

good to hear! The example doesn't make use of that though, does it?

I have this small function:

int main()
{
     char ar[10] = "12";
     return ar[4];
}

...

define i32 @main() nounwind {
entry:
         ret i32 49
}

Here I get

define i32 @main() nounwind {
entry:
        ret i32 0
}

at -O1 and above.

Ciao,

Duncan.

Duncan Sands wrote:

Hi Richard,

I have been working on using arrays and structs as first class objects.

good to hear! The example doesn't make use of that though, does it?

I have this small function:

int main()
{
     char ar[10] = "12";
     return ar[4];
}

...

define i32 @main() nounwind {
entry:
         ret i32 49
}

Here I get

define i32 @main() nounwind {
entry:
        ret i32 0
}

at -O1 and above.

Ciao,

Duncan.

I think you're looking at the output of llvm-gcc or clang, I'm assuming your parser is performing the optimization before it gets to LLVM. My parser isn't quite that smart: I'm letting LLVM do all the hard work. :wink:

I think that the example is using arrays as first class objects, especially this:

          %ar = alloca [10 x i8] ; <[10 x i8]*> [#uses=2]
          store [10 x i8] c"12\00\00\00\00\00\00\00\00", [10 x i8]* %ar

It's assigning an array constant to an array.

-Rich

Hi,

I think that the example is using arrays as first class objects,
especially this:

          %ar = alloca [10 x i8] ; <[10 x i8]*> [#uses=2]
          store [10 x i8] c"12\00\00\00\00\00\00\00\00", [10 x i8]* %ar

It's assigning an array constant to an array.

I missed that, sorry. I can reproduce it here by running "opt -std-compile-opts"
on the -O1 assembler you provided.

Ciao,

Duncan.

Hi Richard, Duncan,

> I have been working on using arrays and structs as first class objects.
good to hear! The example doesn't make use of that though, does it?

Not directly, but as soon as scalarrepl gets its hands on that array, it
becomes a first class array with extract values.

I already found the error, I was doing a preincrement and a dereference of the
same iterator in a single expression. AFAIK, ordering is not strictly defined
by C for that case, so that might explain why you are getting different
results.

Anyway, fixed here:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080714/065096.html

Thanks for reporting!

Gr.

Matthijs