[llvm] bf94ba3 - [RISCV][MC] Fix all remaining fcvt instructions that didn't accept rounding mode but should have (#67889)

via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 1 01:59:56 PDT 2023


Author: Alex Bradbury
Date: 2023-10-01T09:59:52+01:00
New Revision: bf94ba39b65d1212ea84d5783b393280e1ce7478

URL: https://github.com/llvm/llvm-project/commit/bf94ba39b65d1212ea84d5783b393280e1ce7478
DIFF: https://github.com/llvm/llvm-project/commit/bf94ba39b65d1212ea84d5783b393280e1ce7478.diff

LOG: [RISCV][MC] Fix all remaining fcvt instructions that didn't accept rounding mode but should have (#67889)

This is a follow-up to #67555, performing the same fix for the other
instructions that had this issue:
* fcvt.d.w
* fcvt.d.wu
* fcvt.s.h
* fcvt.d.h

As before, we stick to the 'rne' default because this gives maximum
compatibility with older LLVM and GNU tools when disassembling. I've
also double checked disassembling fp-default-rounding-mode.s with GNU
objdump to re-confirm it uses frm=0b000 for these instructions.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVInstrInfoD.td
    llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
    llvm/test/MC/RISCV/fp-default-rounding-mode.s
    llvm/test/MC/RISCV/fp-inx-default-rounding-mode.s
    llvm/test/MC/RISCV/rv32d-valid.s
    llvm/test/MC/RISCV/rv32zdinx-valid.s
    llvm/test/MC/RISCV/rv32zfhmin-valid.s
    llvm/test/MC/RISCV/rv32zhinxmin-valid.s
    llvm/test/MC/RISCV/rv64zhinxmin-valid.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
index 8911e18f09b4ea2..aeb9ebc56a975e0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
@@ -140,12 +140,12 @@ foreach Ext = DExts in {
                                      "fcvt.wu.d">,
                    Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>;
 
-  defm FCVT_D_W : FPUnaryOp_r_m<0b1101001, 0b00000, 0b000, Ext, Ext.PrimaryTy, GPR,
-                                "fcvt.d.w">,
+  defm FCVT_D_W : FPUnaryOp_r_frmlegacy_m<0b1101001, 0b00000, Ext, Ext.PrimaryTy, GPR,
+                                          "fcvt.d.w">,
                   Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
 
-  defm FCVT_D_WU : FPUnaryOp_r_m<0b1101001, 0b00001, 0b000, Ext, Ext.PrimaryTy, GPR,
-                                 "fcvt.d.wu">,
+  defm FCVT_D_WU : FPUnaryOp_r_frmlegacy_m<0b1101001, 0b00001, Ext, Ext.PrimaryTy, GPR,
+                                           "fcvt.d.wu">,
                    Sched<[WriteFCvtI32ToF64, ReadFCvtI32ToF64]>;
 } // foreach Ext = DExts
 
@@ -555,8 +555,8 @@ def : Pat<(i32 (any_lrint FPR64:$rs1)), (FCVT_W_D $rs1, FRM_DYN)>;
 def : Pat<(i32 (any_lround FPR64:$rs1)), (FCVT_W_D $rs1, FRM_RMM)>;
 
 // [u]int->double.
-def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_D_W GPR:$rs1)>;
-def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_D_WU GPR:$rs1)>;
+def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_D_W GPR:$rs1, FRM_RNE)>;
+def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_D_WU GPR:$rs1, FRM_RNE)>;
 } // Predicates = [HasStdExtD, IsRV32]
 
 let Predicates = [HasStdExtZdinx, IsRV32] in {
@@ -576,8 +576,8 @@ def : Pat<(i32 (any_lrint FPR64IN32X:$rs1)), (FCVT_W_D_IN32X $rs1, FRM_DYN)>;
 def : Pat<(i32 (any_lround FPR64IN32X:$rs1)), (FCVT_W_D_IN32X $rs1, FRM_RMM)>;
 
 // [u]int->double.
-def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_D_W_IN32X GPR:$rs1)>;
-def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_D_WU_IN32X GPR:$rs1)>;
+def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_D_W_IN32X GPR:$rs1, FRM_RNE)>;
+def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_D_WU_IN32X GPR:$rs1, FRM_RNE)>;
 } // Predicates = [HasStdExtZdinx, IsRV32]
 
 let Predicates = [HasStdExtD, IsRV64] in {
@@ -593,8 +593,8 @@ def : Pat<(riscv_any_fcvt_w_rv64 FPR64:$rs1, timm:$frm),  (FCVT_W_D $rs1, timm:$
 def : Pat<(riscv_any_fcvt_wu_rv64 FPR64:$rs1, timm:$frm), (FCVT_WU_D $rs1, timm:$frm)>;
 
 // [u]int32->fp
-def : Pat<(any_sint_to_fp (i64 (sexti32 (i64 GPR:$rs1)))), (FCVT_D_W $rs1)>;
-def : Pat<(any_uint_to_fp (i64 (zexti32 (i64 GPR:$rs1)))), (FCVT_D_WU $rs1)>;
+def : Pat<(any_sint_to_fp (i64 (sexti32 (i64 GPR:$rs1)))), (FCVT_D_W $rs1, FRM_RNE)>;
+def : Pat<(any_uint_to_fp (i64 (zexti32 (i64 GPR:$rs1)))), (FCVT_D_WU $rs1, FRM_RNE)>;
 
 // Saturating double->[u]int64.
 def : Pat<(i64 (riscv_fcvt_x FPR64:$rs1, timm:$frm)), (FCVT_L_D $rs1, timm:$frm)>;
@@ -630,8 +630,8 @@ def : Pat<(riscv_any_fcvt_w_rv64 FPR64INX:$rs1, timm:$frm),  (FCVT_W_D_INX $rs1,
 def : Pat<(riscv_any_fcvt_wu_rv64 FPR64INX:$rs1, timm:$frm), (FCVT_WU_D_INX $rs1, timm:$frm)>;
 
 // [u]int32->fp
-def : Pat<(any_sint_to_fp (i64 (sexti32 (i64 GPR:$rs1)))), (FCVT_D_W_INX $rs1)>;
-def : Pat<(any_uint_to_fp (i64 (zexti32 (i64 GPR:$rs1)))), (FCVT_D_WU_INX $rs1)>;
+def : Pat<(any_sint_to_fp (i64 (sexti32 (i64 GPR:$rs1)))), (FCVT_D_W_INX $rs1, FRM_RNE)>;
+def : Pat<(any_uint_to_fp (i64 (zexti32 (i64 GPR:$rs1)))), (FCVT_D_WU_INX $rs1, FRM_RNE)>;
 
 // Saturating double->[u]int64.
 def : Pat<(i64 (riscv_fcvt_x FPR64INX:$rs1, timm:$frm)), (FCVT_L_D_INX $rs1, timm:$frm)>;

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
index f2dc2200fea3887..c53462a74f36264 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
@@ -142,8 +142,8 @@ foreach Ext = ZfhminExts in {
                                     Ext.F32Ty, "fcvt.h.s">,
                   Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
 
-  defm FCVT_S_H : FPUnaryOp_r_m<0b0100000, 0b00010, 0b000, Ext, Ext.F32Ty,
-                                Ext.PrimaryTy, "fcvt.s.h">,
+  defm FCVT_S_H : FPUnaryOp_r_frmlegacy_m<0b0100000, 0b00010,Ext, Ext.F32Ty,
+                                          Ext.PrimaryTy, "fcvt.s.h">,
                  Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>;
 } // foreach Ext = ZfhminExts
 
@@ -191,8 +191,8 @@ foreach Ext = ZfhminDExts in {
                                    Ext.F64Ty, "fcvt.h.d">,
                   Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]>;
 
-  defm FCVT_D_H : FPUnaryOp_r_m<0b0100001, 0b00010, 0b000, Ext, Ext.F64Ty,
-                                Ext.F16Ty, "fcvt.d.h">,
+  defm FCVT_D_H : FPUnaryOp_r_frmlegacy_m<0b0100001, 0b00010, Ext, Ext.F64Ty,
+                                          Ext.F16Ty, "fcvt.d.h">,
                   Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]>;
 } // foreach Ext = ZfhminDExts
 
@@ -439,14 +439,14 @@ let Predicates = [HasStdExtZfhOrZfhmin] in {
 
 // f32 -> f16, f16 -> f32
 def : Pat<(f16 (any_fpround FPR32:$rs1)), (FCVT_H_S FPR32:$rs1, FRM_DYN)>;
-def : Pat<(any_fpextend (f16 FPR16:$rs1)), (FCVT_S_H FPR16:$rs1)>;
+def : Pat<(any_fpextend (f16 FPR16:$rs1)), (FCVT_S_H FPR16:$rs1, FRM_RNE)>;
 
 // Moves (no conversion)
 def : Pat<(f16 (riscv_fmv_h_x GPR:$src)), (FMV_H_X GPR:$src)>;
 def : Pat<(riscv_fmv_x_anyexth (f16 FPR16:$src)), (FMV_X_H FPR16:$src)>;
 def : Pat<(riscv_fmv_x_signexth (f16 FPR16:$src)), (FMV_X_H FPR16:$src)>;
 
-def : Pat<(fcopysign FPR32:$rs1, (f16 FPR16:$rs2)), (FSGNJ_S $rs1, (FCVT_S_H $rs2))>;
+def : Pat<(fcopysign FPR32:$rs1, (f16 FPR16:$rs2)), (FSGNJ_S $rs1, (FCVT_S_H $rs2, FRM_RNE))>;
 } // Predicates = [HasStdExtZfhOrZfhmin]
 
 let Predicates = [HasStdExtZhinxOrZhinxmin] in {
@@ -454,14 +454,14 @@ let Predicates = [HasStdExtZhinxOrZhinxmin] in {
 
 // f32 -> f16, f16 -> f32
 def : Pat<(any_fpround FPR32INX:$rs1), (FCVT_H_S_INX FPR32INX:$rs1, FRM_DYN)>;
-def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_S_H_INX FPR16INX:$rs1)>;
+def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_S_H_INX FPR16INX:$rs1, FRM_RNE)>;
 
 // Moves (no conversion)
 def : Pat<(f16 (riscv_fmv_h_x GPR:$src)), (COPY_TO_REGCLASS GPR:$src, GPR)>;
 def : Pat<(riscv_fmv_x_anyexth FPR16INX:$src), (COPY_TO_REGCLASS FPR16INX:$src, GPR)>;
 def : Pat<(riscv_fmv_x_signexth FPR16INX:$src), (COPY_TO_REGCLASS FPR16INX:$src, GPR)>;
 
-def : Pat<(fcopysign FPR32INX:$rs1, FPR16INX:$rs2), (FSGNJ_S_INX $rs1, (FCVT_S_H_INX $rs2))>;
+def : Pat<(fcopysign FPR32INX:$rs1, FPR16INX:$rs2), (FSGNJ_S_INX $rs1, (FCVT_S_H_INX $rs2, FRM_RNE))>;
 } // Predicates = [HasStdExtZhinxOrZhinxmin]
 
 let Predicates = [HasStdExtZfh, IsRV32] in {
@@ -568,48 +568,48 @@ let Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD] in {
 /// Float conversion operations
 // f64 -> f16, f16 -> f64
 def : Pat<(f16 (any_fpround FPR64:$rs1)), (FCVT_H_D FPR64:$rs1, FRM_DYN)>;
-def : Pat<(any_fpextend (f16 FPR16:$rs1)), (FCVT_D_H FPR16:$rs1)>;
+def : Pat<(any_fpextend (f16 FPR16:$rs1)), (FCVT_D_H FPR16:$rs1, FRM_RNE)>;
 
 /// Float arithmetic operations
 def : Pat<(f16 (fcopysign FPR16:$rs1, FPR64:$rs2)),
           (FSGNJ_H $rs1, (FCVT_H_D $rs2, FRM_DYN))>;
-def : Pat<(fcopysign FPR64:$rs1, (f16 FPR16:$rs2)), (FSGNJ_D $rs1, (FCVT_D_H $rs2))>;
+def : Pat<(fcopysign FPR64:$rs1, (f16 FPR16:$rs2)), (FSGNJ_D $rs1, (FCVT_D_H $rs2, FRM_RNE))>;
 } // Predicates = [HasStdExtZfhOrZfhmin, HasStdExtD]
 
 let Predicates = [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV32] in {
 /// Float conversion operations
 // f64 -> f16, f16 -> f64
 def : Pat<(any_fpround FPR64IN32X:$rs1), (FCVT_H_D_IN32X FPR64IN32X:$rs1, FRM_DYN)>;
-def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_D_H_IN32X FPR16INX:$rs1)>;
+def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_D_H_IN32X FPR16INX:$rs1, FRM_RNE)>;
 
 /// Float arithmetic operations
 def : Pat<(fcopysign FPR16INX:$rs1, FPR64IN32X:$rs2),
           (FSGNJ_H_INX $rs1, (FCVT_H_D_IN32X $rs2, 0b111))>;
-def : Pat<(fcopysign FPR64IN32X:$rs1, FPR16INX:$rs2), (FSGNJ_D_IN32X $rs1, (FCVT_D_H_IN32X $rs2))>;
+def : Pat<(fcopysign FPR64IN32X:$rs1, FPR16INX:$rs2), (FSGNJ_D_IN32X $rs1, (FCVT_D_H_IN32X $rs2, FRM_RNE))>;
 } // Predicates = [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV32]
 
 let Predicates = [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV64] in {
 /// Float conversion operations
 // f64 -> f16, f16 -> f64
 def : Pat<(any_fpround FPR64INX:$rs1), (FCVT_H_D_INX FPR64INX:$rs1, FRM_DYN)>;
-def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_D_H_INX FPR16INX:$rs1)>;
+def : Pat<(any_fpextend FPR16INX:$rs1), (FCVT_D_H_INX FPR16INX:$rs1, FRM_RNE)>;
 
 /// Float arithmetic operations
 def : Pat<(fcopysign FPR16INX:$rs1, FPR64INX:$rs2),
           (FSGNJ_H_INX $rs1, (FCVT_H_D_INX $rs2, 0b111))>;
-def : Pat<(fcopysign FPR64INX:$rs1, FPR16INX:$rs2), (FSGNJ_D_INX $rs1, (FCVT_D_H_INX $rs2))>;
+def : Pat<(fcopysign FPR64INX:$rs1, FPR16INX:$rs2), (FSGNJ_D_INX $rs1, (FCVT_D_H_INX $rs2, FRM_RNE))>;
 } // Predicates = [HasStdExtZhinxOrZhinxmin, HasStdExtZdinx, IsRV64]
 
 let Predicates = [HasStdExtZfhmin, NoStdExtZfh, IsRV32] in {
 // half->[u]int. Round-to-zero must be used.
-def : Pat<(i32 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_H $rs1), FRM_RTZ)>;
-def : Pat<(i32 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_WU_S (FCVT_S_H $rs1), FRM_RTZ)>;
+def : Pat<(i32 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_H $rs1, FRM_RNE), FRM_RTZ)>;
+def : Pat<(i32 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_WU_S (FCVT_S_H $rs1, FRM_RNE), FRM_RTZ)>;
 
 // half->int32 with current rounding mode.
-def : Pat<(i32 (any_lrint (f16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_H $rs1), FRM_DYN)>;
+def : Pat<(i32 (any_lrint (f16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_H $rs1, FRM_RNE), FRM_DYN)>;
 
 // half->int32 rounded to nearest with ties rounded away from zero.
-def : Pat<(i32 (any_lround (f16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_H $rs1), FRM_RMM)>;
+def : Pat<(i32 (any_lround (f16 FPR16:$rs1))), (FCVT_W_S (FCVT_S_H $rs1, FRM_RNE), FRM_RMM)>;
 
 // [u]int->half. Match GCC and default to using dynamic rounding mode.
 def : Pat<(f16 (any_sint_to_fp (i32 GPR:$rs1))), (FCVT_H_S (FCVT_S_W $rs1, FRM_DYN), FRM_DYN)>;
@@ -618,14 +618,14 @@ def : Pat<(f16 (any_uint_to_fp (i32 GPR:$rs1))), (FCVT_H_S (FCVT_S_WU $rs1, FRM_
 
 let Predicates = [HasStdExtZhinxmin, NoStdExtZhinx, IsRV32] in {
 // half->[u]int. Round-to-zero must be used.
-def : Pat<(i32 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_W_S_INX (FCVT_S_H_INX $rs1), FRM_RTZ)>;
-def : Pat<(i32 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_WU_S_INX (FCVT_S_H_INX $rs1), FRM_RTZ)>;
+def : Pat<(i32 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_W_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RTZ)>;
+def : Pat<(i32 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_WU_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RTZ)>;
 
 // half->int32 with current rounding mode.
-def : Pat<(i32 (any_lrint FPR16INX:$rs1)), (FCVT_W_S_INX (FCVT_S_H_INX $rs1), FRM_DYN)>;
+def : Pat<(i32 (any_lrint FPR16INX:$rs1)), (FCVT_W_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_DYN)>;
 
 // half->int32 rounded to nearest with ties rounded away from zero.
-def : Pat<(i32 (any_lround FPR16INX:$rs1)), (FCVT_W_S_INX (FCVT_S_H_INX $rs1), FRM_RMM)>;
+def : Pat<(i32 (any_lround FPR16INX:$rs1)), (FCVT_W_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RMM)>;
 
 // [u]int->half. Match GCC and default to using dynamic rounding mode.
 def : Pat<(any_sint_to_fp (i32 GPR:$rs1)), (FCVT_H_S_INX (FCVT_S_W_INX $rs1, FRM_DYN), FRM_DYN)>;
@@ -634,16 +634,16 @@ def : Pat<(any_uint_to_fp (i32 GPR:$rs1)), (FCVT_H_S_INX (FCVT_S_WU_INX $rs1, FR
 
 let Predicates = [HasStdExtZfhmin, NoStdExtZfh, IsRV64] in {
 // half->[u]int64. Round-to-zero must be used.
-def : Pat<(i64 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1), FRM_RTZ)>;
-def : Pat<(i64 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_LU_S (FCVT_S_H $rs1), FRM_RTZ)>;
+def : Pat<(i64 (any_fp_to_sint (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_RTZ)>;
+def : Pat<(i64 (any_fp_to_uint (f16 FPR16:$rs1))), (FCVT_LU_S (FCVT_S_H $rs1, FRM_RNE), FRM_RTZ)>;
 
 // half->int64 with current rounding mode.
-def : Pat<(i64 (any_lrint (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1), FRM_DYN)>;
-def : Pat<(i64 (any_llrint (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1), FRM_DYN)>;
+def : Pat<(i64 (any_lrint (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_DYN)>;
+def : Pat<(i64 (any_llrint (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_DYN)>;
 
 // half->int64 rounded to nearest with ties rounded away from zero.
-def : Pat<(i64 (any_lround (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1), FRM_RMM)>;
-def : Pat<(i64 (any_llround (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1), FRM_RMM)>;
+def : Pat<(i64 (any_lround (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_RMM)>;
+def : Pat<(i64 (any_llround (f16 FPR16:$rs1))), (FCVT_L_S (FCVT_S_H $rs1, FRM_RNE), FRM_RMM)>;
 
 // [u]int->fp. Match GCC and default to using dynamic rounding mode.
 def : Pat<(f16 (any_sint_to_fp (i64 GPR:$rs1))), (FCVT_H_S (FCVT_S_L $rs1, FRM_DYN), FRM_DYN)>;
@@ -652,16 +652,16 @@ def : Pat<(f16 (any_uint_to_fp (i64 GPR:$rs1))), (FCVT_H_S (FCVT_S_LU $rs1, FRM_
 
 let Predicates = [HasStdExtZhinxmin, NoStdExtZhinx, IsRV64] in {
 // half->[u]int64. Round-to-zero must be used.
-def : Pat<(i64 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1), FRM_RTZ)>;
-def : Pat<(i64 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_LU_S_INX (FCVT_S_H_INX $rs1), FRM_RTZ)>;
+def : Pat<(i64 (any_fp_to_sint FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RTZ)>;
+def : Pat<(i64 (any_fp_to_uint FPR16INX:$rs1)), (FCVT_LU_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RTZ)>;
 
 // half->int64 with current rounding mode.
-def : Pat<(i64 (any_lrint FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1), FRM_DYN)>;
-def : Pat<(i64 (any_llrint FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1), FRM_DYN)>;
+def : Pat<(i64 (any_lrint FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_DYN)>;
+def : Pat<(i64 (any_llrint FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_DYN)>;
 
 // half->int64 rounded to nearest with ties rounded away from zero.
-def : Pat<(i64 (any_lround FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1), FRM_RMM)>;
-def : Pat<(i64 (any_llround FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1), FRM_RMM)>;
+def : Pat<(i64 (any_lround FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RMM)>;
+def : Pat<(i64 (any_llround FPR16INX:$rs1)), (FCVT_L_S_INX (FCVT_S_H_INX $rs1, FRM_RNE), FRM_RMM)>;
 
 // [u]int->fp. Match GCC and default to using dynamic rounding mode.
 def : Pat<(any_sint_to_fp (i64 GPR:$rs1)), (FCVT_H_S_INX (FCVT_S_L_INX $rs1, FRM_DYN), FRM_DYN)>;

diff  --git a/llvm/test/MC/RISCV/fp-default-rounding-mode.s b/llvm/test/MC/RISCV/fp-default-rounding-mode.s
index dfd45980a8935cb..9e3aff12d909ddb 100644
--- a/llvm/test/MC/RISCV/fp-default-rounding-mode.s
+++ b/llvm/test/MC/RISCV/fp-default-rounding-mode.s
@@ -89,15 +89,23 @@ fcvt.w.d a0, fa0
 # CHECK-ALIAS: fcvt.wu.d a0, fa0{{$}}
 fcvt.wu.d a0, fa0
 
-# FIXME: fcvt.d.w should have a default rounding mode.
+# For historical reasons defaults to frm==0b000 (rne) but doesn't print this
+# default rounding mode.
 # CHECK-INST: fcvt.d.w fa0, a0{{$}}
 # CHECK-ALIAS: fcvt.d.w fa0, a0{{$}}
 fcvt.d.w fa0, a0
+# CHECK-INST: fcvt.d.w fa0, a0{{$}}
+# CHECK-ALIAS: fcvt.d.w fa0, a0{{$}}
+fcvt.d.w fa0, a0, rne
 
-# FIXME: fcvt.d.wu should have a default rounding mode.
+# For historical reasons defaults to frm==0b000 (rne) but doesn't print this
+# default rounding mode.
 # CHECK-INST: fcvt.d.wu fa0, a0{{$}}
 # CHECK-ALIAS: fcvt.d.wu fa0, a0{{$}}
 fcvt.d.wu fa0, a0
+# CHECK-INST: fcvt.d.wu fa0, a0{{$}}
+# CHECK-ALIAS: fcvt.d.wu fa0, a0{{$}}
+fcvt.d.wu fa0, a0, rne
 
 # CHECK-INST: fcvt.l.d a0, fa0, dyn{{$}}
 # CHECK-ALIAS: fcvt.l.d a0, fa0{{$}}
@@ -125,19 +133,27 @@ fmadd.h fa0, fa1, fa2, fa3
 # CHECK-ALIAS: fadd.h fa0, fa1, fa2{{$}}
 fadd.h fa0, fa1, fa2
 
-# FIXME: fcvt.s.h should have a default rounding mode.
+# For historical reasons defaults to frm==0b000 (rne) but doesn't print this
+# default rounding mode.
 # CHECK-INST: fcvt.s.h fa0, fa0{{$}}
 # CHECK-ALIAS: fcvt.s.h fa0, fa0{{$}}
 fcvt.s.h fa0, fa0
+# CHECK-INST: fcvt.s.h fa0, fa0{{$}}
+# CHECK-ALIAS: fcvt.s.h fa0, fa0{{$}}
+fcvt.s.h fa0, fa0, rne
 
 # CHECK-INST: fcvt.h.s fa0, fa0, dyn{{$}}
 # CHECK-ALIAS: fcvt.h.s fa0, fa0{{$}}
 fcvt.h.s fa0, fa0
 
-# FIXME: fcvt.d.h should have a default rounding mode.
+# For historical reasons defaults to frm==0b000 (rne) but doesn't print this
+# default rounding mode.
 # CHECK-INST: fcvt.d.h fa0, fa0{{$}}
 # CHECK-ALIAS: fcvt.d.h fa0, fa0{{$}}
 fcvt.d.h fa0, fa0
+# CHECK-INST: fcvt.d.h fa0, fa0{{$}}
+# CHECK-ALIAS: fcvt.d.h fa0, fa0{{$}}
+fcvt.d.h fa0, fa0, rne
 
 # CHECK-INST: fcvt.h.d fa0, fa0, dyn{{$}}
 # CHECK-ALIAS: fcvt.h.d fa0, fa0{{$}}

diff  --git a/llvm/test/MC/RISCV/fp-inx-default-rounding-mode.s b/llvm/test/MC/RISCV/fp-inx-default-rounding-mode.s
index 06b654e98992ae5..d2764ce2ad21712 100644
--- a/llvm/test/MC/RISCV/fp-inx-default-rounding-mode.s
+++ b/llvm/test/MC/RISCV/fp-inx-default-rounding-mode.s
@@ -92,15 +92,23 @@ fcvt.w.d a0, a0
 # CHECK-ALIAS: fcvt.wu.d a0, a0{{$}}
 fcvt.wu.d a0, a0
 
-# FIXME: fcvt.d.w should have a default rounding mode.
+# For historical reasons defaults to frm==0b000 (rne) but doesn't print this
+# default rounding mode.
 # CHECK-INST: fcvt.d.w a0, a0{{$}}
 # CHECK-ALIAS: fcvt.d.w a0, a0{{$}}
 fcvt.d.w a0, a0
+# CHECK-INST: fcvt.d.w a0, a0{{$}}
+# CHECK-ALIAS: fcvt.d.w a0, a0{{$}}
+fcvt.d.w a0, a0, rne
 
-# FIXME: fcvt.d.wu should have a default rounding mode.
+# For historical reasons defaults to frm==0b000 (rne) but doesn't print this
+# default rounding mode.
 # CHECK-INST: fcvt.d.wu a0, a0{{$}}
 # CHECK-ALIAS: fcvt.d.wu a0, a0{{$}}
 fcvt.d.wu a0, a0
+# CHECK-INST: fcvt.d.wu a0, a0{{$}}
+# CHECK-ALIAS: fcvt.d.wu a0, a0{{$}}
+fcvt.d.wu a0, a0, rne
 
 # CHECK-INST: fcvt.l.d a0, a0, dyn{{$}}
 # CHECK-ALIAS: fcvt.l.d a0, a0{{$}}
@@ -128,19 +136,27 @@ fmadd.h a0, a1, a2, a3
 # CHECK-ALIAS: fadd.h a0, a1, a2{{$}}
 fadd.h a0, a1, a2
 
-# FIXME: fcvt.s.h should have a default rounding mode.
+# For historical reasons defaults to frm==0b000 (rne) but doesn't print this
+# default rounding mode.
 # CHECK-INST: fcvt.s.h a0, a0{{$}}
 # CHECK-ALIAS: fcvt.s.h a0, a0{{$}}
 fcvt.s.h a0, a0
+# CHECK-INST: fcvt.s.h a0, a0{{$}}
+# CHECK-ALIAS: fcvt.s.h a0, a0{{$}}
+fcvt.s.h a0, a0, rne
 
 # CHECK-INST: fcvt.h.s a0, a0, dyn{{$}}
 # CHECK-ALIAS: fcvt.h.s a0, a0{{$}}
 fcvt.h.s a0, a0
 
-# FIXME: fcvt.d.h should have a default rounding mode.
+# For historical reasons defaults to frm==0b000 (rne) but doesn't print this
+# default rounding mode.
 # CHECK-INST: fcvt.d.h a0, a0{{$}}
 # CHECK-ALIAS: fcvt.d.h a0, a0{{$}}
 fcvt.d.h a0, a0
+# CHECK-INST: fcvt.d.h a0, a0{{$}}
+# CHECK-ALIAS: fcvt.d.h a0, a0{{$}}
+fcvt.d.h a0, a0, rne
 
 # CHECK-INST: fcvt.h.d a0, a0, dyn{{$}}
 # CHECK-ALIAS: fcvt.h.d a0, a0{{$}}

diff  --git a/llvm/test/MC/RISCV/rv32d-valid.s b/llvm/test/MC/RISCV/rv32d-valid.s
index eb8e9c394a20cd7..2e6812ca8423976 100644
--- a/llvm/test/MC/RISCV/rv32d-valid.s
+++ b/llvm/test/MC/RISCV/rv32d-valid.s
@@ -118,9 +118,15 @@ fcvt.w.d a4, ft11, dyn
 # CHECK-ASM-AND-OBJ: fcvt.d.w ft0, a5
 # CHECK-ASM: encoding: [0x53,0x80,0x07,0xd2]
 fcvt.d.w ft0, a5
+# CHECK-ASM-AND-OBJ: fcvt.d.w ft0, a5, rup
+# CHECK-ASM: encoding: [0x53,0xb0,0x07,0xd2]
+fcvt.d.w ft0, a5, rup
 # CHECK-ASM-AND-OBJ: fcvt.d.wu ft1, a6
 # CHECK-ASM: encoding: [0xd3,0x00,0x18,0xd2]
 fcvt.d.wu ft1, a6
+# CHECK-ASM-AND-OBJ: fcvt.d.wu ft1, a6, rup
+# CHECK-ASM: encoding: [0xd3,0x30,0x18,0xd2]
+fcvt.d.wu ft1, a6, rup
 
 # Rounding modes
 

diff  --git a/llvm/test/MC/RISCV/rv32zdinx-valid.s b/llvm/test/MC/RISCV/rv32zdinx-valid.s
index b668bab0caaec7d..bd1e23104c5ba8a 100644
--- a/llvm/test/MC/RISCV/rv32zdinx-valid.s
+++ b/llvm/test/MC/RISCV/rv32zdinx-valid.s
@@ -81,9 +81,15 @@ fcvt.w.d x20, x22, dyn
 # CHECK-ASM-AND-OBJ: fcvt.d.w s10, t3
 # CHECK-ASM: encoding: [0x53,0x0d,0x0e,0xd2]
 fcvt.d.w x26, x28
+# CHECK-ASM-AND-OBJ: fcvt.d.w s10, t3, rup
+# CHECK-ASM: encoding: [0x53,0x3d,0x0e,0xd2]
+fcvt.d.w x26, x28, rup
 # CHECK-ASM-AND-OBJ: fcvt.d.wu s10, t3
 # CHECK-ASM: encoding: [0x53,0x0d,0x1e,0xd2]
 fcvt.d.wu x26, x28
+# CHECK-ASM-AND-OBJ: fcvt.d.wu s10, t3, rup
+# CHECK-ASM: encoding: [0x53,0x3d,0x1e,0xd2]
+fcvt.d.wu x26, x28, rup
 
 # Rounding modes
 

diff  --git a/llvm/test/MC/RISCV/rv32zfhmin-valid.s b/llvm/test/MC/RISCV/rv32zfhmin-valid.s
index 551a4770f4125c8..736ff566805eb58 100644
--- a/llvm/test/MC/RISCV/rv32zfhmin-valid.s
+++ b/llvm/test/MC/RISCV/rv32zfhmin-valid.s
@@ -51,12 +51,18 @@ fmv.h.x ft1, a6
 # CHECK-ASM-AND-OBJ: fcvt.s.h fa0, ft0
 # CHECK-ASM: encoding: [0x53,0x05,0x20,0x40]
 fcvt.s.h fa0, ft0
+# CHECK-ASM-AND-OBJ: fcvt.s.h fa0, ft0, rup
+# CHECK-ASM: encoding: [0x53,0x35,0x20,0x40]
+fcvt.s.h fa0, ft0, rup
 # CHECK-ASM-AND-OBJ: fcvt.h.s ft2, fa2
 # CHECK-ASM: encoding: [0x53,0x71,0x06,0x44]
 fcvt.h.s ft2, fa2
 # CHECK-ASM-AND-OBJ: fcvt.d.h fa0, ft0
 # CHECK-ASM: encoding: [0x53,0x05,0x20,0x42]
 fcvt.d.h fa0, ft0
+# CHECK-ASM-AND-OBJ: fcvt.d.h fa0, ft0, rup
+# CHECK-ASM: encoding: [0x53,0x35,0x20,0x42]
+fcvt.d.h fa0, ft0, rup
 # CHECK-ASM-AND-OBJ: fcvt.h.d ft2, fa2
 # CHECK-ASM: encoding: [0x53,0x71,0x16,0x44]
 fcvt.h.d ft2, fa2

diff  --git a/llvm/test/MC/RISCV/rv32zhinxmin-valid.s b/llvm/test/MC/RISCV/rv32zhinxmin-valid.s
index 536c0bdfe2b9158..fbdbce06bc0ffb5 100644
--- a/llvm/test/MC/RISCV/rv32zhinxmin-valid.s
+++ b/llvm/test/MC/RISCV/rv32zhinxmin-valid.s
@@ -12,6 +12,9 @@
 # CHECK-ASM-AND-OBJ: fcvt.s.h a0, a1
 # CHECK-ASM: encoding: [0x53,0x85,0x25,0x40]
 fcvt.s.h a0, a1
+# CHECK-ASM-AND-OBJ: fcvt.s.h a0, a1, rup
+# CHECK-ASM: encoding: [0x53,0xb5,0x25,0x40]
+fcvt.s.h a0, a1, rup
 
 # CHECK-ASM-AND-OBJ: fcvt.h.s a0, a1, dyn
 # CHECK-ASM: encoding: [0x53,0xf5,0x05,0x44]

diff  --git a/llvm/test/MC/RISCV/rv64zhinxmin-valid.s b/llvm/test/MC/RISCV/rv64zhinxmin-valid.s
index 54f32e7a07b5076..062844f555ec6ba 100644
--- a/llvm/test/MC/RISCV/rv64zhinxmin-valid.s
+++ b/llvm/test/MC/RISCV/rv64zhinxmin-valid.s
@@ -7,6 +7,9 @@
 # CHECK-ASM-AND-OBJ: fcvt.d.h a0, a2
 # CHECK-ASM: encoding: [0x53,0x05,0x26,0x42]
 fcvt.d.h a0, a2
+# CHECK-ASM-AND-OBJ: fcvt.d.h a0, a2, rup
+# CHECK-ASM: encoding: [0x53,0x35,0x26,0x42]
+fcvt.d.h a0, a2, rup
 
 # CHECK-ASM-AND-OBJ: fcvt.h.d a0, a2, dyn
 # CHECK-ASM: encoding: [0x53,0x75,0x16,0x44]


        


More information about the llvm-commits mailing list