From ad551c1335ba0e6a0c691df5bae03df7d6029b8a Mon Sep 17 00:00:00 2001 From: gonglingqin Date: Wed, 11 Jan 2023 15:04:45 +0800 Subject: [PATCH] [LoongArch] Fixed llvm/test/CodeGen/LoongArch/intrinsic.ll test failure when EXPENSIV_CHECK is enabled [1]. Specifically: ``` *** Bad machine code: Using an undefined physical register *** - function: movgr2fcsr - basic block: %bb.0 entry (0x1af5e60) - instruction: MOVGR2FCSR $fcsr1, %0:gpr - operand 0: $fcsr1 *** Bad machine code: Using an undefined physical register *** - function: movfcsr2gr - basic block: %bb.0 entry (0x133fae0) - instruction: %0:gpr = MOVFCSR2GR $fcsr1 - operand 1: $fcsr1 ``` By building MachineInstructions, the state of the register is clarified, and the error caused by using undefined physical registers is fixed. [1]: https://lab.llvm.org/buildbot/#/builders/16/builds/41677 --- .../Target/LoongArch/LoongArchFloat32InstrInfo.td | 3 +- .../lib/Target/LoongArch/LoongArchISelLowering.cpp | 32 +++++++++++++++++----- llvm/lib/Target/LoongArch/LoongArchInstrInfo.td | 18 ++++++------ llvm/test/CodeGen/LoongArch/intrinsic.ll | 4 +-- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td index f6981a0..40e7665 100644 --- a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td @@ -98,8 +98,7 @@ def FSEL_S : FP_SEL<0b00001101000000, "fsel", FPR32>; def FMOV_S : FP_MOV<0b0000000100010100100101, "fmov.s", FPR32, FPR32>; def MOVGR2FR_W : FP_MOV<0b0000000100010100101001, "movgr2fr.w", FPR32, GPR>; def MOVFR2GR_S : FP_MOV<0b0000000100010100101101, "movfr2gr.s", GPR, FPR32>; -def MOVGR2FCSR : FPFmtMOV<0b0000000100010100110000, (outs), (ins FCSR:$dst, GPR:$src), - "movgr2fcsr", "$dst, $src">; +def MOVGR2FCSR : FP_MOV<0b0000000100010100110000, "movgr2fcsr", FCSR, GPR>; def MOVFCSR2GR : FP_MOV<0b0000000100010100110010, "movfcsr2gr", GPR, FCSR>; def MOVFR2CF_S : FP_MOV<0b0000000100010100110100, "movfr2cf", CFR, FPR32>; def MOVCF2FR_S : FP_MOV<0b0000000100010100110101, "movcf2fr", FPR32, CFR>; diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index afdc6d1..61fda67 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -722,7 +722,7 @@ LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op, } return DAG.getMergeValues( {DAG.getNode(LoongArchISD::MOVFCSR2GR, DL, Op.getValueType(), - DAG.getRegister(LoongArch::FCSR0 + Imm, MVT::i32)), + DAG.getConstant(Imm, DL, GRLenVT)), Op.getOperand(0)}, DL); } @@ -812,7 +812,7 @@ SDValue LoongArchTargetLowering::lowerINTRINSIC_VOID(SDValue Op, return DAG.getNode( LoongArchISD::MOVGR2FCSR, DL, MVT::Other, Op0, - DAG.getRegister(LoongArch::FCSR0 + Imm, MVT::i32), + DAG.getConstant(Imm, DL, GRLenVT), DAG.getNode(ISD::ANY_EXTEND, DL, GRLenVT, Op.getOperand(3))); } case Intrinsic::loongarch_syscall: { @@ -1145,6 +1145,7 @@ void LoongArchTargetLowering::ReplaceNodeResults( SDValue Op0 = N->getOperand(0); EVT VT = N->getValueType(0); uint64_t Op1 = N->getConstantOperandVal(1); + MVT GRLenVT = Subtarget.getGRLenVT(); if (Op1 == Intrinsic::loongarch_movfcsr2gr) { if (!Subtarget.hasBasicF()) { DAG.getContext()->emitError( @@ -1163,15 +1164,14 @@ void LoongArchTargetLowering::ReplaceNodeResults( Results.push_back(N->getOperand(0)); return; } - Results.push_back(DAG.getNode( - ISD::TRUNCATE, DL, VT, - DAG.getNode(LoongArchISD::MOVFCSR2GR, SDLoc(N), MVT::i64, - DAG.getRegister(LoongArch::FCSR0 + Imm, MVT::i32)))); + Results.push_back( + DAG.getNode(ISD::TRUNCATE, DL, VT, + DAG.getNode(LoongArchISD::MOVFCSR2GR, SDLoc(N), MVT::i64, + DAG.getConstant(Imm, DL, GRLenVT)))); Results.push_back(N->getOperand(0)); return; } SDValue Op2 = N->getOperand(2); - MVT GRLenVT = Subtarget.getGRLenVT(); std::string Name = N->getOperationName(0); switch (Op1) { @@ -1729,6 +1729,8 @@ static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI, MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter( MachineInstr &MI, MachineBasicBlock *BB) const { + const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + DebugLoc DL = MI.getDebugLoc(); switch (MI.getOpcode()) { default: @@ -1743,6 +1745,22 @@ MachineBasicBlock *LoongArchTargetLowering::EmitInstrWithCustomInserter( case LoongArch::MOD_DU: return insertDivByZeroTrap(MI, BB); break; + case LoongArch::WRFCSR: { + BuildMI(*BB, MI, DL, TII->get(LoongArch::MOVGR2FCSR), + LoongArch::FCSR0 + MI.getOperand(0).getImm()) + .addReg(MI.getOperand(1).getReg()); + MI.eraseFromParent(); + return BB; + } + case LoongArch::RDFCSR: { + MachineInstr *ReadFCSR = + BuildMI(*BB, MI, DL, TII->get(LoongArch::MOVFCSR2GR), + MI.getOperand(0).getReg()) + .addReg(LoongArch::FCSR0 + MI.getOperand(1).getImm()); + ReadFCSR->getOperand(1).setIsUndef(); + MI.eraseFromParent(); + return BB; + } } } diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td index 8e552b2..75b2adc 100644 --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -48,10 +48,10 @@ def SDT_LoongArchCsrxchg : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisVT<3, GRLenVT>]>; def SDT_LoongArchIocsrwr : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>; -def SDT_LoongArchMovgr2fcsr : SDTypeProfile<0, 2, [SDTCisVT<0, i32>, - SDTCisVT<1, GRLenVT>]>; +def SDT_LoongArchMovgr2fcsr : SDTypeProfile<0, 2, [SDTCisVT<0, GRLenVT>, + SDTCisSameAs<0, 1>]>; def SDT_LoongArchMovfcsr2gr : SDTypeProfile<1, 1, [SDTCisVT<0, GRLenVT>, - SDTCisVT<1, i32>]>; + SDTCisSameAs<0, 1>]>; // TODO: Add LoongArch specific DAG Nodes // Target-independent nodes, but with target-specific formats. @@ -180,7 +180,7 @@ def imm32 : Operand { let ParserMatchClass = ImmAsmOperand<"", 32, "">; } -def uimm2 : Operand { +def uimm2 : Operand, ImmLeaf(Imm);}]> { let ParserMatchClass = UImmAsmOperand<2>; } @@ -1647,11 +1647,11 @@ def PseudoLI_D : Pseudo<(outs GPR:$rd), (ins grlenimm:$imm), [], include "LoongArchFloat32InstrInfo.td" include "LoongArchFloat64InstrInfo.td" -let Predicates = [HasBasicF] in { -def : Pat<(loongarch_movfcsr2gr i32:$fcsr), - (MOVFCSR2GR FCSR:$fcsr)>; -def : Pat<(loongarch_movgr2fcsr i32:$fcsr, GRLenVT:$rj), - (MOVGR2FCSR FCSR:$fcsr, GPR:$rj)>; +let Predicates = [HasBasicF], usesCustomInserter = 1 in { + def WRFCSR : Pseudo<(outs), (ins uimm2:$fcsr, GPR:$src), + [(loongarch_movgr2fcsr uimm2:$fcsr, GRLenVT:$src)]>; + def RDFCSR : Pseudo<(outs GPR:$rd), (ins uimm2:$fcsr), + [(set GPR:$rd, (loongarch_movfcsr2gr uimm2:$fcsr))]>; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/LoongArch/intrinsic.ll b/llvm/test/CodeGen/LoongArch/intrinsic.ll index 401e07f..cfd54e1 100644 --- a/llvm/test/CodeGen/LoongArch/intrinsic.ll +++ b/llvm/test/CodeGen/LoongArch/intrinsic.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc --mtriple=loongarch32 --mattr=+f < %s | FileCheck %s -; RUN: llc --mtriple=loongarch64 --mattr=+f < %s | FileCheck %s +; RUN: llc --mtriple=loongarch32 --mattr=+f --verify-machineinstrs < %s | FileCheck %s +; RUN: llc --mtriple=loongarch64 --mattr=+f --verify-machineinstrs < %s | FileCheck %s declare void @llvm.loongarch.dbar(i32) declare void @llvm.loongarch.ibar(i32) -- 2.7.4