From ffc18c33396b612c543868742fdbcb41a777a172 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 12 Mar 2023 22:02:23 -0700 Subject: [PATCH] Revert "[RISCV] Add separate lookup tables for fli.h and fli.d." This reverts commit ebc11b68412cdcf2a0e6e2c50df262cfd9b8f481. I made a mistake in the f16 table. Will fix and recommit. --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 6 +- .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp | 121 ++------------------- llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 56 +++++++++- llvm/test/CodeGen/RISCV/double-zfa.ll | 4 +- llvm/test/CodeGen/RISCV/half-zfa-fli.ll | 8 +- 5 files changed, 72 insertions(+), 123 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 783c5eb..9698c99 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -496,8 +496,7 @@ public: return isUImm5(); if (Kind != KindTy::FPImmediate) return false; - int Idx = RISCVLoadFPImm::getLoadFP64Imm( - APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst()))); + int Idx = RISCVLoadFPImm::getLoadFP64Imm(APInt(64, getFPConst())); // Don't allow decimal version of the minimum value. It is a different value // for each supported data type. return Idx >= 0 && Idx != 1; @@ -985,8 +984,7 @@ public: return; } - int Imm = RISCVLoadFPImm::getLoadFP64Imm( - APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst()))); + int Imm = RISCVLoadFPImm::getLoadFP64Imm(APInt(64, getFPConst())); Inst.addOperand(MCOperand::createImm(Imm)); } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp index 335c9585..988fefe 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp @@ -214,22 +214,8 @@ bool RISCVRVC::uncompress(MCInst &OutInst, const MCInst &MI, return uncompressInst(OutInst, MI, STI); } -// Lookup table for fli.h for entries 1-31. Entry 0(-1.0) is handled separately. -// NOTE: The exponent for entry 1 is larger than entry 2 and 3 because they -// are denormals. -static constexpr std::pair LoadFP16ImmArr[] = { - {0b00001, 0b00}, {0b00000, 0b10}, {0b00000, 0b01}, {0b00111, 0b00}, - {0b01000, 0b00}, {0b01011, 0b00}, {0b01100, 0b00}, {0b01101, 0b00}, - {0b01101, 0b01}, {0b01101, 0b10}, {0b01101, 0b11}, {0b01110, 0b00}, - {0b01110, 0b01}, {0b01110, 0b10}, {0b01110, 0b11}, {0b01111, 0b00}, - {0b01111, 0b01}, {0b01111, 0b10}, {0b01111, 0b11}, {0b10000, 0b00}, - {0b10000, 0b01}, {0b10000, 0b10}, {0b10001, 0b00}, {0b10010, 0b00}, - {0b10011, 0b00}, {0b10110, 0b00}, {0b10111, 0b00}, {0b11110, 0b00}, - {0b11111, 0b00}, {0b11111, 0b00}, {0b11111, 0b10}, -}; - -// Lookup table for fli.s for entries 1-31. -static constexpr std::pair LoadFP32ImmArr[] = { +// We expect an 5-bit binary encoding of a floating-point constant here. +static constexpr std::pair LoadFPImmArr[] = { {0b00000001, 0b00}, {0b01101111, 0b00}, {0b01110000, 0b00}, {0b01110111, 0b00}, {0b01111000, 0b00}, {0b01111011, 0b00}, {0b01111100, 0b00}, {0b01111101, 0b00}, {0b01111101, 0b01}, @@ -243,104 +229,15 @@ static constexpr std::pair LoadFP32ImmArr[] = { {0b11111111, 0b10}, }; -// Lookup table for fli.d for entries 1-31. -static constexpr std::pair LoadFP64ImmArr[] = { - {0b00000000001, 0b00}, {0b01111101111, 0b00}, {0b01111110000, 0b00}, - {0b01111110111, 0b00}, {0b01111111000, 0b00}, {0b01111111011, 0b00}, - {0b01111111100, 0b00}, {0b01111111101, 0b00}, {0b01111111101, 0b01}, - {0b01111111101, 0b10}, {0b01111111101, 0b11}, {0b01111111110, 0b00}, - {0b01111111110, 0b01}, {0b01111111110, 0b10}, {0b01111111110, 0b11}, - {0b01111111111, 0b00}, {0b01111111111, 0b01}, {0b01111111111, 0b10}, - {0b01111111111, 0b11}, {0b10000000000, 0b00}, {0b10000000000, 0b01}, - {0b10000000000, 0b10}, {0b10000000001, 0b00}, {0b10000000010, 0b00}, - {0b10000000011, 0b00}, {0b10000000110, 0b00}, {0b10000000111, 0b00}, - {0b10000001110, 0b00}, {0b10000001111, 0b00}, {0b11111111111, 0b00}, - {0b11111111111, 0b10}, -}; - -int RISCVLoadFPImm::getLoadFP16Imm(const APFloat &FPImm) { - assert(&FPImm.getSemantics() == &APFloat::IEEEhalf()); - - APInt Imm = FPImm.bitcastToAPInt(); - - if (Imm.extractBitsAsZExtValue(8, 0) != 0) - return -1; - - bool Sign = Imm.extractBitsAsZExtValue(1, 15); - uint8_t Mantissa = Imm.extractBitsAsZExtValue(2, 8); - uint8_t Exp = Imm.extractBitsAsZExtValue(5, 10); - - // The array isn't sorted so we must use std::find unlike fp32 and fp64. - auto EMI = llvm::find(LoadFP16ImmArr, std::make_pair(Exp, Mantissa)); - if (EMI == std::end(LoadFP16ImmArr)) - return -1; - - // Table doesn't have entry 0. - int Entry = std::distance(std::begin(LoadFP16ImmArr), EMI) + 1; - - // The only legal negative value is -1.0(entry 0). 1.0 is entry 16. - if (Sign) { - if (Entry == 16) - return 0; - return false; - } - - // Entry 29 and 30 are both infinity, but 30 is the real infinity. - if (Entry == 29) - ++Entry; - - return Entry; -} - -int RISCVLoadFPImm::getLoadFP32Imm(const APFloat &FPImm) { - assert(&FPImm.getSemantics() == &APFloat::IEEEsingle()); - - APInt Imm = FPImm.bitcastToAPInt(); - - if (Imm.extractBitsAsZExtValue(21, 0) != 0) - return -1; - - bool Sign = Imm.extractBitsAsZExtValue(1, 31); - uint8_t Mantissa = Imm.extractBitsAsZExtValue(2, 21); - uint8_t Exp = Imm.extractBitsAsZExtValue(8, 23); - - auto EMI = llvm::lower_bound(LoadFP32ImmArr, std::make_pair(Exp, Mantissa)); - if (EMI == std::end(LoadFP32ImmArr) || EMI->first != Exp || - EMI->second != Mantissa) - return -1; - - // Table doesn't have entry 0. - int Entry = std::distance(std::begin(LoadFP32ImmArr), EMI) + 1; - - // The only legal negative value is -1.0(entry 0). 1.0 is entry 16. - if (Sign) { - if (Entry == 16) - return 0; - return false; - } - - return Entry; -} - -int RISCVLoadFPImm::getLoadFP64Imm(const APFloat &FPImm) { - assert(&FPImm.getSemantics() == &APFloat::IEEEdouble()); - - APInt Imm = FPImm.bitcastToAPInt(); - - if (Imm.extractBitsAsZExtValue(50, 0) != 0) - return -1; - - bool Sign = Imm.extractBitsAsZExtValue(1, 63); - uint8_t Mantissa = Imm.extractBitsAsZExtValue(2, 50); - uint16_t Exp = Imm.extractBitsAsZExtValue(11, 52); - - auto EMI = llvm::lower_bound(LoadFP64ImmArr, std::make_pair(Exp, Mantissa)); - if (EMI == std::end(LoadFP64ImmArr) || EMI->first != Exp || +int RISCVLoadFPImm::getLoadFPImm(bool Sign, uint8_t Exp, uint8_t Mantissa) { + // Lookup in the table, ignoring the sign. + auto EMI = llvm::lower_bound(LoadFPImmArr, std::make_pair(Exp, Mantissa)); + if (EMI == std::end(LoadFPImmArr) || EMI->first != Exp || EMI->second != Mantissa) return -1; // Table doesn't have entry 0. - int Entry = std::distance(std::begin(LoadFP64ImmArr), EMI) + 1; + int Entry = std::distance(std::begin(LoadFPImmArr), EMI) + 1; // The only legal negative value is -1.0(entry 0). 1.0 is entry 16. if (Sign) { @@ -362,8 +259,8 @@ float RISCVLoadFPImm::getFPImm(unsigned Imm) { Imm = 16; } - uint32_t Exp = LoadFP32ImmArr[Imm - 1].first; - uint32_t Mantissa = LoadFP32ImmArr[Imm - 1].second; + uint32_t Exp = LoadFPImmArr[Imm - 1].first; + uint32_t Mantissa = LoadFPImmArr[Imm - 1].second; uint32_t I = Sign << 31 | Exp << 23 | Mantissa << 21; return bit_cast(I); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index 091a080..9b684a3 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -353,17 +353,67 @@ float getFPImm(unsigned Imm); /// getLoadFP32Imm - Return a 5-bit binary encoding of the 32-bit /// floating-point immediate value. If the value cannot be represented as a /// 5-bit binary encoding, then return -1. -int getLoadFP32Imm(const APFloat &FPImm); +static inline int getLoadFP32Imm(const APInt &Imm) { + if (Imm.extractBitsAsZExtValue(21, 0) != 0) + return -1; + + bool Sign = Imm.extractBitsAsZExtValue(1, 31); + uint8_t Exp = Imm.extractBitsAsZExtValue(8, 23); + uint8_t Mantissa = Imm.extractBitsAsZExtValue(2, 21); + return getLoadFPImm(Sign, Exp, Mantissa); +} + +static inline int getLoadFP32Imm(const APFloat &FPImm) { + return getLoadFP32Imm(FPImm.bitcastToAPInt()); +} /// getLoadFP64Imm - Return a 5-bit binary encoding of the 64-bit /// floating-point immediate value. If the value cannot be represented as a /// 5-bit binary encoding, then return -1. -int getLoadFP64Imm(const APFloat &FPImm); +static inline int getLoadFP64Imm(const APInt &Imm) { + if (Imm.extractBitsAsZExtValue(50, 0) != 0) + return -1; + + bool Sign = Imm.extractBitsAsZExtValue(1, 63); + uint8_t Mantissa = Imm.extractBitsAsZExtValue(2, 50); + uint8_t Exp; + if (Imm.extractBitsAsZExtValue(11, 52) == 1) + Exp = 0b00000001; + else if (Imm.extractBitsAsZExtValue(11, 52) == 2047) + Exp = 0b11111111; + else + Exp = Imm.extractBitsAsZExtValue(11, 52) - 1023 + 127; + + return getLoadFPImm(Sign, Exp, Mantissa); +} + +static inline int getLoadFP64Imm(const APFloat &FPImm) { + return getLoadFP64Imm(FPImm.bitcastToAPInt()); +} /// getLoadFP16Imm - Return a 5-bit binary encoding of the 16-bit /// floating-point immediate value. If the value cannot be represented as a /// 5-bit binary encoding, then return -1. -int getLoadFP16Imm(const APFloat &FPImm); +static inline int getLoadFP16Imm(const APInt &Imm) { + if (Imm.extractBitsAsZExtValue(8, 0) != 0) + return -1; + + bool Sign = Imm.extractBitsAsZExtValue(1, 15); + uint8_t Mantissa = Imm.extractBitsAsZExtValue(2, 8); + uint8_t Exp; + if (Imm.extractBitsAsZExtValue(5, 10) == 1) + Exp = 0b00000001; + else if (Imm.extractBitsAsZExtValue(5, 10) == 31) + Exp = 0b11111111; + else + Exp = Imm.extractBitsAsZExtValue(5, 10) - 15 + 127; + + return getLoadFPImm(Sign, Exp, Mantissa); +} + +static inline int getLoadFP16Imm(const APFloat &FPImm) { + return getLoadFP16Imm(FPImm.bitcastToAPInt()); +} } // namespace RISCVLoadFPImm namespace RISCVSysReg { diff --git a/llvm/test/CodeGen/RISCV/double-zfa.ll b/llvm/test/CodeGen/RISCV/double-zfa.ll index 4b5b1f7..427c5b5 100644 --- a/llvm/test/CodeGen/RISCV/double-zfa.ll +++ b/llvm/test/CodeGen/RISCV/double-zfa.ll @@ -78,11 +78,11 @@ define double @loadfpimm9() { } ; Negative test. This is 1 * 2^256. +; FIXME: This should not use fli.d define double @loadfpimm10() { ; CHECK-LABEL: loadfpimm10: ; CHECK: # %bb.0: -; CHECK-NEXT: lui a0, %hi(.LCPI9_0) -; CHECK-NEXT: fld fa0, %lo(.LCPI9_0)(a0) +; CHECK-NEXT: fli.d fa0, 2.0 ; CHECK-NEXT: ret ret double 0x1000000000000000 } diff --git a/llvm/test/CodeGen/RISCV/half-zfa-fli.ll b/llvm/test/CodeGen/RISCV/half-zfa-fli.ll index 7899fdb..500c74c 100644 --- a/llvm/test/CodeGen/RISCV/half-zfa-fli.ll +++ b/llvm/test/CodeGen/RISCV/half-zfa-fli.ll @@ -136,10 +136,12 @@ define half @loadfpimm9() { } ; This is 1 * 2^-16 +; FIXME: this should use fli.h define half @loadfpimm10() { ; CHECK-LABEL: loadfpimm10: ; CHECK: # %bb.0: -; CHECK-NEXT: fli.h fa0, 3.0517578125e-05 +; CHECK-NEXT: li a0, 256 +; CHECK-NEXT: fmv.h.x fa0, a0 ; CHECK-NEXT: ret ; ; ZFHMIN-LABEL: loadfpimm10: @@ -151,10 +153,12 @@ define half @loadfpimm10() { } ; This is 1 * 2^-15 +; FIXME: This should use fli.h define half @loadfpimm11() { ; CHECK-LABEL: loadfpimm11: ; CHECK: # %bb.0: -; CHECK-NEXT: fli.h fa0, 1.52587890625e-05 +; CHECK-NEXT: li a0, 512 +; CHECK-NEXT: fmv.h.x fa0, a0 ; CHECK-NEXT: ret ; ; ZFHMIN-LABEL: loadfpimm11: -- 2.7.4