Say I have the following code:
main.c:
void foo(char *, ...);
void bar(int, ...);
int main(void)
{
foo("foo", 1);
bar(1, 2, 3, "bar");
return 0;
}
foobar.c:
int printf(const char *, ...);
void foo(const char *str, int i)
{
printf("%s: %d\n", str, i);
}
void bar(int i, int j, int k, const char *str)
{
printf("%s sum: %d\n", str, i+j+k);
}
When I compile these separately and run llvm-ld -disable-opt I get this
unfortunate sequence:
define i32 @main() nounwind {
entry:
%retval = alloca i32 ; <i32*> [#uses=2]
%0 = alloca i32 ; <i32*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
call void (i8*, ...)* bitcast (void (i8*, i32)* @foo to void (i8*, ...)*)
(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 1) nounwind
call void (i32, ...)* bitcast (void (i32, i32, i32, i8*)* @bar to void
(i32, ...)*)(i32 1, i32 2, i32 3, i8* getelementptr inbounds ([4 x i8]*
@.str1, i64 0, i64 0)) nounwind
It's unfortunate because the bitcast gets in the way. For example, looking
at the ValueMap in the linker one would expect a Function to map to a
Function. That's not true here. A Function maps to a bitcast. It also
means the generated code will be suboptimal on targets like x86-64 that
require extra processing for vararg calls.
This happens because RecursiveResolveTypes in LinkModules.cpp doesn't
understand that a "more fully specified" function argument list is compatible
with a "less fully specified" one and that it should be perfectly fine to
resolve the type to the more specified one.
Would it break things horribly if I went in and taught RecursiveResolveTypes
how to handle this or would that violate some deep-level assumption?
-Dave