When adding intrinsic in riscv,the command line option -target-feature fails to set the corresponding feature of subtarget to true, resulting in an error, so how to enable the feature correctly?

descreption:

Following ⚙ D99158 [RISCV] Implement intrinsics for P extension, I want to add an instruction in the P-like extension to riscv, but I have been stuck on failing to enable the corresponding feature

error:

./ztest.c:14:21: error: builtin requires at least one of the following extensions to be enabled: 'Zpn'
   14 |          unsigned int d =  __rv_add16(a, b);
      |                            ^~~~~~~~~~~~~~~~
1 error generated.

The version of llvm : 17.0

test program:

int main () {
	unsigned int a = 10;
	unsigned int b = 10;
	
	 unsigned int d =  __rv_add16(a, b);
	return 0;
}

The command to run:

../clang -cc1 -triple riscv32 -O2 -target-feature +experimental-zpn -emit-llvm ./ztest.c -o test.ll

The modifications I made are as follows:

llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def

TARGET_BUILTIN(__rv_add16, "ULiULiULi", "nc", "experimental-zpn")

llvm-project/llvm/include/llvm/IR/IntrinsicsRISCV.td

let TargetPrefix = "riscv" in {
	class RVPBinaryIntrinsics
		  : Intrinsic<[llvm_any_ty],
					  [LLVMMatchType<0>, LLVMMatchType<0>],
					  [IntrNoMem]>;

	multiclass RVPBinaryIntrinsics {
		def "int_riscv_" # NAME : RVPBinaryIntrinsics;
	}

	defm add8     : RVPBinaryIntrinsics;
	defm add16    : RVPBinaryIntrinsics;
  defm kaddw    : RVPBinaryIntrinsics;
  defm ksubw    : RVPBinaryIntrinsics;
} 

llvm-project/clang/lib/CodeGen/CGBuiltin.cpp

#define BUILTIN_ID(NAME)            \
 case RISCV::BI__rv_##NAME:         \
    ID = Intrinsic::riscv_##NAME;   \
    break;
// Intrinsic type is obtained from Ops[0].
  case RISCV::BI__rv_add8:
  case RISCV::BI__rv_add16:
  case RISCV::BI__rv_ksubw:
  case RISCV::BI__rv_kaddw: {
    switch (BuiltinID) {
      default : llvm_unreachable("unexpected builtin ID");
      BUILTIN_ID(add8)
      BUILTIN_ID(add16)
      BUILTIN_ID(kaddw)
      BUILTIN_ID(ksubw)
    }
#undef BUILTIN_ID
    IntrinsicTypes = {Ops[0]->getType()};
    break;
  }

llvm-project/llvm/lib/Target/RISCV/RISCVFeatures.td

def FeatureStdExtZpn
    : SubtargetFeature<"experimental-zpn", "HasStdExtZpn", "true",
                       "'Zpn' (Normal 'P' Instructions)">;
def HasStdExtZpn : Predicate<"Subtarget->hasStdExtZpn()">,
                             AssemblerPredicate<(all_of FeatureStdExtZpn),
                         "'Zpn' (Normal 'P' Instructions)">;

llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoP.td


//insturction def
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class RVPBinary<bits<7> funct7, bits<3> funct3, string opcodestr,
                DAGOperand rd_kind = GPR, DAGOperand rs1_kind = GPR,
                DAGOperand rs2_kind = GPR>
    : RVInstR<funct7, funct3, OPC_OP_P,
              (outs rd_kind:$rd), (ins rs1_kind:$rs1, rs2_kind:$rs2),
              opcodestr, "$rd, $rs1, $rs2">;

let Predicates = [HasStdExtZpn] in {
def ADD8     : RVPBinary<0b0100100, 0b000, "add8">,
               Sched<[]>;
def ADD16    : RVPBinary<0b0100000, 0b000, "add16">,
               Sched<[]>;
def KADDW    : RVPBinary<0b0000000, 0b001, "kaddw">,
               Sched<[]>;
def KSUBW    : RVPBinary<0b0000001, 0b001, "ksubw">,
               Sched<[]>;
}// Predicates = [HasStdExtZpn]



// match pattern 
class RVPBinaryIntPat<RVInst Inst, string IntID>
    : Pat<(XLenVT (!cast<Intrinsic>("int_riscv_" # IntID)
                   XLenVT:$rs1, XLenVT:$rs2)),
          (Inst GPR:$rs1, GPR:$rs2)>;

let Predicates = [HasStdExtZpn] in {
    def : RVPBinaryIntPat<ADD8,     "add8">;
    def : RVPBinaryIntPat<ADD16,    "add16">;
    def : RVPBinaryIntPat<KADDW,     "kaddw">;
    def : RVPBinaryIntPat<KSUBW,     "ksubw">;
}

OK,I solved it myself
RISCVISAInfo.cpp, Some content needs to be added, and there are some restrictions on the feature in the target-feature in the command line

You should post the specifics so others who hit the same error as you know what they got wrong.

The reason for the above error(When there is no problem with your def file, intrinsic, and feature definitions)

  • I think if you want to add custom features, especially with strange names, it is very likely that you need to modify part of the source code in ISAInfo
  • Please read the code in RISCVISAInfo.cpp carefully
  • my solution : add legal features name in SupportedExtensions vector, so,I changed the name of the feature to ztao

def FeatureStdExtZtao
    : SubtargetFeature<"ztao", "HasStdExtZtao", "true",
                       "'Ztao' (Normal 'P' Instructions)">;
def HasStdExtZtao : Predicate<"Subtarget->hasStdExtZtao()">,
                             AssemblerPredicate<(all_of FeatureStdExtZtao),
                         "'Ztao' (Normal 'P' Instructions)">;

ok

thanks! I meet the same problem and it’s very helpful :smiley: