Hi,
I am beginning the porting process for Linux on System z (aka IBM
Mainframe). I thought I¹d build LLVM first with the c and cpp backends so
that tools like TableGen would be created that I¹d then use to process the
.td files that I¹ll be creating. So I used svn to grab the code from the
repository and ran configure and make. However, the build breaks at this
point:
Is this a known problem? Would it be better to build the tools etc. using a
"stable" tarball and just use the svn sources so I can generate the patches
for adding System z?
llvm[1]: Building Intrinsics.gen.tmp from Intrinsics.td
tblgen: IntrinsicEmitter.cpp:163: void EmitTypeForValueType(std::ostream&,
llvm::MVT::SimpleValueType): Assertion `false && "Unsupported ValueType!"'
failed.
this came up before IIRC, but I don't remember the details - buggy system
compiler? Try searching the archives. Also, if you were compiling with
optimization, try building without optimization.
I searched the archives and found this from last month:
I ran into the same problem and fixed it by forcing the
MVT::SimpleValueType enum to be 64 bits so that all of the types
in the union later in the class are the same size. I tested this
on ppc64 and x86_64.
The comment in the above fix indicates that in this 64-bit system the enum
needs to be 64-bits is correct, but the fix doesn't seem to do it.
the basic problem seems to be that your system compiler is miscompiling
LLVM. Mucking around with the details of the union in the hope of tricking
the compiler into not miscompiling is one approach, but as you saw each
broken compiler tends to be broken differently I'm quite surprised
though because you said you are using gcc 4.3 (right?). This may be a
sign that something is wrong in LLVM rather than in the system compiler...
Did it work when building without optimization?
No it didn't work without optimization. Looking at all the C++ manuals etc.
the idea of forcing an enum to a different size is a practice fraught with
danger. It appears gcc 4.3.3 insists on sizeof(enum) == sizeof(int) so the
union trick is not going to work. Is there any reason it needs to be an
enum? Could SimpleValueType be a typedef long which means the union would
work for _LP64 and _LP32 systems?
Yes, that works much better. However, I fear the problem is more to do with
trying to force enums to be a different size which appears not to be
supported by most compilers. The IBM C++ compiler apparently has a #pragma
which can be used to do it and gcc 4.3 seems to be happy with the hack
described but as Duncan says trying to force this behavior in a union is
probably less than desirable in the long term.
Yes, that works much better. However, I fear the problem is more to do with
trying to force enums to be a different size which appears not to be
supported by most compilers. The IBM C++ compiler apparently has a #pragma
which can be used to do it and gcc 4.3 seems to be happy with the hack
described but as Duncan says trying to force this behavior in a union is
probably less than desirable in the long term.
I don't know if the union is invoking undefined behaviour or not, but given
the number of compilers it breaks it clearly needs to be changed. I'm not sure
the enum needs to be an enum, how about turning it into a uintptr_t instead?