How to add a new intrinsic function?

in " RISCVISelLowering.h " of

    namespace RISCVISD { 
      enum NodeType : unsigend {

add " SWAP_CSR " behid " ADDII " ,

in " RISCVISelLowering.cpp " of " RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN " add

  case Intrinsic::riscv_addii:
    return DAG.getNode(RISCVISD::ADDII,DL,XlenVT,Op.getOperand(1),Op.getOperand(2),Op.getOperand(3));

in " *RISCVTargetLowering::getTargetNodeName " add


in " " add

def SDT_RISCVADDII : SDTypeProfile<1,3,[SDTCisInt<0>,SDTCisInt<1>,SDTCisInt<2>,SDTCisInt<3>]>;

def  riscv_addii : SDNode<"RISCVISD::ADDII", SDT_RISCVADDII,[SDNPHasChain]>;

def ADDII : RVInstRI<0b0, 0b001, OPC_HX_ADDII, (outs GPR:$rd), 
  (ins GPR:$rs1, GPR:$rs2, uimm5:$dat1), 
  "addii", "$rd, $rs1, $rs2, $dat1">,[ADD (ADD GPR: $rs1 ,$rs2) ,imm12:$dat1] Sched<[]> {
    bits<5> dat1; 
    bits<5> rs2; 
    bits<5> rs1; 
    bits<5> rd; 
    let Inst{30} = 0b0; 
    let Inst{29-25} = dat1; 
    let Inst{24-20} = rs2; 
    let Inst{19-15} = rs1; 
    let Inst{14-12} = 0b001; 
    let Inst{11-7} = rd; 
    let Opcode = OPC_HX_ADDI.Value;
def : Pat<(sext_inreg(add (add GPR:$rs1,GPR:$rs2),uimm5:$uimm5 ),i32),
      (ADDII GPR:$rs1, GPR:$rs2, uimm5:$uimm5)>;

but it says

  fatal error : Cannot  select: 0x561e1c7a11a8 : i32 = RISCVISD::ADDII Constant:i32<2> ,Constant:i32<3>,TargetConstant:i32<3>

Can you tell me why ?

RISCVISD::ADDII Constant:i32<2> ,Constant:i32<3>,TargetConstant:i32<3>

Here you’re passing i32 constants to the node, but it accepts GPR here.TableGen definitions can’t help you to move constant into register.

May you tell me where should I change ?

I’m not familiar with RISC-V, but instruction to add two immediate numbers is strange, especially in compiler, because the compiler can fold them into the constant result.

If you’re pretty sure the instruction you added is legal, you should change the operands type (ins ...) from GPR to uimm5.

Thank you for your reply, I am a newer to llvm ,I use it like this

extern  my_addii( int,  int, const  int  ) ;

int main(void)
	volatile int  test_data1=1, test_data2=2, test_data3=3, test_data4=4;

	test_data4 = my_addii(test_data1,test_data2, 3) ;

and hope to compile the code like this

addii   reg1,  reg2 ,   imm

When I use the function , it says

fatal error: error in backend: Cannot select: 0x56278f802898: i32 = RISCVISD::ADDII 0x56278f802420, 0x56278f802488, TargetConstantFP:i32<APFloat(604453686435277732577280)>
  0x56278f802420: i32,ch = load<(volatile dereferenceable load (s32) from %ir.1)> 0x56278f8023b8:1, FrameIndex:i32<0>, undef:i32
    0x56278f801ed8: i32 = FrameIndex<0>
    0x56278f801fa8: i32 = undef
  0x56278f802488: i32,ch = load<(volatile dereferenceable load (s32) from %ir.2)> 0x56278f802420:1, FrameIndex:i32<1>, undef:i32
    0x56278f8020e0: i32 = FrameIndex<1>
    0x56278f801fa8: i32 = undef
  0x56278f8025c0: i32 = TargetConstantFP<APFloat(604453686435277732577280)>
In function: main
clang-13: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 13.0.0 ( f0bdb5eab7f97d3de17d093418f627cc5ce5fe82)
Target: riscv32-unknown-unknown-elf
Thread model: posix
InstalledDir: /home/llvm/Desktop/llvm_13/llvm-project/install/bin/.
clang-13: note: diagnostic msg: 

Preprocessed source(s) and associated run script(s) are located at:
clang-13: note: diagnostic msg: /tmp/main-4a2170.c
clang-13: note: diagnostic msg: /tmp/
clang-13: note: diagnostic msg: 

May you tell me ,what should I do ?