Issues porting intrinsics to LLVM 10

I am maintaining proprietary extensions to the RISCV backend for our custom application.

I have defined intrinsics for many of the custom instructions. Against LLVM 7 this was working well.

When I try to merge my changes into LLVM 10, I get:

/home/dej/work/llvm_git/llvm-project/llvm/build/lib/Target/RISCV/RISCVGenGlobalISel.inc:11582:60: error: ‘idaho_mt_begin’ is not a member of ‘llvm::Intrinsic’
GIM_CheckIntrinsicID, /MI/0, /Op/0, Intrinsic::idaho_mt_begin,

This intrinsic is defined pretty simply:

let TargetPrefix = “idaho” in {
def int_idaho_mt_begin : Intrinsic<[], [llvm_ptr_ty,llvm_i64_ty], []>;
}

With LLVM 7, I notice that build/include/llvm/IntrinsicEnums.inc contains an entry for each intrinsic in the system. This is no longer the case for LLVM 10: there are only 277 definitions in the file. It seems that LLVM 10 imposes some filter condition where it deems inclusion in the IntrinsicEnums.inc unnecessary.

The other thing I notice: GlobalISel was not built (by default) in LLVM 7, but it is for LLVM 10. This is the entity referencing the enums.

I tried renaming my intrinsics to replace “idaho” with “riscv” speculating that this was the filtering condition, but that did not make any difference.

What has changed?

Intrinsic headers have been broken up into smaller files. Now you need to include the target-specific intrinsic header, e.g. IntrinsicsRISCV.h.

Thanks - I was able to get past this problem.

For the benefit of anyone googling a similar problem after me:

I had to fix two separate problems:

  1. Because intrinsic enum definitions are split out into target-specific includes, I needed to name my intrinsics properly.

The target splitter assumes that intrinsics of the form “llvm.foo…” go into “IntrinsicsFoo.h”. For this to work, “foo” must be a known target.

In my case, I was extending the RISCV instruction set with an intrinsic named “int_idaho_mt_begin”. Since “idaho” is not a valid target, I needed to rename to “int_riscv_idaho_mt_begin”. Note that doing so may require changes to both include/llvm/IR/IntrinsicsXXX.h and lib/Target/XXX/XXXInstrInfo.td (or some file referenced by it). You will also have to update any front ends to use the new names.

  1. RISCVGenGlobalISel.inc is included from RISCVInstructionSelector.cpp. Since this file does not already reference intrinsic definitions, the include needed to be added there. The full path relative to your build directory is required:

#include “llvm/IR/IntrinsicsRISCV.h”

With these changes I was able to generate code using my intrinsics with LLVM 10.