llvm-gcc-4.2 RELEASE_26 bootstrap failure on Solaris/SPARC - unhandled REAL_TYPE during compilation of '__powitf2'

Hi all,
I'm currently trying to bootstrap llvm-gcc-4.2 from the latest stable LLVM release 2.6
on Solaris SPARC.

The compilation with a self-build gcc-4.2.4 goes pretty well, however, I hit
a seemingly widely know error during llvm-gcc's bootstrap in getting
an assertion during the compile of /data/LLVM/src/GCC/RELEASE_26/gcc/libgcc2.c:

/data/LLVM/src/GCC/RELEASE_26/gcc/libgcc2.c: In function '__powitf2':
/data/LLVM/src/GCC/RELEASE_26/gcc/libgcc2.c:1765: internal compiler error: in HandleArgument, at llvm-abi.h:535

Looking into the code of llvm-abi.h, I added the following patch to it:
--- /data/LLVM/src/GCC/RELEASE_26/gcc/llvm-abi.h.jnz Thu Oct 29 00:32:52 2009
+++ /data/LLVM/src/GCC/RELEASE_26/gcc/llvm-abi.h Fri Oct 30 13:09:09 2009
@@ -529,7 +529,12 @@
          HandleArgument(TREE_TYPE(type), ScalarElts);
          C.ExitField();
        }
+ } else if (TREE_CODE(type) == REAL_TYPE) {
+ fprintf(stderr,"unhandled REAL_TYPE!\n");
+ assert(0 && "unhandled REAL_TYPE!");
+ abort();
      } else {
+ fprintf(stderr,"unknown aggreate type %d\n",TREE_CODE(type));
        assert(0 && "unknown aggregate type!");
        abort();
      }

Note that at first, I only inserted the last fprintf to get a better
understanding what's going wrong and found out that TREE_CODE(type) has
value 9 which matches REAL_TYPE from my understanding.

With the full patch, I get the assertion of the 'unhandled REAL_TYPE!',
so I wonder what needs to be done in order to get LLVM to produce
code for 'TREE_CODE(type) == REAL_TYPE' in the 'HandleArgument' function.

Does anyone have an idea? And why does this only happen on SPARC?

Regards,
   Juergen

Hello, Juergen

With the full patch, I get the assertion of the 'unhandled REAL_TYPE!',
so I wonder what needs to be done in order to get LLVM to produce
code for 'TREE_CODE(type) == REAL_TYPE' in the 'HandleArgument' function.

Does anyone have an idea? And why does this only happen on SPARC?

What is the value of "Ty" in your case? Just do "call Ty->dump()".

Hi Anton,
thanks for the fast response.

Ty->dump() prints "{double, double}" in the failing case (just before my
introduced assert).

HTH, and regards,
   Juergen

Hello, Juergen

Ty->dump() prints "{double, double}" in the failing case (just before my
introduced assert).

The answer is simple. The code in question contains extended IEEE FP
argument / return type (aka 'long double'). By default it's lowered
into struct {double, double} as you already saw and sparc currently
does not provide any argument layout hooks.

There are two possible solutions for a moment:
1. Temporary turn 128-bit fp into 64-bit fp (there should be some
define in config/sparc/*)
2. Turn 128bit fp into normal first-class type (grep for TARGET_ZARCH
into llvm-types.cpp, where this mapping is done for s390x), but then
you will need to implement all codegen for 128-bit fp, since sparc
backend is currently really weak.

Anton,
I went with the first alternative with some success.

However, now I get some errors during the build of libgcc
with 'multiply defined symbols'.

One thing I noticed is the following fact:

Definition in unwind-pe.h:

static const unsigned char *
read_sleb128 (const unsigned char *p, _Unwind_Sword *val)

Hello, Juergen

which means that LLVM generates this static function as global instead
of local like the native GCC does.
Any idea how this could be fixed?

sparc asmprinter is old and was not maintained for years. Recently
there was some huge asmprinter infrastructure refactoring in the LLVM.
This might be just fallout from it. Or, the asmprinting is just
incomplete.

You might want to look there and, if possible, fix it (the best way
will be migration to MCInst).