[llvm] [RISCV][llvm-mca] Vector Unit Stride Loads and stores use EEW and EMU… (PR #69409)
Wang Pengcheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 17 19:59:10 PDT 2023
================
@@ -185,6 +187,109 @@ RISCVInstrumentManager::createInstruments(const MCInst &Inst) {
return SmallVector<UniqueInstrument>();
}
+/// Return EMUL = (EEW / SEW) * LMUL
+inline static std::pair<unsigned, bool>
+getEMULEqualsEEWDivSEWTimesLMUL(unsigned EEW, unsigned SEW,
+ RISCVII::VLMUL VLMUL) {
+ // Calculate (EEW/SEW)*LMUL preserving fractions less than 1. Use GCD
+ // to put fraction in simplest form.
+ auto [LMUL, Fractional] = RISCVVType::decodeVLMUL(VLMUL);
+ unsigned Num = EEW, Denom = SEW;
+ int GCD =
+ Fractional ? std::gcd(Num, Denom * LMUL) : std::gcd(Num * LMUL, Denom);
+ Num = Fractional ? Num / GCD : Num * LMUL / GCD;
+ Denom = Fractional ? Denom * LMUL / GCD : Denom / GCD;
+ return std::make_pair(Num > Denom ? Num : Denom, Denom > Num);
+}
+
+static std::pair<uint8_t, uint8_t>
+getEEWAndEMULForUnitStrideLoadStore(unsigned Opcode, uint8_t LMUL,
+ uint8_t SEW) {
+ uint8_t EEW;
+ switch (Opcode) {
+ case RISCV::VLM_V:
+ case RISCV::VSM_V:
+ case RISCV::VLE8_V:
+ case RISCV::VSE8_V:
+ EEW = 8;
+ break;
+ case RISCV::VLE16_V:
+ case RISCV::VSE16_V:
+ EEW = 16;
+ break;
+ case RISCV::VLE32_V:
+ case RISCV::VSE32_V:
+ EEW = 32;
+ break;
+ case RISCV::VLE64_V:
+ case RISCV::VSE64_V:
+ EEW = 64;
+ break;
+ default:
+ llvm_unreachable("Opcode is not a vector unit stride load nor store");
+ }
+
+ RISCVII::VLMUL VLMUL;
+ switch (LMUL) {
+ case 0b000:
+ VLMUL = RISCVII::LMUL_1;
+ break;
+ case 0b001:
+ VLMUL = RISCVII::LMUL_2;
+ break;
+ case 0b010:
+ VLMUL = RISCVII::LMUL_4;
+ break;
+ case 0b011:
+ VLMUL = RISCVII::LMUL_8;
+ break;
+ case 0b111:
+ VLMUL = RISCVII::LMUL_F2;
+ break;
+ case 0b110:
+ VLMUL = RISCVII::LMUL_F4;
+ break;
+ case 0b101:
+ VLMUL = RISCVII::LMUL_F8;
+ break;
+ case RISCVII::LMUL_RESERVED:
+ llvm_unreachable("LMUL cannot be LMUL_RESERVED");
+ }
+
+ auto [EMULPart, Fractional] =
+ getEMULEqualsEEWDivSEWTimesLMUL(EEW, SEW, VLMUL);
+ assert(RISCVVType::isValidLMUL(EMULPart, Fractional) &&
+ "Unexpected EEW from instruction used with LMUL and SEW");
+
+ uint8_t EMUL;
+ switch (RISCVVType::encodeLMUL(EMULPart, Fractional)) {
----------------
wangpc-pp wrote:
This conversion can also be `static_cast` too.
https://github.com/llvm/llvm-project/pull/69409
More information about the llvm-commits
mailing list