Skip to content

Commit 716b3d5

Browse files
committed
[WIP][RISCV] Merge GPRPair and GPRF64Pair
1 parent 0b98a56 commit 716b3d5

File tree

6 files changed

+92
-63
lines changed

6 files changed

+92
-63
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -497,16 +497,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
497497
RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(Reg.RegNum);
498498
}
499499

500-
bool isGPRF64Pair() const {
501-
return Kind == KindTy::Register &&
502-
RISCVMCRegisterClasses[RISCV::GPRF64PairRegClassID].contains(
503-
Reg.RegNum);
504-
}
505-
506500
bool isGPRAsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }
507501
bool isGPRAsFPR16() const { return isGPRF16() && Reg.IsGPRAsFPR; }
508502
bool isGPRAsFPR32() const { return isGPRF32() && Reg.IsGPRAsFPR; }
509-
bool isGPRPairAsFPR64() const { return isGPRF64Pair() && Reg.IsGPRAsFPR; }
503+
bool isGPRPairAsFPR64() const { return isGPRPair() && Reg.IsGPRAsFPR; }
510504

511505
static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
512506
RISCVMCExpr::VariantKind &VK) {
@@ -2405,7 +2399,7 @@ ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(OperandVector &Operands) {
24052399
const MCRegisterInfo *RI = getContext().getRegisterInfo();
24062400
MCRegister Pair = RI->getMatchingSuperReg(
24072401
Reg, RISCV::sub_gpr_even,
2408-
&RISCVMCRegisterClasses[RISCV::GPRF64PairRegClassID]);
2402+
&RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
24092403
Operands.push_back(RISCVOperand::createReg(Pair, S, E, /*isGPRAsFPR=*/true));
24102404
return ParseStatus::Success;
24112405
}

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -960,20 +960,14 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
960960
assert((!Subtarget->is64Bit() || Opcode == RISCVISD::BuildGPRPair) &&
961961
"BuildPairF64 only handled here on rv32i_zdinx");
962962

963-
int RegClassID = (Opcode == RISCVISD::BuildGPRPair)
964-
? RISCV::GPRPairRegClassID
965-
: RISCV::GPRF64PairRegClassID;
966-
MVT OutType = (Opcode == RISCVISD::BuildGPRPair) ? MVT::Untyped : MVT::f64;
967-
968963
SDValue Ops[] = {
969-
CurDAG->getTargetConstant(RegClassID, DL, MVT::i32),
964+
CurDAG->getTargetConstant(RISCV::GPRPairRegClassID, DL, MVT::i32),
970965
Node->getOperand(0),
971966
CurDAG->getTargetConstant(RISCV::sub_gpr_even, DL, MVT::i32),
972967
Node->getOperand(1),
973968
CurDAG->getTargetConstant(RISCV::sub_gpr_odd, DL, MVT::i32)};
974969

975-
SDNode *N =
976-
CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, OutType, Ops);
970+
SDNode *N = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, VT, Ops);
977971
ReplaceNode(Node, N);
978972
return;
979973
}
@@ -984,13 +978,15 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
984978
"SplitF64 only handled here on rv32i_zdinx");
985979

986980
if (!SDValue(Node, 0).use_empty()) {
987-
SDValue Lo = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_even, DL, VT,
981+
SDValue Lo = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_even, DL,
982+
Node->getSimpleValueType(0),
988983
Node->getOperand(0));
989984
ReplaceUses(SDValue(Node, 0), Lo);
990985
}
991986

992987
if (!SDValue(Node, 1).use_empty()) {
993-
SDValue Hi = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_odd, DL, VT,
988+
SDValue Hi = CurDAG->getTargetExtractSubreg(RISCV::sub_gpr_odd, DL,
989+
Node->getSimpleValueType(1),
994990
Node->getOperand(0));
995991
ReplaceUses(SDValue(Node, 1), Hi);
996992
}

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
133133
if (Subtarget.is64Bit())
134134
addRegisterClass(MVT::f64, &RISCV::GPRRegClass);
135135
else
136-
addRegisterClass(MVT::f64, &RISCV::GPRF64PairRegClass);
136+
addRegisterClass(MVT::f64, &RISCV::GPRPairRegClass);
137137
}
138138

139139
static const MVT::SimpleValueType BoolVecVTs[] = {
@@ -300,6 +300,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
300300
setOperationAction(ISD::VASTART, MVT::Other, Custom);
301301
setOperationAction({ISD::VAARG, ISD::VACOPY, ISD::VAEND}, MVT::Other, Expand);
302302

303+
setOperationAction(ISD::BITCAST, MVT::Untyped, Custom);
304+
303305
if (!Subtarget.hasVendorXTHeadBb())
304306
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
305307

@@ -20499,7 +20501,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2049920501
if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
2050020502
return std::make_pair(0U, &RISCV::GPRF32NoX0RegClass);
2050120503
if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20502-
return std::make_pair(0U, &RISCV::GPRF64PairNoX0RegClass);
20504+
return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
2050320505
return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2050420506
case 'f':
2050520507
if (VT == MVT::f16) {
@@ -20516,7 +20518,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2051620518
if (Subtarget.hasStdExtD())
2051720519
return std::make_pair(0U, &RISCV::FPR64RegClass);
2051820520
if (Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20519-
return std::make_pair(0U, &RISCV::GPRF64PairNoX0RegClass);
20521+
return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
2052020522
if (Subtarget.hasStdExtZdinx() && Subtarget.is64Bit())
2052120523
return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2052220524
}
@@ -20558,7 +20560,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2055820560
if (VT == MVT::f32 && Subtarget.hasStdExtZfinx())
2055920561
return std::make_pair(0U, &RISCV::GPRF32CRegClass);
2056020562
if (VT == MVT::f64 && Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20561-
return std::make_pair(0U, &RISCV::GPRF64PairCRegClass);
20563+
return std::make_pair(0U, &RISCV::GPRPairCRegClass);
2056220564
if (!VT.isVector())
2056320565
return std::make_pair(0U, &RISCV::GPRCRegClass);
2056420566
} else if (Constraint == "cf") {
@@ -20576,13 +20578,13 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2057620578
if (Subtarget.hasStdExtD())
2057720579
return std::make_pair(0U, &RISCV::FPR64CRegClass);
2057820580
if (Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20579-
return std::make_pair(0U, &RISCV::GPRF64PairCRegClass);
20581+
return std::make_pair(0U, &RISCV::GPRPairCRegClass);
2058020582
if (Subtarget.hasStdExtZdinx() && Subtarget.is64Bit())
2058120583
return std::make_pair(0U, &RISCV::GPRCRegClass);
2058220584
}
2058320585
} else if (Constraint == "Pr") {
2058420586
if (VT == MVT::f64 && !Subtarget.is64Bit() && Subtarget.hasStdExtZdinx())
20585-
return std::make_pair(0U, &RISCV::GPRF64PairCRegClass);
20587+
return std::make_pair(0U, &RISCV::GPRPairCRegClass);
2058620588
return std::make_pair(0U, &RISCV::GPRPairNoX0RegClass);
2058720589
}
2058820590

@@ -20744,7 +20746,7 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2074420746
// Subtarget into account.
2074520747
if (Res.second == &RISCV::GPRF16RegClass ||
2074620748
Res.second == &RISCV::GPRF32RegClass ||
20747-
Res.second == &RISCV::GPRF64PairRegClass)
20749+
Res.second == &RISCV::GPRPairRegClass)
2074820750
return std::make_pair(Res.first, &RISCV::GPRRegClass);
2074920751

2075020752
return Res;
@@ -21371,12 +21373,19 @@ bool RISCVTargetLowering::splitValueIntoRegisterParts(
2137121373
bool IsABIRegCopy = CC.has_value();
2137221374
EVT ValueVT = Val.getValueType();
2137321375

21374-
if (ValueVT == (Subtarget.is64Bit() ? MVT::i128 : MVT::i64) &&
21376+
MVT PairVT = Subtarget.is64Bit() ? MVT::i128 : MVT::i64;
21377+
if ((ValueVT == PairVT ||
21378+
(!Subtarget.is64Bit() && Subtarget.hasStdExtZdinx() &&
21379+
ValueVT == MVT::f64)) &&
2137521380
NumParts == 1 && PartVT == MVT::Untyped) {
21376-
// Pairs in Inline Assembly
21381+
// Pairs in Inline Assembly, f64 in Inline assembly on rv32_zdinx
2137721382
MVT XLenVT = Subtarget.getXLenVT();
21383+
if (ValueVT == MVT::f64)
21384+
Val = DAG.getBitcast(MVT::i64, Val);
2137821385
auto [Lo, Hi] = DAG.SplitScalar(Val, DL, XLenVT, XLenVT);
21379-
Parts[0] = DAG.getNode(RISCVISD::BuildGPRPair, DL, MVT::Untyped, Lo, Hi);
21386+
// Always creating something MVT::Untyped, so always using
21387+
// RISCVISD::BuildGPRPair.
21388+
Parts[0] = DAG.getNode(RISCVISD::BuildGPRPair, DL, PartVT, Lo, Hi);
2138021389
return true;
2138121390
}
2138221391

@@ -21388,7 +21397,7 @@ bool RISCVTargetLowering::splitValueIntoRegisterParts(
2138821397
Val = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Val);
2138921398
Val = DAG.getNode(ISD::OR, DL, MVT::i32, Val,
2139021399
DAG.getConstant(0xFFFF0000, DL, MVT::i32));
21391-
Val = DAG.getNode(ISD::BITCAST, DL, MVT::f32, Val);
21400+
Val = DAG.getNode(ISD::BITCAST, DL, PartVT, Val);
2139221401
Parts[0] = Val;
2139321402
return true;
2139421403
}
@@ -21452,14 +21461,24 @@ SDValue RISCVTargetLowering::joinRegisterPartsIntoValue(
2145221461
MVT PartVT, EVT ValueVT, std::optional<CallingConv::ID> CC) const {
2145321462
bool IsABIRegCopy = CC.has_value();
2145421463

21455-
if (ValueVT == (Subtarget.is64Bit() ? MVT::i128 : MVT::i64) &&
21464+
MVT PairVT = Subtarget.is64Bit() ? MVT::i128 : MVT::i64;
21465+
if ((ValueVT == PairVT ||
21466+
(!Subtarget.is64Bit() && Subtarget.hasStdExtZdinx() &&
21467+
ValueVT == MVT::f64)) &&
2145621468
NumParts == 1 && PartVT == MVT::Untyped) {
21457-
// Pairs in Inline Assembly
21469+
// Pairs in Inline Assembly, f64 in Inline assembly on rv32_zdinx
2145821470
MVT XLenVT = Subtarget.getXLenVT();
21459-
SDValue Res = DAG.getNode(RISCVISD::SplitGPRPair, DL,
21460-
DAG.getVTList(XLenVT, XLenVT), Parts[0]);
21461-
return DAG.getNode(ISD::BUILD_PAIR, DL, ValueVT, Res.getValue(0),
21462-
Res.getValue(1));
21471+
21472+
SDValue Val = Parts[0];
21473+
// Always starting with something MVT::Untyped, so always using
21474+
// RISCVISD::SplitGPRPair
21475+
Val = DAG.getNode(RISCVISD::SplitGPRPair, DL, DAG.getVTList(XLenVT, XLenVT),
21476+
Parts[0]);
21477+
Val = DAG.getNode(ISD::BUILD_PAIR, DL, PairVT, Val.getValue(0),
21478+
Val.getValue(1));
21479+
if (ValueVT == MVT::f64)
21480+
Val = DAG.getBitcast(ValueVT, Val);
21481+
return Val;
2146321482
}
2146421483

2146521484
if (IsABIRegCopy && (ValueVT == MVT::f16 || ValueVT == MVT::bf16) &&

llvm/lib/Target/RISCV/RISCVInstrInfoD.td

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def FPR64INX : RegisterOperand<GPR> {
5252
let DecoderMethod = "DecodeGPRRegisterClass";
5353
}
5454

55-
def FPR64IN32X : RegisterOperand<GPRF64Pair> {
55+
def FPR64IN32X : RegisterOperand<GPRPair> {
5656
let ParserMatchClass = GPRPairAsFPR;
5757
}
5858

@@ -457,16 +457,16 @@ def : PatSetCC<FPR64INX, any_fsetccs, SETOLE, FLE_D_INX, f64>;
457457

458458
let Predicates = [HasStdExtZdinx, IsRV32] in {
459459
// Match signaling FEQ_D
460-
def : Pat<(XLenVT (strict_fsetccs FPR64IN32X:$rs1, FPR64IN32X:$rs2, SETEQ)),
460+
def : Pat<(XLenVT (strict_fsetccs (f64 FPR64IN32X:$rs1), FPR64IN32X:$rs2, SETEQ)),
461461
(AND (XLenVT (FLE_D_IN32X $rs1, $rs2)),
462462
(XLenVT (FLE_D_IN32X $rs2, $rs1)))>;
463-
def : Pat<(XLenVT (strict_fsetccs FPR64IN32X:$rs1, FPR64IN32X:$rs2, SETOEQ)),
463+
def : Pat<(XLenVT (strict_fsetccs (f64 FPR64IN32X:$rs1), FPR64IN32X:$rs2, SETOEQ)),
464464
(AND (XLenVT (FLE_D_IN32X $rs1, $rs2)),
465465
(XLenVT (FLE_D_IN32X $rs2, $rs1)))>;
466466
// If both operands are the same, use a single FLE.
467-
def : Pat<(XLenVT (strict_fsetccs FPR64IN32X:$rs1, FPR64IN32X:$rs1, SETEQ)),
467+
def : Pat<(XLenVT (strict_fsetccs (f64 FPR64IN32X:$rs1), FPR64IN32X:$rs1, SETEQ)),
468468
(FLE_D_IN32X $rs1, $rs1)>;
469-
def : Pat<(XLenVT (strict_fsetccs FPR64IN32X:$rs1, FPR64IN32X:$rs1, SETOEQ)),
469+
def : Pat<(XLenVT (strict_fsetccs (f64 FPR64IN32X:$rs1), FPR64IN32X:$rs1, SETOEQ)),
470470
(FLE_D_IN32X $rs1, $rs1)>;
471471

472472
def : PatSetCC<FPR64IN32X, any_fsetccs, SETLT, FLT_D_IN32X, f64>;
@@ -523,15 +523,15 @@ def PseudoFROUND_D_IN32X : PseudoFROUND<FPR64IN32X, f64>;
523523

524524
/// Loads
525525
let isCall = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 1 in
526-
def PseudoRV32ZdinxLD : Pseudo<(outs GPRF64Pair:$dst), (ins GPR:$rs1, simm12:$imm12), []>;
526+
def PseudoRV32ZdinxLD : Pseudo<(outs GPRPair:$dst), (ins GPR:$rs1, simm12:$imm12), []>;
527527
def : Pat<(f64 (load (AddrRegImmINX (XLenVT GPR:$rs1), simm12:$imm12))),
528528
(PseudoRV32ZdinxLD GPR:$rs1, simm12:$imm12)>;
529529

530530
/// Stores
531531
let isCall = 0, mayLoad = 0, mayStore = 1, Size = 8, isCodeGenOnly = 1 in
532-
def PseudoRV32ZdinxSD : Pseudo<(outs), (ins GPRF64Pair:$rs2, GPRNoX0:$rs1, simm12:$imm12), []>;
533-
def : Pat<(store (f64 GPRF64Pair:$rs2), (AddrRegImmINX (XLenVT GPR:$rs1), simm12:$imm12)),
534-
(PseudoRV32ZdinxSD GPRF64Pair:$rs2, GPR:$rs1, simm12:$imm12)>;
532+
def PseudoRV32ZdinxSD : Pseudo<(outs), (ins GPRPair:$rs2, GPRNoX0:$rs1, simm12:$imm12), []>;
533+
def : Pat<(store (f64 GPRPair:$rs2), (AddrRegImmINX (XLenVT GPR:$rs1), simm12:$imm12)),
534+
(PseudoRV32ZdinxSD GPRPair:$rs2, GPR:$rs1, simm12:$imm12)>;
535535
} // Predicates = [HasStdExtZdinx, IsRV32]
536536

537537
let Predicates = [HasStdExtD, IsRV32] in {

llvm/lib/Target/RISCV/RISCVRegisterInfo.td

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ let RegAltNameIndices = [ABIRegAltName] in {
325325

326326
let RegInfos = XLenPairRI,
327327
DecoderMethod = "DecodeGPRPairRegisterClass" in {
328-
def GPRPair : RISCVRegisterClass<[XLenPairVT], 64, (add
328+
def GPRPair : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (add
329329
X10_X11, X12_X13, X14_X15, X16_X17,
330330
X6_X7,
331331
X28_X29, X30_X31,
@@ -334,11 +334,11 @@ def GPRPair : RISCVRegisterClass<[XLenPairVT], 64, (add
334334
X0_Pair, X2_X3, X4_X5
335335
)>;
336336

337-
def GPRPairNoX0 : RISCVRegisterClass<[XLenPairVT], 64, (sub GPRPair, X0_Pair)>;
337+
def GPRPairNoX0 : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (sub GPRPair, X0_Pair)>;
338338
} // let RegInfos = XLenPairRI, DecoderMethod = "DecodeGPRPairRegisterClass"
339339

340340
let RegInfos = XLenPairRI in
341-
def GPRPairC : RISCVRegisterClass<[XLenPairVT], 64, (add
341+
def GPRPairC : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (add
342342
X10_X11, X12_X13, X14_X15, X8_X9
343343
)>;
344344

@@ -464,22 +464,6 @@ def GPRF32C : RISCVRegisterClass<[f32], 32, (add (sequence "X%u_W", 10, 15),
464464
(sequence "X%u_W", 8, 9))>;
465465
def GPRF32NoX0 : RISCVRegisterClass<[f32], 32, (sub GPRF32, X0_W)>;
466466

467-
let DecoderMethod = "DecodeGPRPairRegisterClass" in
468-
def GPRF64Pair : RISCVRegisterClass<[XLenPairFVT], 64, (add
469-
X10_X11, X12_X13, X14_X15, X16_X17,
470-
X6_X7,
471-
X28_X29, X30_X31,
472-
X8_X9,
473-
X18_X19, X20_X21, X22_X23, X24_X25, X26_X27,
474-
X0_Pair, X2_X3, X4_X5
475-
)>;
476-
477-
def GPRF64PairC : RISCVRegisterClass<[XLenPairFVT], 64, (add
478-
X10_X11, X12_X13, X14_X15, X8_X9
479-
)>;
480-
481-
def GPRF64PairNoX0 : RISCVRegisterClass<[XLenPairFVT], 64, (sub GPRF64Pair, X0_Pair)>;
482-
483467
//===----------------------------------------------------------------------===//
484468
// Vector type mapping to LLVM types.
485469
//===----------------------------------------------------------------------===//

llvm/test/CodeGen/RISCV/zdinx-asm-constraint.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,42 @@ entry:
5252
ret void
5353
}
5454

55+
define dso_local void @zdinx_asm_inout(ptr nocapture noundef writeonly %a, double noundef %b) nounwind {
56+
; CHECK-LABEL: zdinx_asm_inout:
57+
; CHECK: # %bb.0: # %entry
58+
; CHECK-NEXT: mv a3, a2
59+
; CHECK-NEXT: mv a2, a1
60+
; CHECK-NEXT: #APP
61+
; CHECK-NEXT: fmv.d a2, a2
62+
; CHECK-NEXT: #NO_APP
63+
; CHECK-NEXT: sw a2, 8(a0)
64+
; CHECK-NEXT: sw a3, 12(a0)
65+
; CHECK-NEXT: ret
66+
entry:
67+
%arrayidx = getelementptr inbounds double, ptr %a, i32 1
68+
%0 = tail call double asm "fsgnj.d $0, $1, $1", "=r,0"(double %b)
69+
store double %0, ptr %arrayidx, align 8
70+
ret void
71+
}
72+
73+
define dso_local void @zdinx_asm_Pr_inout(ptr nocapture noundef writeonly %a, double noundef %b) nounwind {
74+
; CHECK-LABEL: zdinx_asm_Pr_inout:
75+
; CHECK: # %bb.0: # %entry
76+
; CHECK-NEXT: mv a3, a2
77+
; CHECK-NEXT: mv a2, a1
78+
; CHECK-NEXT: #APP
79+
; CHECK-NEXT: fabs.d a2, a2
80+
; CHECK-NEXT: #NO_APP
81+
; CHECK-NEXT: sw a2, 8(a0)
82+
; CHECK-NEXT: sw a3, 12(a0)
83+
; CHECK-NEXT: ret
84+
entry:
85+
%arrayidx = getelementptr inbounds double, ptr %a, i32 1
86+
%0 = tail call double asm "fsgnjx.d $0, $1, $1", "=^Pr,0"(double %b)
87+
store double %0, ptr %arrayidx, align 8
88+
ret void
89+
}
90+
5591
define dso_local void @zfinx_asm(ptr nocapture noundef writeonly %a, float noundef %b, float noundef %c) nounwind {
5692
; CHECK-LABEL: zfinx_asm:
5793
; CHECK: # %bb.0: # %entry

0 commit comments

Comments
 (0)