As far as I know, microTVM has supported qemu-riscv, you can find some information in tvm/apps/microtvm, or search for some discussions in this forum, for example here.
generic-rv64 only supportsI instructions (RV64I Base Integer instruction set).
To use MAFD instructions (aka RV64GC) we can specify -mcpu=sifive-u54 in llvm string.
I saved the lib to assembly file to check the generated instructions
lib.save("model.s")
-mcpu=sifive-u54 assembly code shows that it uses MAFD and C instructions (RV64GC)
Line 3 in model.s
.attribute 5, "rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0"
In the file I can find the following instructions
mulw
fdiv.s
fadd.s
A bit strange that I do not see double precision instructions such as fdiv.d…
Problem is that I still have the issue with linking
riscv64-unknown-linux-gnu/bin/ld: /tmp/tmp_zy2om28/lib0.o: can't link soft-float modules with double-float modules
Why lib0.o is soft-float??? The assembly code clearly shows that it uses M and F instructions.
/usr/bin/riscv64-linux-gnu-ld: test2.o: can't link soft-float modules with double-float modules
/usr/bin/riscv64-linux-gnu-ld: failed to merge target specific data of file test2.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Update - missing llc parameter is -target-abi=lp64d.
I haven’t tied to generate double float object file with clang, but can get it by riscv64-unknown-linux-gnu-gcc, and here in TVM can get the llvm module object file,
can you explain more about it, except for SaveToFile function or calling external compilers, I don’t know where it calls for llc to get object file, thanks!
clang generated object file is “hard-float” and can be linked to shared library just fine (even with gcc). (in contrast, llc generated object file still has soft-float issue)
To avoid the steps above we need to fix TVM to recognize -target-abi=lp64d llvm parameter in target string. After that we can use relay.build / lib.export_library as usual.
Looks like we also need to fix devc.o generation in case when relay.build generates single output - GraphExecutorFactoryModule instead of three outputs graph, lib, params.
with tvm.transform.PassContext(opt_level=3):
#graph, lib, params = relay.build(mod, target=target, target_host=target_host, params=params)
lib = relay.build(mod, target=target, target_host=target_host, params=params)
lib.export_library(path_lib, cc="riscv64-linux-gnu-g++-10", options=["-march=rv64gc","-mtune=sifive-u54", "-mabi=lp64d"])
/usr/lib/gcc-cross/riscv64-linux-gnu/10/../../../../riscv64-linux-gnu/bin/ld: error: /tmp/tmp3yrlbrsk/devc.o: ISA string of input (rv32i2p0) doesn't match output (rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0).
Update:
devc.o compilation was fixed too - the PR was updated.