Question about SPARC target status

Hello,

I've noticed SPARC target lacks some of functionality (only asm printer is implemented with no binary code emitter and no 64-bit ABI support).

Are there any (probably uncommited) advances in these areas? The most needed feature for me is sparc64 support. If I decide to implement these ones by myself what are the problems/guidelines/whatever? Why hasn't this been done before? I mean is it some technical problem or just lack of time?

Hi Peter,

The SPARC target is currently suffering from lack of maintainer. I wrote most of the current sparc port and got it working pretty well, but haven't had time (or machines) to do further development. I would love to see someone add 64-bit ABI and JIT support. I don't know of any outstanding patches to add this. The good news is that there are no technical problems here, just lack of time.

-Chris

Hi,

but haven't had time (or machines) to do further development. I would
love to see someone add 64-bit ABI and JIT support. I don't know of

And fix 32 bit ones :slight_smile: Mostly byval stuff + FP arguments.

It looks like I'm going to be working on the 32-bit stuff periodically over the next couple of months so that I can run tests on the Niagara (and soon Rock) processors.

Luke

Anton Korobeynikov wrote:

And fix 32 bit ones :slight_smile: Mostly byval stuff + FP arguments.

How serious these bugs are? Any link to bug descriptions? Is LLVM sparc target usable and stable in case of not using any FP stuff?

There are usually two levels of translation that go on. First, your C/C++ code is compiled to LLVM IR using llvm-gcc. Then, LLVM generates SPARC assembly from the LLVM IR.

llvm-gcc isn't prepared to compile for a SPARC target. This includes lack of complete FP support, and no implementation of the SPARC ABI which means that function arguments aren't passed correctly and you probably can't call any precompiled code that assumes the SPARC ABI. I will be working on fixing this for sparc-solaris, but not sparc64.

LLVM code generation doesn't appear to correctly implement atomic builtins, but that should be a trivial thing to fix (so they tell me).

-Luke

Hi,

Luke K. Dalessandro wrote:

llvm-gcc isn't prepared to compile for a SPARC target. This includes lack of complete FP support, and no implementation of the SPARC ABI which means that function arguments aren't passed correctly and you probably can't call any precompiled code that assumes the SPARC ABI. I will be working on fixing this for sparc-solaris, but not sparc64.

I thought llvm-gcc isn't meant to compile for specific target (at least with -emit-llvm flag I'm using).

Speaking of SPARC ABI can I still call non-FP external (i.e. compiled with regular non-llvm gcc to native sparc binary) functions from within LLVM code? Or ABI is competely broken?

LLVM code generation doesn't appear to correctly implement atomic builtins, but that should be a trivial thing to fix (so they tell me).

Do you mean calls like __gnu_cxx::__exchange_and_add ?

Slightly off topic, but I am looking to set up a sparc buildbot on one
of our sparcs. This won't help with the incompleteness of the
backend, but it will at least help keep sparc building.

Andrew

Hi,

I thought llvm-gcc isn't meant to compile for specific target (at least
with -emit-llvm flag I'm using).

No, it is not. C language is highly target-specific, thus LLVM IR
obtained from such sources also has the same nice 'property'

Speaking of SPARC ABI can I still call non-FP external (i.e. compiled
with regular non-llvm gcc to native sparc binary) functions from within
LLVM code? Or ABI is competely broken?

I think best answer will be: try it and let us know :slight_smile: Currently there
is no active sparc maintainer, thus it will be safe to assume it to be
arbitrary broken.

Do you mean calls like __gnu_cxx::__exchange_and_add ?

http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html

That would be excellent!
What OS is it running? (Solaris, Linux?)

Best regards,
--Edwin

Solaris.

Andrew

Speaking of SPARC ABI can I still call non-FP external (i.e. compiled
with regular non-llvm gcc to native sparc binary) functions from within
LLVM code? Or ABI is competely broken?

I think best answer will be: try it and let us know :slight_smile: Currently there
is no active sparc maintainer, thus it will be safe to assume it to be
arbitrary broken.

From my very brief visual inspection it seems like it should probably work

for code that doesn't try and pass or return a structure, complex number, or double precision floating point number by value, or use any type of nifty calling convention like FASTCALL or whatever else gcc defines.

This is completely untested though.

-Luke

Do you mean calls like __gnu_cxx::__exchange_and_add ?

http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html

I was actually referring to llvm.atomic.* that is in my .ll code. I get "not-yet-implemented" errors.

-Luke

Hi,

Anton Korobeynikov wrote:

I thought llvm-gcc isn't meant to compile for specific target (at least
with -emit-llvm flag I'm using).

No, it is not. C language is highly target-specific, thus LLVM IR
obtained from such sources also has the same nice 'property'

I can see only one reason for such dependence: inclusion of system headers in /usr/include. If I compile llvm-gcc with predefined set of Linux headers (the way cross-compilers are usually made) will the IR output be the same no matter which platform is used for compilation?

I had trouble with this too -- I still haven't entirely figured it out. Try browsing through http://www.gaisler.com/doc/sparc-abi.pdf which is the SPARC ABI. It explains things like structure padding and stack layout/function calling. llvm-gcc has to make lots of decisions dependent on this ABI when converting C/C++ to IR. I imagine that every platform has its own rules.

The SPARC rules actually seem relatively straightforward.

-Luke

No. Consider use of sizeof(), ABI issues, etc.

--Owen

I'd expect llvm-gcc to get the structure layout rules "for free". You could write some testcases to verify this. The case that requires a bit of work are the various parameter passing cases if there is weirdness. When I was working on the sparc backend, just about everything was passing in llvm-test, so I think it is pretty close to good.

-Chris

Chris Lattner dixit:

When I was working on the sparc backend, just about everything was
passing in llvm-test, so I think it is pretty close to good.

So, if I patch llvm-gcc with MirBSD/sparc rules in gcc/config.gcc
and gcc/config/sparc/ like I did with i386, chances are it would
work (in a limited fashion)? Or is sparc support in llvm specific
to Solaris?

bye,
//mirabilos

Hi,

Owen Anderson wrote:

I can see only one reason for such dependence: inclusion of system
headers in /usr/include. If I compile llvm-gcc with predefined set of
Linux headers (the way cross-compilers are usually made) will the IR
output be the same no matter which platform is used for compilation?

No. Consider use of sizeof(), ABI issues, etc.

Ooh, now I see llvm-gcc is not cross-compiler in the terms of GCC. Okay, but what if I actually compile LLVM-gcc as cross-compiler for 64-bit x86-64 Linux. Then it is guaranteed to produce identical output on all the systems.

Question is: how the resulting LLVM IR will run on 32-bit machine? Should I create stubs for all called functions to convert between 32 and 64-bit pointers? Or it won't run at all?

If you configure it as a cross-compiler for 64-bit x86 Linux and feed it the appropriate header files, it will produce the same output on any platform. However, that output will not be executable on most platforms, just on 64-bit x86 Linux. The problems go beyond pointer size. The size of int is implementation dependent, etc. The layout and padding of structs is implementation dependent. While all implementations on a given target-triple will generally agree to ensure binary compatibility, there is no guarantee of things being the same once you go to another target-triple.

--Owen

Owen Anderson wrote:

If you configure it as a cross-compiler for 64-bit x86 Linux and feed it the appropriate header files, it will produce the same output on any platform. However, that output will not be executable on most platforms, just on 64-bit x86 Linux. The problems go beyond pointer size. The size of int is implementation dependent, etc. The layout and padding of structs is implementation dependent. While all implementations on a given target-triple will generally agree to ensure binary compatibility, there is no guarantee of things being the same once you go to another target-triple.

Do you mean that cross-target execution CAN break on examples like this one? [eventually on this example it doesn't]

   struct X {
     void *a;
     int b;
   } x;

   *(int *) ((char *)&x + sizeof(void*)) = 1;

However this one will work because getelementptr is wise enough:

   struct X {
     void *a;
     int b;
   } x;

   x.b = 1;

Now I avoid the former code sample and likes of it and figure out every problem of alignment. Do I have the chance to run the same LLVM IR on platform of different bitness?

BTW: is there a plan to introduce expressions as constants (including sizeof() operation) in IR? It will rule out some of llvm-gcc compile time optimizations but the resulting code will be much more portable.