[cfe-dev] Questions on adding a CLANG builtin to connect to a LLVM intrinsic

Jessica Clarke via cfe-dev cfe-dev at lists.llvm.org
Wed Jan 26 05:58:30 PST 2022


On 26 Jan 2022, at 12:19, David Mallasén Quintana via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> 
> Hello,
> 
> Following up on this, and trying to do something similar to
> https://github.com/llvm/llvm-project/commit/16877c5, I am trying to
> add a simple Clang builtin: void __builtin_riscv_foo() that should
> output an intrinsic @llvm.riscv.foo() which will outpu, with a pattern
> in the backend, a simple custom instruction FOO without parameters.
> However, when compiling I receive the following error:
> 
> clang: llvm/lib/IR/Function.cpp:844: std::string
> llvm::Intrinsic::getName(llvm::Intrinsic::ID,
> llvm::ArrayRef<llvm::Type*>, llvm::Module*, llvm::FunctionType*):
> Assertion `(Tys.empty() || Intrinsic::isOverloaded(Id)) && "This
> version of getName is for overloaded intrinsics only"' failed.

As you can see, it’s telling you that you’re treating your intrinsic as
an overloaded intrinsic, but your intrinsic isn’t polymorphic (it
doesn’t even have any arguments or return types, let alone overloaded).
You can see towards the bottom of EmitRISCVBuiltinExpr the
IntrinsicTypes = {ResultType}, which is the list of types used to
instantiate the overloads. Since you have no overloads, that list
should be empty for your intrinsic, so you should not be reusing that
bit of code and instead have a separate top-level case statement.

Jess

> PLEASE submit a bug report to https://bugs.llvm.org/ and include the
> crash backtrace, preprocessed source, and associated run script.
> Stack dump:
> 0.    Program arguments: clang --target=riscv64 -march=rv64gcxbar
> intrinsics_test.c -c -o intrinsics_test.o
> 1.    <eof> parser at end of file
> 2.    intrinsics_test.c:21:6: LLVM IR generation of declaration 'test'
> 3.    intrinsics_test.c:21:6: Generating code for declaration 'test'
> 4.    intrinsics_test.c:22:33: LLVM IR generation of compound statement ('{}')
> 5.    intrinsics_test.c:23:37: LLVM IR generation of compound statement ('{}')
> 
> To get to this point I have added the following code:
> In clang/include/clang/Basic/BuiltinsRISCV.def:
>    TARGET_BUILTIN(__builtin_riscv_foo, "v", "n", "xbar")
> 
> In clang/lib/CodeGen/CGBuiltin.cpp : EmitRISCVBuiltinExpr:
>    case RISCV::BI__builtin_riscv_foo: {
> and later in that same function
>    case RISCV::BI__builtin_riscv_foo:
>        ID = Intrinsic::riscv_foo;
>        break;
> 
> In llvm/include/llvm/IR/IntrinsicsRISCV.td:
>    let TargetPrefix = "riscv" in {
>        def int_riscv_foo : Intrinsic<[], [], []>;
>    }
> 
> In llvm/lib/Target/RISCV/RISCVISelLowering.h:
>    FOO, // Before ISD::FIRST_TARGET_MEMORY_OPCODE
> 
> In llvm/lib/Target/RISCV/RISCVISelLowering.cpp : LowerINTRINSIC_WO_CHAIN:
>    case Intrinsic::riscv_foo: {
>        return DAG.getNode(RISCVISD::FOO, DL, XLenVT);
>    }
> and in RISCVTargetLowering::getTargetNodeName:
>   NODE_NAME_CASE(FOO)
> 
> In llvm/lib/Target/RISCV/RISCVInstrInfoBar.td
>    def riscv_foo : SDNode<"RISCVISD::FOO", SDTypeProfile<0, 0, []>>;
>    def : Pat<(riscv_foo), (FOO)>;
> 
> I think the test for the Clang builtin should be:
> // RUN: %clang_cc1 -triple riscv64 -target-feature +xbar -emit-llvm %s -o - \
> // RUN:     | FileCheck %s  -check-prefix=RV64Xbar
> 
> // RV64Xbar-LABEL: @foo(
> // RV64Xbar-NEXT:  entry:
> // RV64Xbar-NEXT:    call void @llvm.riscv.foo()
> // RV64Xbar-NEXT:    ret void
> //
> void foo() {
>    __builtin_riscv_foo();
> }
> 
> Is there something missing that I can't find? I have tried small
> variations of this code with no success.
> 
> Best regards,
> David
> 
> El mar, 18 ene 2022 a las 12:34, David Mallasén Quintana
> (<dmallase at ucm.es>) escribió:
>> 
>> Hello,
>> 
>> I have added new instructions to the RISC-V LLVM backend for some
>> specific hardware I developed and I want to access a sequence of them
>> directly from C code. As of now I do this using inline assembly but it
>> can be a bit cumbersome. If I'm not mistaken the way to go would be to
>> access this functionality from C with CLANG builtins and lowering this
>> to machine code with LLVM intrinsics that generate my target RISC-V
>> instructions.
>> 
>> I have seen the documentation on how to add LLVM intrinsics. However,
>> I can't find something similar with CLANG builtins, so any pointers to
>> some documentation would be greatly appreciated. Also, if there is a
>> better way of achieving this I would be grateful for some information
>> on how it could be done.
>> 
>> Best regards,
>> David
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



More information about the cfe-dev mailing list