Closed tpunix closed 1 year ago
It seems we don't support function pointers as operands to select
, indeed. I can reproduce this problem with the LLVM IR produced by Clang for this tiny program:
void puts(const char *);
void a(void)
{
puts("a");
}
void b(void)
{
puts("b");
}
int main(int argc, char **argv)
{
void (*fp)(void) = (argc > 1 ? a : b);
fp();
}
This is probably easy to fix…
Oh, I see, the problem is that we want to build a llvm_select_xxx
helper function, where xxx
is some legal C identifier that we use to uniquely identify the type, and we don't have support for building those for function pointers. Not sure how easy that is to fix.
Essentially it's a mangled function name. I wonder if we could re-use LLVM's name-mangling functionality rather than reinventing the wheel?
Okay, a trivial change is enough to make this work:
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index bb3653f..4cf9a8c 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -280,6 +280,10 @@ raw_ostream &CWriter::printTypeString(raw_ostream &Out, Type *Ty,
case Type::X86_MMXTyID:
return Out << (isSigned ? "i32y2" : "u32y2");
+
+ case Type::FunctionTyID:
+ return Out << getFunctionName(cast<FunctionType>(Ty));
+
#if LLVM_VERSION_MAJOR > 10
case Type::FixedVectorTyID:
case Type::ScalableVectorTyID:
Hopefully I'll remember to make this into a pull request.
This line: %5 = select i1 %4, void (i8, i16, i8, i16) %0, void (i8, i16, i8, i16) null, !dbg !581 will report error:
Unknown primitive type: void (i8, i16, i8*, i16)