Skip to content

Commit fc6d517

Browse files
committed
[RISCV][CodeGen] Add codegen pattern for experimental zfa extension (FLI and FCVTMOD not included)
1 parent 5e81537 commit fc6d517

File tree

5 files changed

+676
-9
lines changed

5 files changed

+676
-9
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

+59-9
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
353353
if (Subtarget.hasStdExtZfhOrZfhmin()) {
354354
if (Subtarget.hasStdExtZfh()) {
355355
setOperationAction(FPLegalNodeTypes, MVT::f16, Legal);
356-
setOperationAction(FPRndMode, MVT::f16, Custom);
356+
setOperationAction(FPRndMode, MVT::f16,
357+
Subtarget.hasStdExtZfa() ? Legal : Custom);
357358
setOperationAction(ISD::SELECT, MVT::f16, Custom);
358359
} else {
359360
static const unsigned ZfhminPromoteOps[] = {
@@ -382,7 +383,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
382383
setOperationAction(ISD::SELECT_CC, MVT::f16, Expand);
383384
setOperationAction(ISD::BR_CC, MVT::f16, Expand);
384385

385-
setOperationAction({ISD::FREM, ISD::FNEARBYINT, ISD::FPOW, ISD::FPOWI,
386+
setOperationAction(ISD::FNEARBYINT, MVT::f16,
387+
Subtarget.hasStdExtZfa() ? Legal : Promote);
388+
setOperationAction({ISD::FREM, ISD::FPOW, ISD::FPOWI,
386389
ISD::FCOS, ISD::FSIN, ISD::FSINCOS, ISD::FEXP,
387390
ISD::FEXP2, ISD::FLOG, ISD::FLOG2, ISD::FLOG10},
388391
MVT::f16, Promote);
@@ -402,24 +405,36 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
402405

403406
if (Subtarget.hasStdExtF()) {
404407
setOperationAction(FPLegalNodeTypes, MVT::f32, Legal);
405-
setOperationAction(FPRndMode, MVT::f32, Custom);
408+
setOperationAction(FPRndMode, MVT::f32,
409+
Subtarget.hasStdExtZfa() ? Legal : Custom);
406410
setCondCodeAction(FPCCToExpand, MVT::f32, Expand);
407411
setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
408412
setOperationAction(ISD::SELECT, MVT::f32, Custom);
409413
setOperationAction(ISD::BR_CC, MVT::f32, Expand);
410414
setOperationAction(FPOpToExpand, MVT::f32, Expand);
411415
setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
412416
setTruncStoreAction(MVT::f32, MVT::f16, Expand);
417+
418+
if (Subtarget.hasStdExtZfa())
419+
setOperationAction(ISD::FNEARBYINT, MVT::f32, Legal);
413420
}
414421

415422
if (Subtarget.hasStdExtF() && Subtarget.is64Bit())
416423
setOperationAction(ISD::BITCAST, MVT::i32, Custom);
417424

418425
if (Subtarget.hasStdExtD()) {
419426
setOperationAction(FPLegalNodeTypes, MVT::f64, Legal);
420-
if (Subtarget.is64Bit()) {
421-
setOperationAction(FPRndMode, MVT::f64, Custom);
427+
if (Subtarget.hasStdExtZfa()) {
428+
setOperationAction(FPRndMode, MVT::f64, Legal);
429+
setOperationAction(ISD::FNEARBYINT, MVT::f64, Legal);
430+
setOperationAction(ISD::BITCAST, MVT::i64, Custom);
431+
setOperationAction(ISD::BITCAST, MVT::f64, Custom);
422432
}
433+
434+
if (Subtarget.is64Bit())
435+
setOperationAction(FPRndMode, MVT::f64,
436+
Subtarget.hasStdExtZfa() ? Legal : Custom);
437+
423438
setOperationAction(ISD::STRICT_FP_ROUND, MVT::f32, Legal);
424439
setOperationAction(ISD::STRICT_FP_EXTEND, MVT::f64, Legal);
425440
setCondCodeAction(FPCCToExpand, MVT::f64, Expand);
@@ -3812,6 +3827,16 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
38123827
DAG.getNode(RISCVISD::FMV_W_X_RV64, DL, MVT::f32, NewOp0);
38133828
return FPConv;
38143829
}
3830+
if (VT == MVT::f64 && Op0VT == MVT::i64 && XLenVT == MVT::i32 &&
3831+
Subtarget.hasStdExtZfa()) {
3832+
SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op0,
3833+
DAG.getConstant(0, DL, MVT::i32));
3834+
SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op0,
3835+
DAG.getConstant(1, DL, MVT::i32));
3836+
SDValue RetReg =
3837+
DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
3838+
return RetReg;
3839+
}
38153840

38163841
// Consider other scalar<->scalar casts as legal if the types are legal.
38173842
// Otherwise expand them.
@@ -8020,6 +8045,14 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
80208045
SDValue FPConv =
80218046
DAG.getNode(RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64, Op0);
80228047
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, FPConv));
8048+
} else if (VT == MVT::i64 && Op0VT == MVT::f64 && XLenVT == MVT::i32 &&
8049+
Subtarget.hasStdExtZfa()) {
8050+
SDValue NewReg = DAG.getNode(RISCVISD::SplitF64, DL,
8051+
DAG.getVTList(MVT::i32, MVT::i32), Op0);
8052+
SDValue Lo = NewReg.getValue(0);
8053+
SDValue Hi = NewReg.getValue(1);
8054+
SDValue RetReg = DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
8055+
Results.push_back(RetReg);
80238056
} else if (!VT.isVector() && Op0VT.isFixedLengthVector() &&
80248057
isTypeLegal(Op0VT)) {
80258058
// Custom-legalize bitcasts from fixed-length vector types to illegal
@@ -11124,7 +11157,8 @@ static MachineBasicBlock *emitReadCycleWidePseudo(MachineInstr &MI,
1112411157
}
1112511158

1112611159
static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
11127-
MachineBasicBlock *BB) {
11160+
MachineBasicBlock *BB,
11161+
const RISCVSubtarget &Subtarget) {
1112811162
assert(MI.getOpcode() == RISCV::SplitF64Pseudo && "Unexpected instruction");
1112911163

1113011164
MachineFunction &MF = *BB->getParent();
@@ -11134,6 +11168,13 @@ static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
1113411168
Register LoReg = MI.getOperand(0).getReg();
1113511169
Register HiReg = MI.getOperand(1).getReg();
1113611170
Register SrcReg = MI.getOperand(2).getReg();
11171+
if (Subtarget.hasStdExtD() && Subtarget.hasStdExtZfa() && !Subtarget.is64Bit()) {
11172+
BuildMI(*BB, MI, DL, TII.get(RISCV::FMV_X_W_FPR64), LoReg).addReg(SrcReg);
11173+
BuildMI(*BB, MI, DL, TII.get(RISCV::FMVH_X_D), HiReg).addReg(SrcReg);
11174+
MI.eraseFromParent(); // The pseudo instruction is gone now.
11175+
return BB;
11176+
}
11177+
1113711178
const TargetRegisterClass *SrcRC = &RISCV::FPR64RegClass;
1113811179
int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF);
1113911180

@@ -11157,7 +11198,8 @@ static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
1115711198
}
1115811199

1115911200
static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
11160-
MachineBasicBlock *BB) {
11201+
MachineBasicBlock *BB,
11202+
const RISCVSubtarget &Subtarget) {
1116111203
assert(MI.getOpcode() == RISCV::BuildPairF64Pseudo &&
1116211204
"Unexpected instruction");
1116311205

@@ -11168,6 +11210,14 @@ static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
1116811210
Register DstReg = MI.getOperand(0).getReg();
1116911211
Register LoReg = MI.getOperand(1).getReg();
1117011212
Register HiReg = MI.getOperand(2).getReg();
11213+
if (Subtarget.hasStdExtD() && Subtarget.hasStdExtZfa() && !Subtarget.is64Bit()) {
11214+
BuildMI(*BB, MI, DL, TII.get(RISCV::FMVP_D_X), DstReg)
11215+
.addReg(LoReg)
11216+
.addReg(HiReg);
11217+
MI.eraseFromParent();
11218+
return BB;
11219+
}
11220+
1117111221
const TargetRegisterClass *DstRC = &RISCV::FPR64RegClass;
1117211222
int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex(MF);
1117311223

@@ -11683,9 +11733,9 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1168311733
case RISCV::Select_FPR64_Using_CC_GPR:
1168411734
return emitSelectPseudo(MI, BB, Subtarget);
1168511735
case RISCV::BuildPairF64Pseudo:
11686-
return emitBuildPairF64Pseudo(MI, BB);
11736+
return emitBuildPairF64Pseudo(MI, BB, Subtarget);
1168711737
case RISCV::SplitF64Pseudo:
11688-
return emitSplitF64Pseudo(MI, BB);
11738+
return emitSplitF64Pseudo(MI, BB, Subtarget);
1168911739
case RISCV::PseudoQuietFLE_H:
1169011740
return emitQuietFCMP(MI, BB, RISCV::FLE_H, RISCV::FEQ_H, Subtarget);
1169111741
case RISCV::PseudoQuietFLT_H:

llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td

+77
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ def FMVH_X_D : FPUnaryOp_r<0b1110001, 0b00001, 0b000, GPR, FPR64, "fmvh.x.d">,
8585
Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]>;
8686
def FMVP_D_X : FPBinaryOp_rr<0b1011001, 0b000, FPR64, GPR, "fmvp.d.x">,
8787
Sched<[WriteFMovI32ToF32, ReadFMovI32ToF32]>;
88+
let isCodeGenOnly = 1, mayRaiseFPException = 0 in {
89+
def FMV_X_W_FPR64 : FPUnaryOp_r<0b1110000, 0b00000, 0b000, GPR, FPR64, "fmv.x.w">,
90+
Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]>;
91+
}
8892
} // Predicates = [HasStdExtZfa, HasStdExtD, IsRV32]
8993

9094
let Predicates = [HasStdExtZfa, HasStdExtZfh] in {
@@ -97,3 +101,76 @@ def FROUNDNX_H : FPUnaryOp_r_frm<0b0100010, 0b00101, FPR16, FPR16, "froundnx.h">
97101
def FLTQ_H : FPCmp_rr<0b1010010, 0b101, "fltq.h", FPR16, /*Commutable*/ 1>;
98102
def FLEQ_H : FPCmp_rr<0b1010010, 0b100, "fleq.h", FPR16, /*Commutable*/ 1>;
99103
} // Predicates = [HasStdExtZfa, HasStdExtZfh]
104+
105+
106+
//===----------------------------------------------------------------------===//
107+
// Codegen patterns
108+
//===----------------------------------------------------------------------===//
109+
110+
let Predicates = [HasStdExtZfa] in {
111+
def: PatFprFpr<fminimum, FMINM_S, FPR32>;
112+
def: PatFprFpr<fmaximum, FMAXM_S, FPR32>;
113+
114+
// frint rounds according to the current rounding mode and detects
115+
// inexact conditions.
116+
def: Pat<(any_frint FPR32 : $rs1), (FROUNDNX_S FPR32 : $rs1, 0b111)>;
117+
118+
// fnearbyint is like frint but does not detect inexact conditions.
119+
def: Pat<(any_fnearbyint FPR32 : $rs1), (FROUND_S FPR32 : $rs1, 0b111)>;
120+
121+
def: Pat<(any_fround FPR32 : $rs1), (FROUND_S FPR32 : $rs1, 0b100)>;
122+
def: Pat<(any_ffloor FPR32 : $rs1), (FROUND_S FPR32 : $rs1, 0b011)>;
123+
def: Pat<(any_fceil FPR32 : $rs1), (FROUND_S FPR32 : $rs1, 0b010)>;
124+
def: Pat<(any_ftrunc FPR32 : $rs1), (FROUND_S FPR32 : $rs1, 0b001)>;
125+
126+
def: PatSetCC<FPR32, strict_fsetcc, SETLT, FLTQ_S>;
127+
def: PatSetCC<FPR32, strict_fsetcc, SETOLT, FLTQ_S>;
128+
def: PatSetCC<FPR32, strict_fsetcc, SETLE, FLEQ_S>;
129+
def: PatSetCC<FPR32, strict_fsetcc, SETOLE, FLEQ_S>;
130+
} // Predicates = [HasStdExtZfa]
131+
132+
let Predicates = [HasStdExtZfa, HasStdExtD] in {
133+
def: PatFprFpr<fminimum, FMINM_D, FPR64>;
134+
def: PatFprFpr<fmaximum, FMAXM_D, FPR64>;
135+
136+
// frint rounds according to the current rounding mode and detects
137+
// inexact conditions.
138+
def: Pat<(any_frint FPR64 : $rs1), (FROUNDNX_D FPR64 : $rs1, 0b111)>;
139+
140+
// fnearbyint is like frint but does not detect inexact conditions.
141+
def: Pat<(any_fnearbyint FPR64 : $rs1), (FROUND_D FPR64 : $rs1, 0b111)>;
142+
143+
def: Pat<(any_fround FPR64 : $rs1), (FROUND_D FPR64 : $rs1, 0b100)>;
144+
def: Pat<(any_froundeven FPR64 : $rs1), (FROUND_D FPR64 : $rs1, 0b000)>;
145+
def: Pat<(any_ffloor FPR64 : $rs1), (FROUND_D FPR64 : $rs1, 0b011)>;
146+
def: Pat<(any_fceil FPR64 : $rs1), (FROUND_D FPR64 : $rs1, 0b010)>;
147+
def: Pat<(any_ftrunc FPR64 : $rs1), (FROUND_D FPR64 : $rs1, 0b001)>;
148+
149+
def: PatSetCC<FPR64, strict_fsetcc, SETLT, FLTQ_D>;
150+
def: PatSetCC<FPR64, strict_fsetcc, SETOLT, FLTQ_D>;
151+
def: PatSetCC<FPR64, strict_fsetcc, SETLE, FLEQ_D>;
152+
def: PatSetCC<FPR64, strict_fsetcc, SETOLE, FLEQ_D>;
153+
} // Predicates = [HasStdExtZfa, HasStdExtD]
154+
155+
let Predicates = [HasStdExtZfa, HasStdExtZfh] in {
156+
def: PatFprFpr<fminimum, FMINM_H, FPR16>;
157+
def: PatFprFpr<fmaximum, FMAXM_H, FPR16>;
158+
159+
// frint rounds according to the current rounding mode and detects
160+
// inexact conditions.
161+
def: Pat<(any_frint FPR16 : $rs1), (FROUNDNX_H FPR16 : $rs1, 0b111)>;
162+
163+
// fnearbyint is like frint but does not detect inexact conditions.
164+
def: Pat<(any_fnearbyint FPR16 : $rs1), (FROUND_H FPR16 : $rs1, 0b111)>;
165+
166+
def: Pat<(any_fround FPR16 : $rs1), (FROUND_H FPR16 : $rs1, 0b100)>;
167+
def: Pat<(any_froundeven FPR16 : $rs1), (FROUND_H FPR16 : $rs1, 0b000)>;
168+
def: Pat<(any_ffloor FPR16 : $rs1), (FROUND_H FPR16 : $rs1, 0b011)>;
169+
def: Pat<(any_fceil FPR16 : $rs1), (FROUND_H FPR16 : $rs1, 0b010)>;
170+
def: Pat<(any_ftrunc FPR16 : $rs1), (FROUND_H FPR16 : $rs1, 0b001)>;
171+
172+
def: PatSetCC<FPR16, strict_fsetcc, SETLT, FLTQ_H>;
173+
def: PatSetCC<FPR16, strict_fsetcc, SETOLT, FLTQ_H>;
174+
def: PatSetCC<FPR16, strict_fsetcc, SETLE, FLEQ_H>;
175+
def: PatSetCC<FPR16, strict_fsetcc, SETOLE, FLEQ_H>;
176+
} // Predicates = [HasStdExtZfa, HasStdExtZfh]

0 commit comments

Comments
 (0)