[LLVMdev] llvm/test: suffix or operands invalid for `push'

Joachim Durchholz jo at durchholz.org
Sat Mar 1 16:27:30 PST 2008

Am Samstag, den 01.03.2008, 10:57 -0800 schrieb Chris Lattner:
> > # Configure & install
> > $ cd llvm-2.2
> > # I'm trying the --build option, too.
> > $ ./configure --prefix=$HOME CC=gcc-4.2 CXX=g++-4.2 \
> >  --build=x86_64-pc-linux-gnu \
> >  --host=i686-pc-linux-gnu --target=i686-pc-linux-gnu
> This is probably the problem.  It sounds like you have llvm-gcc  
> building for x86-64 (so the compiler defaults to emitting x86-64 code)

Hmm... did I misunderstand ./configure --help? It says
  --build=BUILD   configure for building on BUILD [guessed]
  --host=HOST     cross-compile to build programs to run on HOST [BUILD]
  --target=TARGET configure for building compilers for TARGET [HOST]
which I interpreted to mean:
--build - the arch the build process will run on (usually the same as
the current machine, though in some cases people might want to
run ./configure on one machine and then distribute it to other machines)
--host - the arch the compilers will be run on
--target - the arch the programs compiled by the compilers will run on

In my case, since I'm using an amd64 machine that can run both 32-bit
and 64-bit code, this would mean that any combination of x86_64 and i686
for --build, --host, and --target should work.
Since llvm cannot generate code for amd64 at this time, this translates
to an additional constraint on --target, restricting me to --target=i686
If I wish to compile llvm-gcc, and compile llvm itself using llvm-gcc,
I'd have to set both --host and --target as i686.

Well, at least that's how I interpret these options. If that
interpretation is correct, then I suspect there's a bug in the way the
configure script processes these options.

> but your assembler defaults to x86-32.  Thus, your assembler requires - 
> m64 to be passed for it to grok 64-bit code, which isn't being passed  
> by the test.

Actually it's the other way round: the assembler needs a --32 option. I
had set CCFLAGS and CXXFLAGS to -Wa,--32 (the Wa meaning "pass the
following options to as", and the --32 tells as it's being fed 32-bit
assembly instructions), and with that, the assembly instructions would
pass without an error.
After that, the linker would complain because it tried to link the
default 64-bit libraries with the 32-bit object files generated by the
assembler. That's the point at which I started to think that -Wa,--32 is
probably a fix that's a bit too low-level; besides, sorting out 32-bit
and 64-bit libraries sounded like Very Much Not Fun, and hoped I could
avoid the issue by placing the toolchain in 32-bit mode.

> Does it work if you change the top of that test to:
> ...
> // RUN: as -m64 NoCompileUnit.s -o NoCompileUnit.o
> ..
> ?

Lemme see (and checking my own hypotheses, of course...)

... gives me
  as: unrecognized option `-m64'
This is actually gas, the GNU assembler. It expects a --64 or a --32
option (or --arch=<whatever>, but I'll stick with --64 for now)

BTW I see that the RUN lines are using g++. Shouldn't they use $(CXX) so
that the same toolchain is used for building and testing llvm? After
all, I did
  ./configure CXX=gcc-4.2
specifically to avoid miscompilation issues with the default gcc on
Ubuntu, which is currently 4.1. I have also been toying with the idea of
compiling llvm with llvm-gcc, and it would be quite reassuring if I
could run the tests using just the llvm infrastructure.

Now back to our regularly scheduled programme, and trying --64 now:
... gives me the same old "suffix or operand invalid for pop/push"

Trying with --32:
  FAIL: /home/jo/Delta/llvm-2.2/test/\
  Failed with exit(1) at line 3
  while running: g++ NoCompileUnit.o -o NoCompileUnit.exe
  /usr/bin/ld: i386 architecture of input file `NoCompileUnit.o' is
  incompatible with i386:x86-64 output
  collect2: ld gab 1 als Ende-Status zurück
So the assembler is doing its thing (no error message from that stage),
but after that, ld fails because it wasn't told to use the 32-bit libs.

However, if the llvm build/test machinery mishandles --build/host/target
somewhere, things *should* work if all three are uniformly set for 32
Trying that approach with
$ ./configure --prefix=$HOME  CC=gcc-4.2 CXX=g++-4.2 \
  --build=i686-pc-linux-gnu \
  --host=i686-pc-linux-gnu \
$ make
$ make check
... well, what shall I say: it's still saying
  Host is x86_64-unknown-linux-gnu
and giving me
  NoCompileUnit.s:33: Error: suffix or operands invalid for `push'
(plus variations of the latter).

My best hypothesis is that the test simply doesn't follow ./configure.

Would it make sense to skip the short test entirely and proceed with the
full test suite? I had considered running it anyway, so that wouldn't be
a serious problem for me.
Heck, I'd even compile llvm-gcc using llvm and good riddance to the
preinstalled gcc/g++ infrastructure, I wasn't planning on using it for
more than doing the initial bootstrap anyway. I'm not sure whether that
solves more problems than it creates though, and that's why I didn't try
to that yet - but I'm beginning to think it might be the easier route
for me.


More information about the llvm-dev mailing list