JuliaHubOSS / llvm-cbe

resurrected LLVM "C Backend", with improvements
Other
808 stars 138 forks source link

Code generator does not support intrinsic function `llvm.fshl.i32` #111

Open XAMPPRocky opened 3 years ago

XAMPPRocky commented 3 years ago

In more attempts to compile Rust generated IR, I tried compiling the output from my project tokei, and I immediately get an error about an unsupported intrinsic.

LLVM ERROR: Code generator does not support intrinsic function 'llvm.fshl.i32'!
hzhangxyz commented 3 years ago

Hello, I am compiling cpp program, and llvm cbe also complains unsupported intrinsic(#102)

hikari-no-yume commented 3 years ago

@hzhangxyz That is a completely different intrinsic.

hikari-no-yume commented 3 years ago

It looks like this is yet another intrinsic we don't have support for, and that must be because it's quite new. Unfortunately, LLVM won't lower it (convert it to instructions we do support) for us. So I guess we have to implement it ourselves.

Anyway, I hacked the C backend to pretend to support the fshl intrinsic:

diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 7116b94..d9e2cbc 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -4673,6 +4673,9 @@ bool CWriter::lowerIntrinsics(Function &F) {
           case Intrinsic::dbg_value:
           case Intrinsic::dbg_declare:
             // We directly implement these intrinsics
+            
+            //FIXME:
+          case Intrinsic::fshl:
             break;

           default:
@@ -4833,7 +4836,8 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID) {
   switch (ID) {
   default: {
     DBG_ERRS("Unknown LLVM intrinsic! " << I);
-    errorWithMessage("unknown llvm instrinsic");
+    //errorWithMessage("unknown llvm instrinsic");
+    Out << ";"; // FIXME
     return false;
   }
   case Intrinsic::dbg_value:

I wanted to see if I'd get any more intrinsic errors. Sure enough, it complained about llvm.uadd.sat (for i16), so we also should add that.

There was also llvm.x86.sse2.pause, which is an x86-specific intrinsic. While we could add support for that, I assume you probably want to use C for portability reasons, and therefore you would want to get Rust to avoid that intrinsic by specifying a different target. Maybe something very generic like WebAssembly?

By the way, if you want to try to add support to LLVM-CBE for these intrinsics, it should be fairly easy. You just need to look up the intrinsic's definition in the LLVM Language Reference to find out what it does, write a simple C function that does the required task, and then modify CWriter::lowerIntrinsics, CWriter::visitBuiltinCall and CWriter::printIntrinsicDefinition so they accept it and spit out the C code you wrote.

(I will probably implement these intrinsics myself at some point, though.)


As an aside: wow, that's one massive LLVM IR file! 22MB, 256k lines… I guess that's a result of Rust considering an entire crate as one translation unit!

XAMPPRocky commented 3 years ago

By the way, if you want to try to add support to LLVM-CBE for these intrinsics, it should be fairly easy. You just need to look up the intrinsic's definition in the LLVM Language Reference to find out what it does, write a simple C function that does the required task, and then modify CWriter::lowerIntrinsics, CWriter::visitBuiltinCall and CWriter::printIntrinsicDefinition so they accept it and spit out the C code you wrote.

Unfortunately I don't have much if any experience with C (hence all the Rust), and wouldn't really feel comfortable writing those definitions.

There was also llvm.x86.sse2.pause, which is an x86-specific intrinsic. While we could add support for that, I assume you probably want to use C for portability reasons, and therefore you would want to get Rust to avoid that intrinsic by specifying a different target. Maybe something very generic like WebAssembly?

Well I'm not too concerned with the C being portable beyond being C, as I can use targets from rustc or add custom targets to rustc make sure it generates the right intrinsics. So it's more important that the code can run on that platform, than whether or not it's abstract over a number of platforms.

hikari-no-yume commented 3 years ago

Unfortunately I don't have much if any experience with C (hence all the Rust), and wouldn't really feel comfortable writing those definitions.

That's fine, I'm happy to do it myself (eventually).