Build error with gcc 4.1.1

Hello all,

I am trying to build llvm 1.8a with gcc 4.1.1 and I get the attached error.
Are there any easy workarounds or should I just try another version of gcc?

build-error (3.44 KB)

I haven't seen this error, but I'm not using GCC 4.1.1. It would be good to track this down and either file a bug with GCC or for us to get it fixed in LLVM. The offending line of code looks fine on our side, but there could be something I'm missing.

Known-good/bad versions of GCC are listed here:
http://llvm.org/docs/GettingStarted.html#brokengcc

-Chris

I fixed my immediate problem by using a different version
of gcc.

Chris Lattner kirjoitti:

The offending line of code looks fine on our side, but there could be something I'm missing.

For what it is worth, I've run into problems with boost_concept_check
before when using Boost.Python. Some versions of gcc worked fine,
while others gave error messages relating to boost_concept_check.
My guess is that it is due to some slight differences in how templates
are instantiated in different versions of gcc.

I fixed my immediate problem by using a different version
of gcc.

ok.

Chris Lattner kirjoitti:

The offending line of code looks fine on our side,
but there could be something I'm missing.

For what it is worth, I've run into problems with boost_concept_check
before when using Boost.Python. Some versions of gcc worked fine,
while others gave error messages relating to boost_concept_check.
My guess is that it is due to some slight differences in how templates
are instantiated in different versions of gcc.

Okay. Question: does GCC 4.1.2 (if it exists) or GCC mainline fix the problem? If so, we should document 4.1.1 as being buggy.

-Chris

FWIW, I returned to 3.4.6 when 4.1.1 didn't work out for me. I haven't
tried 4.1.2. I'm waiting for the dust to settle on 4.2

Reid

Do you recall what didn't work? Does 4.1.0 work? Documenting this in the GSG is really important for new users.

Thx,

-Chris

I am trying to symbolically execute LLVM assembly language. I found a possible
semantic inconsistancy of the LLVM assembly language, or maybe my understanding
is wrong.

The C code is:

#include <stdlib.h>

1 int f(void)
2 {
3 int a;
4 int *b = (int *) malloc(3*sizeof(int));
5 a = 3;
6 return 0;
7 }

I compile it with llvm-gcc 4 front end. The generated LLVM assembly code is:

1 target endian = little
2 target pointersize = 32
3 target triple = "i686-pc-linux-gnu"

4 implementation ; Functions:

5 int %f() {
6 entry:
7 %retval = alloca int, align 4 ; <int*> [#uses=2]
8 %tmp = alloca int, align 4 ; <int*> [#uses=2]
9 %a = alloca int, align 4 ; <int*> [#uses=1]
10 %b = alloca int*, align 4 ; <int**> [#uses=1]
11 "alloca point" = cast int 0 to int ; <int> [#uses=0]
12 %tmp = call sbyte* %malloc( uint 12 ) ; <sbyte*> [#uses=1]
13 %tmp1 = cast sbyte* %tmp to int* ; <int*> [#uses=1]
14 store int* %tmp1, int** %b
15 store int 3, int* %a
16 store int 0, int* %tmp
17 %tmp = load int* %tmp ; <int> [#uses=1]
18 store int %tmp, int* %retval
19 br label %return

20 return: ; preds = %entry
21 %retval = load int* %retval ; <int> [#uses=1]
22 ret int %retval
23 }

declare sbyte* %malloc(uint)

After line 8, %tmp holds a pointer to stack, whose type is int*
After line 12, %tmp holds a pointer to heap, whose type is sbyte*

At line 16, value 0 is to be stored to a memory location of type int
pointed to by %tmp. But at this time %tmp is holding a pointer to
heap of type sbyte. And the heap should not be written to. (There is
no assignment to b[0] in the C code.)
So I guess that %;tmp also holds its original value, which is a pointer
to stack of type int. And we can decide which location to store according
to the type.

Could someone explain this for me? Thanks.

-- Zhongxing Xu

Zhongxing Xu wrote:

After line 8, %tmp holds a pointer to stack, whose type is int*
After line 12, %tmp holds a pointer to heap, whose type is sbyte*

Yes, the same name can be used for two different variables of two
different types. It's an annoying quirk, but otherwise harmless. When
reading such code, just keep an eye on the type of each instruction so
that you don't get the two confused.

In your case, there are three variables with the same name: one int*
defined on line 8, one sbyte* on line 12 and one int on line 17. The
sbyte* is only used on line 13 and the int is only used in line 18. The
others are all the int* variable.

Nick Lewycky

Zhongxing Xu,

I am trying to symbolically execute LLVM assembly language. I found a
possible
semantic inconsistancy of the LLVM assembly language, or maybe my
understanding
is wrong.

The C code is:

#include <stdlib.h>

1 int f(void)
2 {
3 int a;
4 int *b = (int *) malloc(3*sizeof(int));
5 a = 3;
6 return 0;
7 }

I compile it with llvm-gcc 4 front end. The generated LLVM assembly code
is:

1 target endian = little
2 target pointersize = 32
3 target triple = "i686-pc-linux-gnu"

4 implementation ; Functions:

5 int %f() {
6 entry:
7 %retval = alloca int, align 4 ; <int*> [#uses=2]
8 %tmp = alloca int, align 4 ; <int*> [#uses=2]
9 %a = alloca int, align 4 ; <int*> [#uses=1]
10 %b = alloca int*, align 4 ; <int**> [#uses=1]
11 "alloca point" = cast int 0 to int ; <int> [#uses=0]
12 %tmp = call sbyte* %malloc( uint 12 ) ; <sbyte*>
[#uses=1]
13 %tmp1 = cast sbyte* %tmp to int* ; <int*>
[#uses=1]
14 store int* %tmp1, int** %b
15 store int 3, int* %a
16 store int 0, int* %tmp
17 %tmp = load int* %tmp ; <int> [#uses=1]
18 store int %tmp, int* %retval
19 br label %return

20 return: ; preds = %entry
21 %retval = load int* %retval ; <int> [#uses=1]
22 ret int %retval
23 }

declare sbyte* %malloc(uint)

After line 8, %tmp holds a pointer to stack, whose type is int*
After line 12, %tmp holds a pointer to heap, whose type is sbyte*

SSA Register names, like %tmp in your example, are unique within their
type. They are *not* scoped variable names. Furthermore, due to SSA
requirements, each register name can only be assigned ones (one def,
zero or more uses). It would be illegal to have another int* assigned
to the variable %tmp because that violates SSA rules. However, you can
have a multitude of %tmp registers as long as they are all of different
types. Note that LLVM will rename a register if it finds a duplicate, as
was the case for %tmp1 on line 13. This was necessary because %tmp and %
tmp1 both have the same type (sbyte*).

At line 16, value 0 is to be stored to a memory location of type int
pointed to by %tmp. But at this time %tmp is holding a pointer to
heap of type sbyte.

Actually its not. The two %tmp names are referring to things of
different types. One is int*, the other is sbyte*. These are what we
loosely call "type planes" in LLVM. That is, within a given type plane
all names are unique. But there is no requirement for names to be unique
across type planes.

So, the %tmp on line 16 is referring to the %tmp defined on line 8.

And the heap should not be written to. (There is
no assignment to b[0] in the C code.)

The stack is written to through int* %tmp (def on line 8) but the heap
is not written.

So I guess that %;tmp also holds its original value, which is a pointer
to stack of type int.

Correct.

And we can decide which location to store according to the type.

Righ.

Could someone explain this for me? Thanks.

I think I just did.

You might want to read the http://llvm.org/docs/LangRef.html document.

Reid.

Chris Lattner kirjoitti:

Question: does GCC 4.1.2 (if it exists) or GCC mainline fix the problem? If so, we should document 4.1.1 as being buggy.

GCC 4.1.2 does not exist yet, but I grabbed the 4.2-20060906
snapshot of GCC and it compiled LLVM without problems. I verified
that the hello world example from Getting Started worked, but did
not test beyond that. This is on x86 Gentoo.

Thank you for investigating this. I added a note to the GSG to avoid GCC 4.1.1. Thanks!

-Chris