From 73516b355c623baa7cd9c5be8ce672b3621e0652 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 8 Mar 2023 09:10:31 -0800 Subject: [PATCH] [RISCV] Don't parse the decimal minimum value for fli.s/fli.d/fli.h. There are a couple bugs in the current support for this: -We do all the parsing in single precision so any value less than or equal to the minimum fp32 is accepted as the minimum value for f64. -To support fp16 minimum value, getLoadFP32Imm has a special case, but that causes a miscompile in CodeGen. Differential Revision: https://reviews.llvm.org/D145542 --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 8 +++++-- llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 5 ----- llvm/test/CodeGen/RISCV/float-zfa.ll | 5 +++-- llvm/test/MC/RISCV/zfa-invalid.s | 26 ++++++++++++++++++++++ llvm/test/MC/RISCV/zfa-valid.s | 15 ------------- 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index b2f7092..4a472e9 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -494,8 +494,12 @@ public: bool isLoadFPImm() const { if (isImm()) return isUImm5(); - return Kind == KindTy::FPImmediate && - RISCVLoadFPImm::getLoadFP32Imm(APInt(32, getFPConst())) != -1; + if (Kind != KindTy::FPImmediate) + return false; + int Idx = RISCVLoadFPImm::getLoadFP32Imm(APInt(32, 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; } bool isImmXLenLI() const { diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index ac7fe95..22b6a73 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -398,11 +398,6 @@ inline static uint32_t getFPImm(unsigned Imm) { /// floating-point immediate value. If the value cannot be represented as a /// 5-bit binary encoding, then return -1. static inline int getLoadFP32Imm(const APInt &Imm) { - if ((Imm.extractBitsAsZExtValue(9, 23) == 0b001110001 && - Imm.extractBitsAsZExtValue(23, 0) == 0) || - Imm.extractBitsAsZExtValue(32, 0) == 0) - return 1; - if (Imm.extractBitsAsZExtValue(20, 0) != 0) return -1; diff --git a/llvm/test/CodeGen/RISCV/float-zfa.ll b/llvm/test/CodeGen/RISCV/float-zfa.ll index 7700f57..ab85ad0 100644 --- a/llvm/test/CodeGen/RISCV/float-zfa.ll +++ b/llvm/test/CodeGen/RISCV/float-zfa.ll @@ -77,11 +77,12 @@ define float @loadfpimm9() { ret float 255.0 } -; FIXME: This is the f16 minimum value. It should not be supported for f32. +; This is the f16 minimum value. Make sure we don't use fli.s. define float @loadfpimm10() { ; CHECK-LABEL: loadfpimm10: ; CHECK: # %bb.0: -; CHECK-NEXT: fli.s fa0, min +; CHECK-NEXT: lui a0, 231424 +; CHECK-NEXT: fmv.w.x fa0, a0 ; CHECK-NEXT: ret ret float 0.00006103515625 } diff --git a/llvm/test/MC/RISCV/zfa-invalid.s b/llvm/test/MC/RISCV/zfa-invalid.s index 0263d61..f565c96 100644 --- a/llvm/test/MC/RISCV/zfa-invalid.s +++ b/llvm/test/MC/RISCV/zfa-invalid.s @@ -46,3 +46,29 @@ fli.s ft1, -inf # CHECK-NO-RV64: error: invalid floating point immediate # CHECK-NO-RV32: error: invalid floating point immediate fli.s ft1, -nan + +# Don't accept decimal minimum. +# CHECK-NO-RV64: error: operand must be a valid floating-point constant +# CHECK-NO-RV32: error: operand must be a valid floating-point constant +fli.s ft1, 1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625e-38 + +# Don't accept decimal minimum. +# CHECK-NO-RV64: error: operand must be a valid floating-point constant +# CHECK-NO-RV32: error: operand must be a valid floating-point constant +fli.d ft1, 2.225073858507201383090232717332404064219215980462331830553327416887204434813918195854283159012511020564067339731035811005152434161553460108856012385377718821130777993532002330479610147442583636071921565046942503734208375250806650616658158948720491179968591639648500635908770118304874799780887753749949451580451605050915399856582470818645113537935804992115981085766051992433352114352390148795699609591288891602992641511063466313393663477586513029371762047325631781485664350872122828637642044846811407613911477062801689853244110024161447421618567166150540154285084716752901903161322778896729707373123334086988983175067838846926092773977972858659654941091369095406136467568702398678315290680984617210924625396728515625e-308 + +# Don't accept decimal minimum. +# CHECK-NO-RV64: error: operand must be a valid floating-point constant +# CHECK-NO-RV32: error: operand must be a valid floating-point constant +fli.h ft1, 6.103516e-05 + +# Don't accept single precision minimum for double. +# CHECK-NO-RV64: error: operand must be a valid floating-point constant +# CHECK-NO-RV32: error: operand must be a valid floating-point constant +fli.d ft1, 1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625e-38 + +# Don't accept single precision minimum for half. +# CHECK-NO-RV64: error: operand must be a valid floating-point constant +# CHECK-NO-RV32: error: operand must be a valid floating-point constant +fli.h ft1, 1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625e-38 + diff --git a/llvm/test/MC/RISCV/zfa-valid.s b/llvm/test/MC/RISCV/zfa-valid.s index 4324992..21d5d92 100644 --- a/llvm/test/MC/RISCV/zfa-valid.s +++ b/llvm/test/MC/RISCV/zfa-valid.s @@ -24,11 +24,6 @@ fli.s ft1, -1.000000e+00 # CHECK-ASM-AND-OBJ: fli.s ft1, min # CHECK-ASM: encoding: [0xd3,0x80,0x10,0xf0] # CHECK-NO-EXT: error: instruction requires the following: 'Zfa' (Additional Floating-Point){{$}} -fli.s ft1, 1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625e-38 - -# CHECK-ASM-AND-OBJ: fli.s ft1, min -# CHECK-ASM: encoding: [0xd3,0x80,0x10,0xf0] -# CHECK-NO-EXT: error: instruction requires the following: 'Zfa' (Additional Floating-Point){{$}} fli.s ft1, min # CHECK-ASM-AND-OBJ: fli.s ft1, 1.525879e-05 @@ -194,11 +189,6 @@ fli.d ft1, -1.000000e+00 # CHECK-ASM-AND-OBJ: fli.d ft1, min # CHECK-ASM: encoding: [0xd3,0x80,0x10,0xf2] # CHECK-NO-EXT: error: instruction requires the following: 'Zfa' (Additional Floating-Point){{$}} -fli.d ft1, 2.225073858507201383090232717332404064219215980462331830553327416887204434813918195854283159012511020564067339731035811005152434161553460108856012385377718821130777993532002330479610147442583636071921565046942503734208375250806650616658158948720491179968591639648500635908770118304874799780887753749949451580451605050915399856582470818645113537935804992115981085766051992433352114352390148795699609591288891602992641511063466313393663477586513029371762047325631781485664350872122828637642044846811407613911477062801689853244110024161447421618567166150540154285084716752901903161322778896729707373123334086988983175067838846926092773977972858659654941091369095406136467568702398678315290680984617210924625396728515625e-308 - -# CHECK-ASM-AND-OBJ: fli.d ft1, min -# CHECK-ASM: encoding: [0xd3,0x80,0x10,0xf2] -# CHECK-NO-EXT: error: instruction requires the following: 'Zfa' (Additional Floating-Point){{$}} fli.d ft1, min # CHECK-ASM-AND-OBJ: fli.d ft1, 1.525879e-05 @@ -369,11 +359,6 @@ fli.h ft1, -1.000000e+00 # CHECK-ASM-AND-OBJ: fli.h ft1, min # CHECK-ASM: encoding: [0xd3,0x80,0x10,0xf4] # CHECK-NO-EXT: error: instruction requires the following: 'Zfa' (Additional Floating-Point){{$}} -fli.h ft1, 6.103516e-05 - -# CHECK-ASM-AND-OBJ: fli.h ft1, min -# CHECK-ASM: encoding: [0xd3,0x80,0x10,0xf4] -# CHECK-NO-EXT: error: instruction requires the following: 'Zfa' (Additional Floating-Point){{$}} fli.h ft1, min # CHECK-ASM-AND-OBJ: fli.h ft1, 1.525879e-05 -- 2.7.4