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

David Mallasén Quintana via cfe-dev cfe-dev at lists.llvm.org
Wed Jan 26 04:19:35 PST 2022


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.
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


More information about the cfe-dev mailing list