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">;
}