Hi,
I'm working on a LLVM backend for OpenRISC and
noticed some odd behaviour when compiling busybox for uClibc
using Clang.
After digging in to the issue I found out that functions that
are declared with a transparent union argument got called
with the argument casted to the union instead of using the
calling convention of the first member of the union.
Let me show an example:
typedef union {
int *a;
char *b;
} ARG __attribute__ ((__transparent_union__));
void foo(ARG u);
void bar(int *a)
{
foo(a);
}
Turns into:
%union.ARG = type { i32* }
define void @bar(i32* %a) nounwind {
entry:
%a.addr = alloca i32*, align 4
%u = alloca %union.ARG, align 4
%agg.tmp = alloca %union.ARG, align 4
%.compoundliteral = alloca %union.ARG, align 4
store i32* %a, i32** %a.addr, align 4
%a1 = bitcast %union.ARG* %.compoundliteral to i32**
%0 = load i32** %a.addr, align 4
store i32* %0, i32** %a1, align 4
%1 = bitcast %union.ARG* %agg.tmp to i8*
%2 = bitcast %union.ARG* %.compoundliteral to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %1, i8* %2, i32 4, i32 4, i1 false)
call void @foo(%union.ARG* byval %agg.tmp)
ret void
}
declare void @foo(%union.ARG* byval)
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
When I would have expected something like:
define void @bar(i32* %a) nounwind {
entry:
%a.addr = alloca i32*, align 4
%u = alloca i32*, align 4
store i32* %a, i32** %a.addr, align 4
%0 = load i32** %a.addr, align 4
call void @foo(i32* %0)
ret void
}
declare void @foo(i32*)
I've been able to "solve" the problem by inserting conversions of the
argument type in various places in CodeGen, by it's more of an ugly hack
than a real solution as it is now.
I've got a feeling that the record type (with the transparent union attribute)
should be kept intact as long as possible, so I believe the ideal solution would
be to go through all possible places right before CodeGen, but I'm too much of
a Clang novice to be able to pinpoint where and how (and if my belief is right),
so it's here that I'd like some advice on this issue.
Stefan