From 29318f779da9c962af60d574b19159ecc10cfdd7 Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Thu, 15 Jun 2023 09:30:16 +0800 Subject: [PATCH 2/9] [neon2rvv] Model vxrm in LLVM intrinsics and add optimization for removing redundant csrwi Signed-off-by: Eric Tang --- clang/include/clang/Basic/riscv_vector.td | 134 +++++- llvm/include/llvm/IR/IntrinsicsRISCV.td | 94 +++- llvm/lib/Target/RISCV/CMakeLists.txt | 1 + .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 8 + llvm/lib/Target/RISCV/RISCV.h | 3 + .../Target/RISCV/RISCVInsertReadWriteCSR.cpp | 115 +++++ llvm/lib/Target/RISCV/RISCVInstrFormats.td | 3 + llvm/lib/Target/RISCV/RISCVInstrInfo.td | 2 + .../Target/RISCV/RISCVInstrInfoVPseudos.td | 428 +++++++++++++++++- llvm/lib/Target/RISCV/RISCVMCInstLower.cpp | 2 + llvm/lib/Target/RISCV/RISCVSystemOperands.td | 2 +- llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 2 + 12 files changed, 747 insertions(+), 47 deletions(-) create mode 100644 llvm/lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td index b23e26ecaa57..9d443be0403c 100644 --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -316,11 +316,21 @@ multiclass RVVSignedBinBuiltinSet [["vv", "v", "vvv"], ["vx", "v", "vve"]]>; +multiclass RVVSignedBinBuiltinSetRoundingMode + : RVVOutOp1BuiltinSet; + multiclass RVVUnsignedBinBuiltinSet : RVVOutOp1BuiltinSet; +multiclass RVVUnsignedBinBuiltinSetRoundingMode + : RVVOutOp1BuiltinSet; + multiclass RVVIntBinBuiltinSet : RVVSignedBinBuiltinSet, RVVUnsignedBinBuiltinSet; @@ -335,11 +345,21 @@ multiclass RVVSignedShiftBuiltinSet [["vv", "v", "vvUv"], ["vx", "v", "vvz"]]>; +multiclass RVVSignedShiftBuiltinSetRoundingMode + : RVVOutOp1BuiltinSet; + multiclass RVVUnsignedShiftBuiltinSet : RVVOutOp1BuiltinSet; +multiclass RVVUnsignedShiftBuiltinSetRoundingMode + : RVVOutOp1BuiltinSet; + multiclass RVVShiftBuiltinSet : RVVSignedShiftBuiltinSet, RVVUnsignedShiftBuiltinSet; @@ -349,10 +369,18 @@ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { : RVVOutOp0Op1BuiltinSet; + multiclass RVVSignedNShiftBuiltinSetRoundingMode + : RVVOutOp0Op1BuiltinSet; multiclass RVVUnsignedNShiftBuiltinSet : RVVOutOp0Op1BuiltinSet; + multiclass RVVUnsignedNShiftBuiltinSetRoundingMode + : RVVOutOp0Op1BuiltinSet; } multiclass RVVCarryinBuiltinSet @@ -1928,6 +1956,17 @@ let HasMasked = false, } // 13. Vector Fixed-Point Arithmetic Instructions +let HeaderCode = +[{ +enum __RISCV_VXRM { + __RISCV_VXRM_RNU = 0, + __RISCV_VXRM_RNE = 1, + __RISCV_VXRM_RDN = 2, + __RISCV_VXRM_ROD = 3, +}; +}] in +def vxrm_enum : RVVHeader; + // 13.1. Vector Single-Width Saturating Add and Subtract let UnMaskedPolicyScheme = HasPassthruOperand in { defm vsaddu : RVVUnsignedBinBuiltinSet; @@ -1936,23 +1975,94 @@ defm vssubu : RVVUnsignedBinBuiltinSet; defm vssub : RVVSignedBinBuiltinSet; // 13.2. Vector Single-Width Averaging Add and Subtract -defm vaaddu : RVVUnsignedBinBuiltinSet; -defm vaadd : RVVSignedBinBuiltinSet; -defm vasubu : RVVUnsignedBinBuiltinSet; -defm vasub : RVVSignedBinBuiltinSet; +let ManualCodegen = [{ + { + // LLVM intrinsic + // Unmasked: (passthru, op0, op1, round_mode, vl) + // Masked: (passthru, vector_in, vector_in/scalar_in, mask, vxrm, vl, policy) + + SmallVector Operands; + bool HasMaskedOff = !( + (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) || + (!IsMasked && PolicyAttrs & RVV_VTA)); + unsigned Offset = IsMasked ? + (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0); + + if (!HasMaskedOff) + Operands.push_back(llvm::PoisonValue::get(ResultType)); + else + Operands.push_back(Ops[Offset]); + + Operands.push_back(Ops[Offset]); // op0 + Operands.push_back(Ops[Offset + 1]); // op1 + + if (IsMasked) + Operands.push_back(Ops[0]); // mask + + Operands.push_back(Ops[Offset + 2]); // vxrm + Operands.push_back(Ops[Offset + 3]); // vl + + if (IsMasked) + Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs)); + + IntrinsicTypes = {ResultType, Ops[Offset + 1]->getType(), Ops.back()->getType()}; + llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes); + return Builder.CreateCall(F, Operands, ""); + } +}] in { + defm vaaddu : RVVUnsignedBinBuiltinSetRoundingMode; + defm vaadd : RVVSignedBinBuiltinSetRoundingMode; + defm vasubu : RVVUnsignedBinBuiltinSetRoundingMode; + defm vasub : RVVSignedBinBuiltinSetRoundingMode; // 13.3. Vector Single-Width Fractional Multiply with Rounding and Saturation -let RequiredFeatures = ["FullMultiply"] in { -defm vsmul : RVVSignedBinBuiltinSet; -} + let RequiredFeatures = ["FullMultiply"] in { + defm vsmul : RVVSignedBinBuiltinSetRoundingMode; + } // 13.4. Vector Single-Width Scaling Shift Instructions -defm vssrl : RVVUnsignedShiftBuiltinSet; -defm vssra : RVVSignedShiftBuiltinSet; - + defm vssrl : RVVUnsignedShiftBuiltinSetRoundingMode; + defm vssra : RVVSignedShiftBuiltinSetRoundingMode; +} +let ManualCodegen = [{ + { + // LLVM intrinsic + // Unmasked: (passthru, op0, op1, round_mode, vl) + // Masked: (passthru, vector_in, vector_in/scalar_in, mask, vxrm, vl, policy) + + SmallVector Operands; + bool HasMaskedOff = !( + (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) || + (!IsMasked && PolicyAttrs & RVV_VTA)); + unsigned Offset = IsMasked ? + (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0); + + if (!HasMaskedOff) + Operands.push_back(llvm::PoisonValue::get(ResultType)); + else + Operands.push_back(Ops[Offset - 1]); + + Operands.push_back(Ops[Offset]); // op0 + Operands.push_back(Ops[Offset + 1]); // op1 + + if (IsMasked) + Operands.push_back(Ops[0]); // mask + + Operands.push_back(Ops[Offset + 2]); // vxrm + Operands.push_back(Ops[Offset + 3]); // vl + + if (IsMasked) + Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs)); + + IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops[Offset + 1]->getType(), Ops.back()->getType()}; + llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes); + return Builder.CreateCall(F, Operands, ""); + } +}] in { // 13.5. Vector Narrowing Fixed-Point Clip Instructions -defm vnclipu : RVVUnsignedNShiftBuiltinSet; -defm vnclip : RVVSignedNShiftBuiltinSet; + defm vnclipu : RVVUnsignedNShiftBuiltinSetRoundingMode; + defm vnclip : RVVSignedNShiftBuiltinSetRoundingMode; +} // 14. Vector Floating-Point Instructions // 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index e9c88f468076..7103bb5f5e39 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -586,6 +586,17 @@ let TargetPrefix = "riscv" in { let ScalarOperand = 2; let VLOperand = 3; } + // For Saturating binary operations with rounding-mode operand + // The destination vector type is the same as first source vector. + // Input: (passthru, vector_in, vector_in/scalar_in, vxrm, vl) + class RISCVSaturatingBinaryAAXUnMaskedRoundingMode + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty, + llvm_anyint_ty, LLVMMatchType<2>], + [ImmArg>, IntrNoMem]>, RISCVVIntrinsic { + let ScalarOperand = 2; + let VLOperand = 4; + } // For Saturating binary operations with mask. // The destination vector type is the same as first source vector. // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vl, policy) @@ -598,6 +609,18 @@ let TargetPrefix = "riscv" in { let ScalarOperand = 2; let VLOperand = 4; } + // For Saturating binary operations with mask and rounding-mode operand + // The destination vector type is the same as first source vector. + // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vxrm, vl, policy) + class RISCVSaturatingBinaryAAXMaskedRoundingMode + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty, + LLVMMatchType<2>, LLVMMatchType<2>], + [ImmArg>, ImmArg>, IntrNoMem]>, RISCVVIntrinsic { + let ScalarOperand = 2; + let VLOperand = 5; + } // For Saturating binary operations. // The destination vector type is the same as first source vector. // The second source operand matches the destination type or is an XLen scalar. @@ -609,6 +632,15 @@ let TargetPrefix = "riscv" in { [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic { let VLOperand = 3; } + + // Input: (passthru, vector_in, vector_in/scalar_in, vxrm, vl) + class RISCVSaturatingBinaryAAShiftUnMaskedRoundingMode + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty, + llvm_anyint_ty, LLVMMatchType<2>], + [ImmArg>, IntrNoMem]>, RISCVVIntrinsic { + let VLOperand = 4; + } // For Saturating binary operations with mask. // The destination vector type is the same as first source vector. // The second source operand matches the destination type or is an XLen scalar. @@ -621,6 +653,17 @@ let TargetPrefix = "riscv" in { [ImmArg>, IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic { let VLOperand = 4; } + + // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vxrm, vl, policy) + class RISCVSaturatingBinaryAAShiftMaskedRoundingMode + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_any_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty, + LLVMMatchType<2>, LLVMMatchType<2>], + [ImmArg>, ImmArg>, IntrNoMem]>, RISCVVIntrinsic { + let VLOperand = 5; + } + // For Saturating binary operations. // The destination vector type is NOT the same as first source vector. // The second source operand matches the destination type or is an XLen scalar. @@ -632,6 +675,16 @@ let TargetPrefix = "riscv" in { [IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic { let VLOperand = 3; } + + // Input: (passthru, vector_in, vector_in/scalar_in, vxrm, vl) + class RISCVSaturatingBinaryABShiftUnMaskedRoundingMode + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, llvm_anyvector_ty, llvm_any_ty, + llvm_anyint_ty, LLVMMatchType<3>], + [ImmArg>, IntrNoMem]>, RISCVVIntrinsic { + let VLOperand = 4; + } + // For Saturating binary operations with mask. // The destination vector type is NOT the same as first source vector (with mask). // The second source operand matches the destination type or is an XLen scalar. @@ -644,6 +697,17 @@ let TargetPrefix = "riscv" in { [ImmArg>, IntrNoMem, IntrHasSideEffects]>, RISCVVIntrinsic { let VLOperand = 4; } + + // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, vxrm, vl, policy) + class RISCVSaturatingBinaryABShiftMaskedRoundingMode + : Intrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, llvm_anyvector_ty, llvm_any_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty, + LLVMMatchType<3>, LLVMMatchType<3>], + [ImmArg>, ImmArg>, IntrNoMem]>, RISCVVIntrinsic { + let VLOperand = 5; + } + // Input: (vector_in, vector_in, scalar_in, vl, policy) class RVVSlideUnMasked : DefaultAttrsIntrinsic<[llvm_anyvector_ty], @@ -1074,14 +1138,26 @@ let TargetPrefix = "riscv" in { def "int_riscv_" # NAME : RISCVSaturatingBinaryAAXUnMasked; def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryAAXMasked; } + multiclass RISCVSaturatingBinaryAAXRoundingMode { + def "int_riscv_" # NAME : RISCVSaturatingBinaryAAXUnMaskedRoundingMode; + def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryAAXMaskedRoundingMode; + } multiclass RISCVSaturatingBinaryAAShift { def "int_riscv_" # NAME : RISCVSaturatingBinaryAAShiftUnMasked; def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryAAShiftMasked; } + multiclass RISCVSaturatingBinaryAAShiftRoundingMode { + def "int_riscv_" # NAME : RISCVSaturatingBinaryAAShiftUnMaskedRoundingMode; + def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryAAShiftMaskedRoundingMode; + } multiclass RISCVSaturatingBinaryABShift { def "int_riscv_" # NAME : RISCVSaturatingBinaryABShiftUnMasked; def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryABShiftMasked; } + multiclass RISCVSaturatingBinaryABShiftRoundingMode { + def "int_riscv_" # NAME : RISCVSaturatingBinaryABShiftUnMaskedRoundingMode; + def "int_riscv_" # NAME # "_mask" : RISCVSaturatingBinaryABShiftMaskedRoundingMode; + } multiclass RVVSlide { def "int_riscv_" # NAME : RVVSlideUnMasked; def "int_riscv_" # NAME # "_mask" : RVVSlideMasked; @@ -1350,18 +1426,18 @@ let TargetPrefix = "riscv" in { def "int_riscv_vcompress" : RISCVCompress; - defm vaaddu : RISCVSaturatingBinaryAAX; - defm vaadd : RISCVSaturatingBinaryAAX; - defm vasubu : RISCVSaturatingBinaryAAX; - defm vasub : RISCVSaturatingBinaryAAX; + defm vaaddu : RISCVSaturatingBinaryAAXRoundingMode; + defm vaadd : RISCVSaturatingBinaryAAXRoundingMode; + defm vasubu : RISCVSaturatingBinaryAAXRoundingMode; + defm vasub : RISCVSaturatingBinaryAAXRoundingMode; - defm vsmul : RISCVSaturatingBinaryAAX; + defm vsmul : RISCVSaturatingBinaryAAXRoundingMode; - defm vssrl : RISCVSaturatingBinaryAAShift; - defm vssra : RISCVSaturatingBinaryAAShift; + defm vssrl : RISCVSaturatingBinaryAAShiftRoundingMode; + defm vssra : RISCVSaturatingBinaryAAShiftRoundingMode; - defm vnclipu : RISCVSaturatingBinaryABShift; - defm vnclip : RISCVSaturatingBinaryABShift; + defm vnclipu : RISCVSaturatingBinaryABShiftRoundingMode; + defm vnclip : RISCVSaturatingBinaryABShiftRoundingMode; defm vmfeq : RISCVCompare; defm vmfne : RISCVCompare; diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt index f909e0017e2b..db84f0504f21 100644 --- a/llvm/lib/Target/RISCV/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/CMakeLists.txt @@ -27,6 +27,7 @@ add_llvm_target(RISCVCodeGen RISCVFrameLowering.cpp RISCVGatherScatterLowering.cpp RISCVInsertVSETVLI.cpp + RISCVInsertReadWriteCSR.cpp RISCVInstrInfo.cpp RISCVISelDAGToDAG.cpp RISCVISelLowering.cpp diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 2cf2045c1719..eb43f4bf0a02 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -102,6 +102,9 @@ enum { // in bits 63:31. Used by the SExtWRemoval pass. IsSignExtendingOpWShift = UsesMaskPolicyShift + 1, IsSignExtendingOpWMask = 1ULL << IsSignExtendingOpWShift, + + HasRoundModeOpShift = IsSignExtendingOpWShift + 1, + HasRoundModeOpMask = 1 << HasRoundModeOpShift, }; // Match with the definitions in RISCVInstrFormats.td @@ -176,6 +179,11 @@ static inline bool usesMaskPolicy(uint64_t TSFlags) { return TSFlags & UsesMaskPolicyMask; } +/// \returns true if there is a rounding mode operand for this instruction +static inline bool hasRoundModeOp(uint64_t TSFlags) { + return TSFlags & HasRoundModeOpMask; +} + static inline unsigned getMergeOpNum(const MCInstrDesc &Desc) { assert(hasMergeOp(Desc.TSFlags)); assert(!Desc.isVariadic()); diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h index c42fb070aade..f629bd2faea9 100644 --- a/llvm/lib/Target/RISCV/RISCV.h +++ b/llvm/lib/Target/RISCV/RISCV.h @@ -68,6 +68,9 @@ void initializeRISCVExpandAtomicPseudoPass(PassRegistry &); FunctionPass *createRISCVInsertVSETVLIPass(); void initializeRISCVInsertVSETVLIPass(PassRegistry &); +FunctionPass *createRISCVInsertReadWriteCSRPass(); +void initializeRISCVInsertReadWriteCSRPass(PassRegistry &); + FunctionPass *createRISCVRedundantCopyEliminationPass(); void initializeRISCVRedundantCopyEliminationPass(PassRegistry &); diff --git a/llvm/lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp b/llvm/lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp new file mode 100644 index 000000000000..9cc06adf658c --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp @@ -0,0 +1,115 @@ +//===-- RISCVInsertReadWriteCSR.cpp - Insert Read/Write of RISC-V CSR -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// This file implements the machine function pass to insert read/write of CSR-s +// of the RISC-V instructions. +// +// Currently the pass implements naive insertion of a write to vxrm before an +// RVV fixed-point instruction. +// +//===----------------------------------------------------------------------===// + +#include "RISCV.h" +#include "RISCVSubtarget.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +using namespace llvm; + +#define DEBUG_TYPE "riscv-insert-read-write-csr" +#define RISCV_INSERT_READ_WRITE_CSR_NAME "RISC-V Insert Read/Write CSR Pass" + +namespace { + +class RISCVInsertReadWriteCSR : public MachineFunctionPass { + const TargetInstrInfo *TII; + +public: + static char ID; + + RISCVInsertReadWriteCSR() : MachineFunctionPass(ID) { + initializeRISCVInsertReadWriteCSRPass(*PassRegistry::getPassRegistry()); + } + + bool runOnMachineFunction(MachineFunction &MF) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesCFG(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + StringRef getPassName() const override { + return RISCV_INSERT_READ_WRITE_CSR_NAME; + } + +private: + bool emitWriteVXRM(MachineBasicBlock &MBB); + std::optional getRoundModeIdx(const MachineInstr &MI); +}; + +} // end anonymous namespace + +char RISCVInsertReadWriteCSR::ID = 0; + +static unsigned PreVXRMValue = 4; + +INITIALIZE_PASS(RISCVInsertReadWriteCSR, DEBUG_TYPE, + RISCV_INSERT_READ_WRITE_CSR_NAME, false, false) + +// This function returns the index to the rounding mode immediate value if any, +// otherwise the function will return None. +std::optional +RISCVInsertReadWriteCSR::getRoundModeIdx(const MachineInstr &MI) { + uint64_t TSFlags = MI.getDesc().TSFlags; + if (!RISCVII::hasRoundModeOp(TSFlags)) + return std::nullopt; + + // The operand order + // ------------------------------------- + // | n-1 (if any) | n-2 | n-3 | n-4 | + // | policy | sew | vl | rm | + // ------------------------------------- + return MI.getNumExplicitOperands() - RISCVII::hasVecPolicyOp(TSFlags) - 3; +} + +// This function inserts a write to vxrm when encountering an RVV fixed-point +// instruction. +bool RISCVInsertReadWriteCSR::emitWriteVXRM(MachineBasicBlock &MBB) { + bool Changed = false; + for (MachineInstr &MI : MBB) { + if (auto RoundModeIdx = getRoundModeIdx(MI)) { + unsigned VXRMImm = MI.getOperand(*RoundModeIdx).getImm(); + if (VXRMImm == PreVXRMValue) + continue; + PreVXRMValue = VXRMImm; + Changed = true; + BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::WriteVXRMImm)) + .addImm(VXRMImm); + MI.addOperand(MachineOperand::CreateReg(RISCV::VXRM, /*IsDef*/ false, + /*IsImp*/ true)); + } + } + return Changed; +} + +bool RISCVInsertReadWriteCSR::runOnMachineFunction(MachineFunction &MF) { + // Skip if the vector extension is not enabled. + const RISCVSubtarget &ST = MF.getSubtarget(); + if (!ST.hasVInstructions()) + return false; + + TII = ST.getInstrInfo(); + + bool Changed = false; + + for (MachineBasicBlock &MBB : MF) + Changed |= emitWriteVXRM(MBB); + + return Changed; +} + +FunctionPass *llvm::createRISCVInsertReadWriteCSRPass() { + return new RISCVInsertReadWriteCSR(); +} diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td index 3a494a5e3b58..f2cd4ed8857f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -211,6 +211,9 @@ class RVInst; def WriteFRMImm : WriteSysRegImm; def SwapFRMImm : SwapSysRegImm; +def WriteVXRMImm : WriteSysRegImm; + let hasSideEffects = true in { def ReadFFLAGS : ReadSysReg; def WriteFFLAGS : WriteSysReg; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td index 3f69b5e41cf1..ec7af31a23e2 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -1139,6 +1139,65 @@ class VPseudoBinaryNoMaskTU : + Pseudo<(outs RetClass:$rd), + (ins Op1Class:$rs2, Op2Class:$rs1, ixlenimm:$rm, AVL:$vl, ixlenimm:$sew), []>, + RISCVVPseudo { + let mayLoad = 0; + let mayStore = 0; + let hasSideEffects = 0; + let Constraints = Constraint; + let HasVLOp = 1; + let HasSEWOp = 1; + let HasDummyMask = DummyMask; + let HasRoundModeOp = 1; +} + +class VPseudoBinaryNoMaskTURoundingMode : + Pseudo<(outs RetClass:$rd), + (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, ixlenimm:$rm, + AVL:$vl, ixlenimm:$sew), []>, + RISCVVPseudo { + let mayLoad = 0; + let mayStore = 0; + let hasSideEffects = 0; + let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret; + let HasVLOp = 1; + let HasSEWOp = 1; + let HasDummyMask = 1; + let HasMergeOp = 1; + let HasRoundModeOp = 1; +} + +class VPseudoBinaryMaskPolicyRoundingMode : + Pseudo<(outs GetVRegNoV0.R:$rd), + (ins GetVRegNoV0.R:$merge, + Op1Class:$rs2, Op2Class:$rs1, + VMaskOp:$vm, ixlenimm:$rm, AVL:$vl, + ixlenimm:$sew, ixlenimm:$policy), []>, + RISCVVPseudo { + let mayLoad = 0; + let mayStore = 0; + let hasSideEffects = 0; + let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret; + let HasVLOp = 1; + let HasSEWOp = 1; + let HasMergeOp = 1; + let HasVecPolicyOp = 1; + let UsesMaskPolicy = 1; + let HasRoundModeOp = 1; +} + // Special version of VPseudoBinaryNoMask where we pretend the first source is // tied to the destination. // This allows maskedoff and rs2 to be the same register. @@ -1923,6 +1982,24 @@ multiclass VPseudoBinary { + let VLMul = MInfo.value in { + def "_" # MInfo.MX : + VPseudoBinaryNoMaskRoundingMode; + def "_" # MInfo.MX # "_TU" : + VPseudoBinaryNoMaskTURoundingMode; + def "_" # MInfo.MX # "_MASK" : + VPseudoBinaryMaskPolicyRoundingMode, + RISCVMaskedPseudo; + } +} + multiclass VPseudoBinaryM { defm _VV : VPseudoBinary; } +multiclass VPseudoBinaryV_VV_RM { + defm _VV : VPseudoBinaryRoundingMode; +} + // Similar to VPseudoBinaryV_VV, but uses MxListF. multiclass VPseudoBinaryFV_VV { defm _VV : VPseudoBinary; @@ -2000,6 +2081,10 @@ multiclass VPseudoBinaryV_VX { defm "_VX" : VPseudoBinary; } +multiclass VPseudoBinaryV_VX_RM { + defm "_VX" : VPseudoBinaryRoundingMode; +} + multiclass VPseudoVSLD1_VX { foreach m = MxList in { defvar mx = m.MX; @@ -2036,6 +2121,10 @@ multiclass VPseudoBinaryV_VI; } +multiclass VPseudoBinaryV_VI_RM { + defm _VI : VPseudoBinaryRoundingMode; +} + multiclass VPseudoVALU_MM { foreach m = MxList in { defvar mx = m.MX; @@ -2098,16 +2187,31 @@ multiclass VPseudoBinaryV_WV { !if(!ge(m.octuple, 8), "@earlyclobber $rd", "")>; } +multiclass VPseudoBinaryV_WV_RM { + defm _WV : VPseudoBinaryRoundingMode; +} + multiclass VPseudoBinaryV_WX { defm _WX : VPseudoBinary; } +multiclass VPseudoBinaryV_WX_RM { + defm _WX : VPseudoBinaryRoundingMode; +} + multiclass VPseudoBinaryV_WI { defm _WI : VPseudoBinary; } +multiclass VPseudoBinaryV_WI_RM { + defm _WI : VPseudoBinaryRoundingMode; +} + // For vadc and vsbc, the instruction encoding is reserved if the destination // vector register is v0. // For vadc and vsbc, CarryIn == 1 and CarryOut == 0 @@ -2419,6 +2523,23 @@ multiclass VPseudoVSALU_VV_VX_VI { + foreach m = MxList in { + defvar mx = m.MX; + defvar WriteVSALUV_MX = !cast("WriteVSALUV_" # mx); + defvar WriteVSALUX_MX = !cast("WriteVSALUX_" # mx); + defvar WriteVSALUI_MX = !cast("WriteVSALUI_" # mx); + defvar ReadVSALUV_MX = !cast("ReadVSALUV_" # mx); + defvar ReadVSALUX_MX = !cast("ReadVSALUX_" # mx); + + defm "" : VPseudoBinaryV_VV_RM, + Sched<[WriteVSALUV_MX, ReadVSALUV_MX, ReadVSALUV_MX, ReadVMask]>; + defm "" : VPseudoBinaryV_VX_RM, + Sched<[WriteVSALUX_MX, ReadVSALUV_MX, ReadVSALUX_MX, ReadVMask]>; + defm "" : VPseudoBinaryV_VI_RM, + Sched<[WriteVSALUI_MX, ReadVSALUV_MX, ReadVMask]>; + } +} multiclass VPseudoVSHT_VV_VX_VI { foreach m = MxList in { @@ -2456,6 +2577,24 @@ multiclass VPseudoVSSHT_VV_VX_VI { + foreach m = MxList in { + defvar mx = m.MX; + defvar WriteVSShiftV_MX = !cast("WriteVSShiftV_" # mx); + defvar WriteVSShiftX_MX = !cast("WriteVSShiftX_" # mx); + defvar WriteVSShiftI_MX = !cast("WriteVSShiftI_" # mx); + defvar ReadVSShiftV_MX = !cast("ReadVSShiftV_" # mx); + defvar ReadVSShiftX_MX = !cast("ReadVSShiftX_" # mx); + + defm "" : VPseudoBinaryV_VV_RM, + Sched<[WriteVSShiftV_MX, ReadVSShiftV_MX, ReadVSShiftV_MX, ReadVMask]>; + defm "" : VPseudoBinaryV_VX_RM, + Sched<[WriteVSShiftX_MX, ReadVSShiftV_MX, ReadVSShiftX_MX, ReadVMask]>; + defm "" : VPseudoBinaryV_VI_RM, + Sched<[WriteVSShiftI_MX, ReadVSShiftV_MX, ReadVMask]>; + } +} + multiclass VPseudoVALU_VV_VX_VI { foreach m = MxList in { defvar mx = m.MX; @@ -2489,6 +2628,21 @@ multiclass VPseudoVSALU_VV_VX { } } +multiclass VPseudoVSALU_VV_VX_RM { + foreach m = MxList in { + defvar mx = m.MX; + defvar WriteVSALUV_MX = !cast("WriteVSALUV_" # mx); + defvar WriteVSALUX_MX = !cast("WriteVSALUX_" # mx); + defvar ReadVSALUV_MX = !cast("ReadVSALUV_" # mx); + defvar ReadVSALUX_MX = !cast("ReadVSALUX_" # mx); + + defm "" : VPseudoBinaryV_VV_RM, + Sched<[WriteVSALUV_MX, ReadVSALUV_MX, ReadVSALUV_MX, ReadVMask]>; + defm "" : VPseudoBinaryV_VX_RM, + Sched<[WriteVSALUX_MX, ReadVSALUV_MX, ReadVSALUX_MX, ReadVMask]>; + } +} + multiclass VPseudoVSMUL_VV_VX { foreach m = MxList in { defvar mx = m.MX; @@ -2504,6 +2658,21 @@ multiclass VPseudoVSMUL_VV_VX { } } +multiclass VPseudoVSMUL_VV_VX_RM { + foreach m = MxList in { + defvar mx = m.MX; + defvar WriteVSMulV_MX = !cast("WriteVSMulV_" # mx); + defvar WriteVSMulX_MX = !cast("WriteVSMulX_" # mx); + defvar ReadVSMulV_MX = !cast("ReadVSMulV_" # mx); + defvar ReadVSMulX_MX = !cast("ReadVSMulX_" # mx); + + defm "" : VPseudoBinaryV_VV_RM, + Sched<[WriteVSMulV_MX, ReadVSMulV_MX, ReadVSMulV_MX, ReadVMask]>; + defm "" : VPseudoBinaryV_VX_RM, + Sched<[WriteVSMulX_MX, ReadVSMulV_MX, ReadVSMulX_MX, ReadVMask]>; + } +} + multiclass VPseudoVAALU_VV_VX { foreach m = MxList in { defvar mx = m.MX; @@ -2519,6 +2688,21 @@ multiclass VPseudoVAALU_VV_VX { } } +multiclass VPseudoVAALU_VV_VX_RM { + foreach m = MxList in { + defvar mx = m.MX; + defvar WriteVAALUV_MX = !cast("WriteVAALUV_" # mx); + defvar WriteVAALUX_MX = !cast("WriteVAALUX_" # mx); + defvar ReadVAALUV_MX = !cast("ReadVAALUV_" # mx); + defvar ReadVAALUX_MX = !cast("ReadVAALUX_" # mx); + + defm "" : VPseudoBinaryV_VV_RM, + Sched<[WriteVAALUV_MX, ReadVAALUV_MX, ReadVAALUV_MX, ReadVMask]>; + defm "" : VPseudoBinaryV_VX_RM, + Sched<[WriteVAALUX_MX, ReadVAALUV_MX, ReadVAALUX_MX, ReadVMask]>; + } +} + multiclass VPseudoVMINMAX_VV_VX { foreach m = MxList in { defvar mx = m.MX; @@ -3002,6 +3186,24 @@ multiclass VPseudoVNCLP_WV_WX_WI { } } +multiclass VPseudoVNCLP_WV_WX_WI_RM { + foreach m = MxListW in { + defvar mx = m.MX; + defvar WriteVNClipV_MX = !cast("WriteVNClipV_" # mx); + defvar WriteVNClipX_MX = !cast("WriteVNClipX_" # mx); + defvar WriteVNClipI_MX = !cast("WriteVNClipI_" # mx); + defvar ReadVNClipV_MX = !cast("ReadVNClipV_" # mx); + defvar ReadVNClipX_MX = !cast("ReadVNClipX_" # mx); + + defm "" : VPseudoBinaryV_WV_RM, + Sched<[WriteVNClipV_MX, ReadVNClipV_MX, ReadVNClipV_MX, ReadVMask]>; + defm "" : VPseudoBinaryV_WX_RM, + Sched<[WriteVNClipX_MX, ReadVNClipV_MX, ReadVNClipX_MX, ReadVMask]>; + defm "" : VPseudoBinaryV_WI_RM, + Sched<[WriteVNClipI_MX, ReadVNClipV_MX, ReadVMask]>; + } +} + multiclass VPseudoVNSHT_WV_WX_WI { foreach m = MxListW in { defvar mx = m.MX; @@ -3881,6 +4083,48 @@ class VPatBinaryNoMaskTU; +class VPatBinaryNoMaskTARoundingMode : + Pat<(result_type (!cast(intrinsic_name) + (result_type (undef)), + (op1_type op1_reg_class:$rs1), + (op2_type op2_kind:$rs2), + (XLenVT timm:$round), + VLOpFrag)), + (!cast(inst) + (op1_type op1_reg_class:$rs1), + (op2_type op2_kind:$rs2), + (XLenVT timm:$round), + GPR:$vl, sew)>; + +class VPatBinaryNoMaskTURoundingMode : + Pat<(result_type (!cast(intrinsic_name) + (result_type result_reg_class:$merge), + (op1_type op1_reg_class:$rs1), + (op2_type op2_kind:$rs2), + (XLenVT timm:$round), + VLOpFrag)), + (!cast(inst#"_TU") + (result_type result_reg_class:$merge), + (op1_type op1_reg_class:$rs1), + (op2_type op2_kind:$rs2), + (XLenVT timm:$round), + GPR:$vl, sew)>; + // Same as above but source operands are swapped. class VPatBinaryNoMaskSwapped; +class VPatBinaryMaskTARoundingMode : + Pat<(result_type (!cast(intrinsic_name#"_mask") + (result_type result_reg_class:$merge), + (op1_type op1_reg_class:$rs1), + (op2_type op2_kind:$rs2), + (mask_type V0), + (XLenVT timm:$round), + VLOpFrag, (XLenVT timm:$policy))), + (!cast(inst#"_MASK") + (result_type result_reg_class:$merge), + (op1_type op1_reg_class:$rs1), + (op2_type op2_kind:$rs2), + (mask_type V0), + (XLenVT timm:$round), + GPR:$vl, sew, (XLenVT timm:$policy))>; + // Same as above but source operands are swapped. class VPatBinaryMaskSwapped; } +multiclass VPatBinaryTARoundingMode +{ + def : VPatBinaryNoMaskTARoundingMode; + def : VPatBinaryNoMaskTURoundingMode; + def : VPatBinaryMaskTARoundingMode; +} + multiclass VPatBinarySwapped; } +multiclass VPatBinaryV_VVRoundingMode vtilist> { + foreach vti = vtilist in + defm : VPatBinaryTARoundingMode; +} + multiclass VPatBinaryV_VV_INT vtilist> { foreach vti = vtilist in { @@ -4428,6 +4726,17 @@ multiclass VPatBinaryV_VX vtilist> { + foreach vti = vtilist in { + defvar kind = "V"#vti.ScalarSuffix; + defm : VPatBinaryTARoundingMode; + } +} + multiclass VPatBinaryV_VX_INT vtilist> { foreach vti = vtilist in @@ -4446,6 +4755,15 @@ multiclass VPatBinaryV_VI; } +multiclass VPatBinaryV_VIRoundingMode vtilist, Operand imm_type> { + foreach vti = vtilist in + defm : VPatBinaryTARoundingMode; +} + multiclass VPatBinaryM_MM { foreach mti = AllMasks in def : VPatBinaryM vtilist> { + foreach VtiToWti = vtilist in { + defvar Vti = VtiToWti.Vti; + defvar Wti = VtiToWti.Wti; + defm : VPatBinaryTARoundingMode; + } +} + multiclass VPatBinaryV_WX vtilist> { foreach VtiToWti = vtilist in { @@ -4542,6 +4872,19 @@ multiclass VPatBinaryV_WX vtilist> { + foreach VtiToWti = vtilist in { + defvar Vti = VtiToWti.Vti; + defvar Wti = VtiToWti.Wti; + defvar kind = "W"#Vti.ScalarSuffix; + defm : VPatBinaryTARoundingMode; + } +} + multiclass VPatBinaryV_WI vtilist> { foreach VtiToWti = vtilist in { @@ -4554,6 +4897,18 @@ multiclass VPatBinaryV_WI vtilist> { + foreach VtiToWti = vtilist in { + defvar Vti = VtiToWti.Vti; + defvar Wti = VtiToWti.Wti; + defm : VPatBinaryTARoundingMode; + } +} + multiclass VPatBinaryV_VM vtilist = AllIntegerVectors> { @@ -4688,11 +5043,22 @@ multiclass VPatBinaryV_VV_VX_VI, VPatBinaryV_VI; +multiclass VPatBinaryV_VV_VX_VIRoundingMode vtilist, Operand ImmType = simm5> + : VPatBinaryV_VVRoundingMode, + VPatBinaryV_VXRoundingMode, + VPatBinaryV_VIRoundingMode; + multiclass VPatBinaryV_VV_VX vtilist> : VPatBinaryV_VV, VPatBinaryV_VX; +multiclass VPatBinaryV_VV_VXRoundingMode vtilist> + : VPatBinaryV_VVRoundingMode, + VPatBinaryV_VXRoundingMode; + multiclass VPatBinaryV_VX_VI vtilist> : VPatBinaryV_VX, @@ -4714,6 +5080,12 @@ multiclass VPatBinaryV_WV_WX_WI, VPatBinaryV_WI; +multiclass VPatBinaryV_WV_WX_WIRoundingMode vtilist> + : VPatBinaryV_WVRoundingMode, + VPatBinaryV_WXRoundingMode, + VPatBinaryV_WIRoundingMode; + multiclass VPatBinaryV_VM_XM_IM : VPatBinaryV_VM_TAIL, VPatBinaryV_XM_TAIL, @@ -5382,34 +5754,34 @@ let Defs = [VXSAT], hasSideEffects = 1 in { //===----------------------------------------------------------------------===// // 12.2. Vector Single-Width Averaging Add and Subtract //===----------------------------------------------------------------------===// -let Uses = [VXRM], hasSideEffects = 1 in { - defm PseudoVAADDU : VPseudoVAALU_VV_VX; - defm PseudoVAADD : VPseudoVAALU_VV_VX; - defm PseudoVASUBU : VPseudoVAALU_VV_VX; - defm PseudoVASUB : VPseudoVAALU_VV_VX; +let hasSideEffects = 1 in { + defm PseudoVAADDU : VPseudoVAALU_VV_VX_RM; + defm PseudoVAADD : VPseudoVAALU_VV_VX_RM; + defm PseudoVASUBU : VPseudoVAALU_VV_VX_RM; + defm PseudoVASUB : VPseudoVAALU_VV_VX_RM; } //===----------------------------------------------------------------------===// // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation //===----------------------------------------------------------------------===// -let Uses = [VXRM], Defs = [VXSAT], hasSideEffects = 1 in { - defm PseudoVSMUL : VPseudoVSMUL_VV_VX; +let Defs = [VXSAT], hasSideEffects = 1 in { + defm PseudoVSMUL : VPseudoVSMUL_VV_VX_RM; } //===----------------------------------------------------------------------===// // 12.4. Vector Single-Width Scaling Shift Instructions //===----------------------------------------------------------------------===// -let Uses = [VXRM], hasSideEffects = 1 in { - defm PseudoVSSRL : VPseudoVSSHT_VV_VX_VI; - defm PseudoVSSRA : VPseudoVSSHT_VV_VX_VI; +let hasSideEffects = 1 in { + defm PseudoVSSRL : VPseudoVSSHT_VV_VX_VI_RM; + defm PseudoVSSRA : VPseudoVSSHT_VV_VX_VI_RM; } //===----------------------------------------------------------------------===// // 12.5. Vector Narrowing Fixed-Point Clip Instructions //===----------------------------------------------------------------------===// -let Uses = [VXRM], Defs = [VXSAT], hasSideEffects = 1 in { - defm PseudoVNCLIP : VPseudoVNCLP_WV_WX_WI; - defm PseudoVNCLIPU : VPseudoVNCLP_WV_WX_WI; +let Defs = [VXSAT], hasSideEffects = 1 in { + defm PseudoVNCLIP : VPseudoVNCLP_WV_WX_WI_RM; + defm PseudoVNCLIPU : VPseudoVNCLP_WV_WX_WI_RM; } } // Predicates = [HasVInstructions] @@ -6040,30 +6412,36 @@ defm : VPatBinaryV_VV_VX<"int_riscv_vssub", "PseudoVSSUB", AllIntegerVectors>; //===----------------------------------------------------------------------===// // 12.2. Vector Single-Width Averaging Add and Subtract //===----------------------------------------------------------------------===// -defm : VPatBinaryV_VV_VX<"int_riscv_vaaddu", "PseudoVAADDU", AllIntegerVectors>; -defm : VPatBinaryV_VV_VX<"int_riscv_vaadd", "PseudoVAADD", AllIntegerVectors>; -defm : VPatBinaryV_VV_VX<"int_riscv_vasubu", "PseudoVASUBU", AllIntegerVectors>; -defm : VPatBinaryV_VV_VX<"int_riscv_vasub", "PseudoVASUB", AllIntegerVectors>; +defm : VPatBinaryV_VV_VXRoundingMode<"int_riscv_vaaddu", "PseudoVAADDU", + AllIntegerVectors>; +defm : VPatBinaryV_VV_VXRoundingMode<"int_riscv_vasubu", "PseudoVASUBU", + AllIntegerVectors>; +defm : VPatBinaryV_VV_VXRoundingMode<"int_riscv_vasub", "PseudoVASUB", + AllIntegerVectors>; +defm : VPatBinaryV_VV_VXRoundingMode<"int_riscv_vaadd", "PseudoVAADD", + AllIntegerVectors>; //===----------------------------------------------------------------------===// // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation //===----------------------------------------------------------------------===// -defm : VPatBinaryV_VV_VX<"int_riscv_vsmul", "PseudoVSMUL", AllIntegerVectors>; +defm : VPatBinaryV_VV_VXRoundingMode<"int_riscv_vsmul", "PseudoVSMUL", + AllIntegerVectors>; //===----------------------------------------------------------------------===// // 12.4. Vector Single-Width Scaling Shift Instructions //===----------------------------------------------------------------------===// -defm : VPatBinaryV_VV_VX_VI<"int_riscv_vssrl", "PseudoVSSRL", AllIntegerVectors, - uimm5>; -defm : VPatBinaryV_VV_VX_VI<"int_riscv_vssra", "PseudoVSSRA", AllIntegerVectors, - uimm5>; +defm : VPatBinaryV_VV_VX_VIRoundingMode<"int_riscv_vssrl", "PseudoVSSRL", + AllIntegerVectors, uimm5>; +defm : VPatBinaryV_VV_VX_VIRoundingMode<"int_riscv_vssra", "PseudoVSSRA", + AllIntegerVectors, uimm5>; //===----------------------------------------------------------------------===// // 12.5. Vector Narrowing Fixed-Point Clip Instructions //===----------------------------------------------------------------------===// -defm : VPatBinaryV_WV_WX_WI<"int_riscv_vnclipu", "PseudoVNCLIPU", AllWidenableIntVectors>; -defm : VPatBinaryV_WV_WX_WI<"int_riscv_vnclip", "PseudoVNCLIP", AllWidenableIntVectors>; - +defm : VPatBinaryV_WV_WX_WIRoundingMode<"int_riscv_vnclipu", "PseudoVNCLIPU", + AllWidenableIntVectors>; +defm : VPatBinaryV_WV_WX_WIRoundingMode<"int_riscv_vnclip", "PseudoVNCLIP", + AllWidenableIntVectors>; } // Predicates = [HasVInstructions] //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp index 281918259cdb..7455df64c38a 100644 --- a/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp +++ b/llvm/lib/Target/RISCV/RISCVMCInstLower.cpp @@ -159,6 +159,8 @@ static bool lowerRISCVVMachineInstrToMCInst(const MachineInstr *MI, --NumOps; if (RISCVII::hasVLOp(TSFlags)) --NumOps; + if (RISCVII::hasRoundModeOp(TSFlags)) + --NumOps; if (RISCVII::hasSEWOp(TSFlags)) --NumOps; diff --git a/llvm/lib/Target/RISCV/RISCVSystemOperands.td b/llvm/lib/Target/RISCV/RISCVSystemOperands.td index b9aa25b321b0..ced58fbb2a6d 100644 --- a/llvm/lib/Target/RISCV/RISCVSystemOperands.td +++ b/llvm/lib/Target/RISCV/RISCVSystemOperands.td @@ -350,7 +350,7 @@ def : SysReg<"dscratch1", 0x7B3>; //===----------------------------------------------------------------------===// def : SysReg<"vstart", 0x008>; def : SysReg<"vxsat", 0x009>; -def : SysReg<"vxrm", 0x00A>; +def SysRegVXRM : SysReg<"vxrm", 0x00A>; def : SysReg<"vcsr", 0x00F>; def : SysReg<"vl", 0xC20>; def : SysReg<"vtype", 0xC21>; diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index cc881406666c..28908e88f39f 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -81,6 +81,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { initializeRISCVPreRAExpandPseudoPass(*PR); initializeRISCVExpandPseudoPass(*PR); initializeRISCVInsertVSETVLIPass(*PR); + initializeRISCVInsertReadWriteCSRPass(*PR); initializeRISCVDAGToDAGISelPass(*PR); } @@ -354,6 +355,7 @@ void RISCVPassConfig::addPreRegAlloc() { if (TM->getOptLevel() != CodeGenOpt::None) addPass(createRISCVMergeBaseOffsetOptPass()); addPass(createRISCVInsertVSETVLIPass()); + addPass(createRISCVInsertReadWriteCSRPass()); } void RISCVPassConfig::addPostRegAlloc() { -- 2.25.1