Skip to content

Commit 1a54a3a

Browse files
chenqianAlexey Gerenkov
authored andcommitted
[RISCV][ESP32P4][ESPV] Add p4 espv 2.1 intrinsic left support
1 parent ed1318f commit 1a54a3a

46 files changed

Lines changed: 5528 additions & 1951 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

clang/include/clang/Basic/BuiltinsRISCVESPVM.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,14 @@ let Features = "xespv", Attributes = [NoThrow, RequiredVectorWidth<128>] in
14161416
// defined in BuiltinsRISCVESP32P4.td, so we don't redefine them here.
14171417
}
14181418

1419+
// GPR ALU (.m): SSA result = op(rs1, rs2); lowers to esp.{addx2,addx4,subx2,subx4}.
1420+
let Features = "xespv", Attributes = [NoThrow] in {
1421+
def esp_addx2_m : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">;
1422+
def esp_addx4_m : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">;
1423+
def esp_subx2_m : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">;
1424+
def esp_subx4_m : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">;
1425+
}
1426+
14191427
// MOVX - Read/Write implicit registers (_m version)
14201428
// These are scalar instructions, so they don't need RequiredVectorWidth<128>
14211429
let Features = "xespv", Attributes = [NoThrow] in {

clang/test/CodeGen/RISCV/esp32p4-intrinsics/riscv-esp32p4-vector-max-min.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,52 @@ void test_vmin_u8(void *src1, void *src2, void *dst) {
9393
esp_vst_128_ip_m(min_val, dst, 16);
9494
}
9595

96+
// GPR ALU (.m): Builtin -> Intrinsic (@llvm.riscv.esp.*.m)
97+
unsigned int __builtin_riscv_esp_addx2_m(unsigned int, unsigned int);
98+
unsigned int __builtin_riscv_esp_addx4_m(unsigned int, unsigned int);
99+
unsigned int __builtin_riscv_esp_subx2_m(unsigned int, unsigned int);
100+
unsigned int __builtin_riscv_esp_subx4_m(unsigned int, unsigned int);
101+
102+
// CHECK-LABEL: define dso_local i32 @test_gpr_addx2_m(
103+
// CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
104+
// CHECK-NEXT: [[ENTRY:.*:]]
105+
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.riscv.esp.addx2.m(i32 [[A]], i32 [[B]])
106+
// CHECK-NEXT: ret i32 [[TMP0]]
107+
//
108+
unsigned test_gpr_addx2_m(unsigned a, unsigned b) {
109+
return __builtin_riscv_esp_addx2_m(a, b);
110+
}
111+
112+
// CHECK-LABEL: define dso_local i32 @test_gpr_addx4_m(
113+
// CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR2]] {
114+
// CHECK-NEXT: [[ENTRY:.*:]]
115+
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.riscv.esp.addx4.m(i32 [[A]], i32 [[B]])
116+
// CHECK-NEXT: ret i32 [[TMP0]]
117+
//
118+
unsigned test_gpr_addx4_m(unsigned a, unsigned b) {
119+
return __builtin_riscv_esp_addx4_m(a, b);
120+
}
121+
122+
// CHECK-LABEL: define dso_local i32 @test_gpr_subx2_m(
123+
// CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR2]] {
124+
// CHECK-NEXT: [[ENTRY:.*:]]
125+
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.riscv.esp.subx2.m(i32 [[A]], i32 [[B]])
126+
// CHECK-NEXT: ret i32 [[TMP0]]
127+
//
128+
unsigned test_gpr_subx2_m(unsigned a, unsigned b) {
129+
return __builtin_riscv_esp_subx2_m(a, b);
130+
}
131+
132+
// CHECK-LABEL: define dso_local i32 @test_gpr_subx4_m(
133+
// CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) local_unnamed_addr #[[ATTR2]] {
134+
// CHECK-NEXT: [[ENTRY:.*:]]
135+
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.riscv.esp.subx4.m(i32 [[A]], i32 [[B]])
136+
// CHECK-NEXT: ret i32 [[TMP0]]
137+
//
138+
unsigned test_gpr_subx4_m(unsigned a, unsigned b) {
139+
return __builtin_riscv_esp_subx4_m(a, b);
140+
}
141+
96142
// Vector absolute value (8-bit)
97143
//
98144

llvm/include/llvm/IR/IntrinsicsRISCVESPVM.td

Lines changed: 246 additions & 2 deletions
Large diffs are not rendered by default.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5534,6 +5534,20 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
55345534

55355535
// Create the node.
55365536
SDValue Result;
5537+
// Void intrinsics with IntrNoMem make F->doesNotAccessMemory() true, so
5538+
// HasChain is false. INTRINSIC_WO_CHAIN requires a non-empty VT list (at
5539+
// least one result); use INTRINSIC_VOID with an explicit chain operand.
5540+
bool ChainForRoot = HasChain;
5541+
5542+
if (auto Bundle = I.getOperandBundle(LLVMContext::OB_convergencectrl)) {
5543+
auto *Token = Bundle->Inputs[0].get();
5544+
SDValue ConvControlToken = getValue(Token);
5545+
assert(Ops.back().getValueType() != MVT::Glue &&
5546+
"Did not expected another glue node here.");
5547+
ConvControlToken =
5548+
DAG.getNode(ISD::CONVERGENCECTRL_GLUE, {}, MVT::Glue, ConvControlToken);
5549+
Ops.push_back(ConvControlToken);
5550+
}
55375551

55385552
// In some cases, custom collection of operands from CallInst I may be needed.
55395553
TLI.CollectTargetIntrinsicOperands(I, Ops, DAG);
@@ -5563,8 +5577,27 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I,
55635577

55645578
Result = DAG.getMemIntrinsicNode(Info->opc, getCurSDLoc(), VTs, Ops,
55655579
Info->memVT, MMOs);
5580+
} else if (!HasChain && I.getType()->isVoidTy()) {
5581+
SmallVector<SDValue, 8> VoidOps;
5582+
VoidOps.push_back(getRoot());
5583+
VoidOps.append(Ops.begin(), Ops.end());
5584+
SDVTList VoidVTs = DAG.getVTList(MVT::Other);
5585+
Result = DAG.getNode(ISD::INTRINSIC_VOID, getCurSDLoc(), VoidVTs, VoidOps);
5586+
ChainForRoot = true;
5587+
} else if (!HasChain) {
5588+
Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, getCurSDLoc(), VTs, Ops);
5589+
} else if (!I.getType()->isVoidTy()) {
5590+
Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, getCurSDLoc(), VTs, Ops);
55665591
} else {
5567-
Result = getTargetNonMemIntrinsicNode(*I.getType(), HasChain, Ops, VTs);
5592+
Result = DAG.getNode(ISD::INTRINSIC_VOID, getCurSDLoc(), VTs, Ops);
5593+
}
5594+
5595+
if (ChainForRoot) {
5596+
SDValue Chain = Result.getValue(Result.getNode()->getNumValues() - 1);
5597+
if (OnlyLoad)
5598+
PendingLoads.push_back(Chain);
5599+
else
5600+
DAG.setRoot(Chain);
55685601
}
55695602

55705603
Result = handleTargetIntrinsicRet(I, HasChain, OnlyLoad, Result);

llvm/lib/Target/RISCV/RISCVESPISelLowering.cpp

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -5101,81 +5101,6 @@ MachineBasicBlock *RISCVTargetLowering::emitDSPInstrWithCustomInserter(
51015101
MI.eraseFromParent();
51025102
return MBB;
51035103
}
5104-
case RISCV::ESP_ADDX2_P: {
5105-
unsigned Opc = RISCV::ESP_ADDX2;
5106-
MachineBasicBlock *MBB = MI.getParent();
5107-
MachineOperand &RS1 = MI.getOperand(0);
5108-
MachineOperand &RS2 = MI.getOperand(1);
5109-
const TargetRegisterClass *RC = &RISCV::GPRPIERegClass;
5110-
unsigned R1 = MRI.createVirtualRegister(RC);
5111-
BuildMI(*MBB, MI, DL, TII.get(Opc))
5112-
.addReg(R1, RegState::Define)
5113-
.addReg(RS1.getReg())
5114-
.addReg(RS2.getReg());
5115-
5116-
MI.eraseFromParent();
5117-
return MBB;
5118-
}
5119-
case RISCV::ESP_ADDX4_P: {
5120-
unsigned Opc = RISCV::ESP_ADDX4;
5121-
MachineBasicBlock *MBB = MI.getParent();
5122-
MachineOperand &RS1 = MI.getOperand(0);
5123-
MachineOperand &RS2 = MI.getOperand(1);
5124-
const TargetRegisterClass *RC = &RISCV::GPRPIERegClass;
5125-
unsigned R1 = MRI.createVirtualRegister(RC);
5126-
BuildMI(*MBB, MI, DL, TII.get(Opc))
5127-
.addReg(R1, RegState::Define)
5128-
.addReg(RS1.getReg())
5129-
.addReg(RS2.getReg());
5130-
5131-
MI.eraseFromParent();
5132-
return MBB;
5133-
}
5134-
case RISCV::ESP_SAT_P: {
5135-
unsigned Opc = RISCV::ESP_SAT;
5136-
MachineBasicBlock *MBB = MI.getParent();
5137-
MachineOperand &RS0 = MI.getOperand(1);
5138-
MachineOperand &RS1 = MI.getOperand(2);
5139-
MachineOperand &RSD = MI.getOperand(3);
5140-
BuildMI(*MBB, MI, DL, TII.get(Opc))
5141-
.addReg(MI.getOperand(0).getReg(), RegState::Define)
5142-
.addReg(RS0.getReg())
5143-
.addReg(RS1.getReg())
5144-
.addReg(RSD.getReg());
5145-
5146-
MI.eraseFromParent();
5147-
return MBB;
5148-
}
5149-
case RISCV::ESP_SUBX2_P: {
5150-
unsigned Opc = RISCV::ESP_SUBX2;
5151-
MachineBasicBlock *MBB = MI.getParent();
5152-
MachineOperand &RS1 = MI.getOperand(0);
5153-
MachineOperand &RS2 = MI.getOperand(1);
5154-
const TargetRegisterClass *RC = &RISCV::GPRPIERegClass;
5155-
unsigned R1 = MRI.createVirtualRegister(RC);
5156-
BuildMI(*MBB, MI, DL, TII.get(Opc))
5157-
.addReg(R1, RegState::Define)
5158-
.addReg(RS1.getReg())
5159-
.addReg(RS2.getReg());
5160-
5161-
MI.eraseFromParent();
5162-
return MBB;
5163-
}
5164-
case RISCV::ESP_SUBX4_P: {
5165-
unsigned Opc = RISCV::ESP_SUBX4;
5166-
MachineBasicBlock *MBB = MI.getParent();
5167-
MachineOperand &RS1 = MI.getOperand(0);
5168-
MachineOperand &RS2 = MI.getOperand(1);
5169-
const TargetRegisterClass *RC = &RISCV::GPRPIERegClass;
5170-
unsigned R1 = MRI.createVirtualRegister(RC);
5171-
BuildMI(*MBB, MI, DL, TII.get(Opc))
5172-
.addReg(R1, RegState::Define)
5173-
.addReg(RS1.getReg())
5174-
.addReg(RS2.getReg());
5175-
5176-
MI.eraseFromParent();
5177-
return MBB;
5178-
}
51795104
case RISCV::ESP_ANDQ_P: {
51805105
unsigned Opc = RISCV::ESP_ANDQ;
51815106
MachineBasicBlock *MBB = MI.getParent();

0 commit comments

Comments
 (0)