Skip to content

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Jun 25, 2024

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Jun 25, 2024

@llvm/pr-subscribers-llvm-globalisel

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

Changes

Patch is 25.03 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/96582.diff

5 Files Affected:

  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+13-5)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp (+33-14)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-arith-f16.mir (+194)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fp-arith-f16.mir (+233)
  • (added) llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-arith-f16.mir (+257)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index e003b6b8ee4e1..bec542f7781b1 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -371,17 +371,25 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
 
   // FP Operations
 
-  getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FNEG,
-                               G_FABS, G_FSQRT, G_FMAXNUM, G_FMINNUM})
-      .legalIf(typeIsScalarFPArith(0, ST));
+  auto &FPArithActions = getActionDefinitionsBuilder(
+                             {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FNEG,
+                              G_FABS, G_FSQRT, G_FMAXNUM, G_FMINNUM})
+                             .legalIf(typeIsScalarFPArith(0, ST));
+  // TODO: Fold this into typeIsScalarFPArith.
+  if (ST.hasStdExtZfh())
+    FPArithActions.legalFor({s16});
 
   getActionDefinitionsBuilder(G_FREM)
       .libcallFor({s32, s64})
       .minScalar(0, s32)
       .scalarize(0);
 
-  getActionDefinitionsBuilder(G_FCOPYSIGN)
-      .legalIf(all(typeIsScalarFPArith(0, ST), typeIsScalarFPArith(1, ST)));
+  auto &CopySignActions =
+      getActionDefinitionsBuilder(G_FCOPYSIGN)
+          .legalIf(all(typeIsScalarFPArith(0, ST), typeIsScalarFPArith(1, ST)));
+  // TODO: Fold this into typeIsScalarFPArith.
+  if (ST.hasStdExtZfh())
+    CopySignActions.legalFor({s16, s16});
 
   getActionDefinitionsBuilder(G_FPTRUNC).legalIf(
       [=, &ST](const LegalityQuery &Query) -> bool {
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index 686c8d89a7321..41ca164b38f3d 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -29,6 +29,7 @@ const RegisterBankInfo::PartialMapping PartMappings[] = {
     // clang-format off
     {0, 32, GPRBRegBank},
     {0, 64, GPRBRegBank},
+    {0, 16, FPRBRegBank},
     {0, 32, FPRBRegBank},
     {0, 64, FPRBRegBank},
     {0, 64, VRBRegBank},
@@ -41,12 +42,13 @@ const RegisterBankInfo::PartialMapping PartMappings[] = {
 enum PartialMappingIdx {
   PMI_GPRB32 = 0,
   PMI_GPRB64 = 1,
-  PMI_FPRB32 = 2,
-  PMI_FPRB64 = 3,
-  PMI_VRB64 = 4,
-  PMI_VRB128 = 5,
-  PMI_VRB256 = 6,
-  PMI_VRB512 = 7,
+  PMI_FPRB16 = 2,
+  PMI_FPRB32 = 3,
+  PMI_FPRB64 = 4,
+  PMI_VRB64 = 5,
+  PMI_VRB128 = 6,
+  PMI_VRB256 = 7,
+  PMI_VRB512 = 8,
 };
 
 const RegisterBankInfo::ValueMapping ValueMappings[] = {
@@ -60,6 +62,10 @@ const RegisterBankInfo::ValueMapping ValueMappings[] = {
     {&PartMappings[PMI_GPRB64], 1},
     {&PartMappings[PMI_GPRB64], 1},
     {&PartMappings[PMI_GPRB64], 1},
+    // Maximum 3 FPR operands; 16 bit.
+    {&PartMappings[PMI_FPRB16], 1},
+    {&PartMappings[PMI_FPRB16], 1},
+    {&PartMappings[PMI_FPRB16], 1},
     // Maximum 3 FPR operands; 32 bit.
     {&PartMappings[PMI_FPRB32], 1},
     {&PartMappings[PMI_FPRB32], 1},
@@ -90,12 +96,13 @@ enum ValueMappingIdx {
   InvalidIdx = 0,
   GPRB32Idx = 1,
   GPRB64Idx = 4,
-  FPRB32Idx = 7,
-  FPRB64Idx = 10,
-  VRB64Idx = 13,
-  VRB128Idx = 16,
-  VRB256Idx = 19,
-  VRB512Idx = 22,
+  FPRB16Idx = 7,
+  FPRB32Idx = 10,
+  FPRB64Idx = 13,
+  VRB64Idx = 16,
+  VRB128Idx = 19,
+  VRB256Idx = 22,
+  VRB512Idx = 25,
 };
 } // namespace RISCV
 } // namespace llvm
@@ -151,8 +158,20 @@ RISCVRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
 }
 
 static const RegisterBankInfo::ValueMapping *getFPValueMapping(unsigned Size) {
-  assert(Size == 32 || Size == 64);
-  unsigned Idx = Size == 64 ? RISCV::FPRB64Idx : RISCV::FPRB32Idx;
+  unsigned Idx;
+  switch (Size) {
+  default:
+    llvm_unreachable("Unexpected size");
+  case 16:
+    Idx = RISCV::FPRB16Idx;
+    break;
+  case 32:
+    Idx = RISCV::FPRB32Idx;
+    break;
+  case 64:
+    Idx = RISCV::FPRB64Idx;
+    break;
+  }
   return &RISCV::ValueMappings[Idx];
 }
 
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-arith-f16.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-arith-f16.mir
new file mode 100644
index 0000000000000..449e45467728d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-arith-f16.mir
@@ -0,0 +1,194 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+zfh -run-pass=instruction-select \
+# RUN:   -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=riscv64 -mattr=+zfh -run-pass=instruction-select \
+# RUN:   -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name:            fadd_f16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fadd_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $f11_h
+    ; CHECK-NEXT: [[FADD_H:%[0-9]+]]:fpr16 = nofpexcept FADD_H [[COPY]], [[COPY1]], 7
+    ; CHECK-NEXT: $f10_h = COPY [[FADD_H]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:fprb(s16) = COPY $f10_h
+    %1:fprb(s16) = COPY $f11_h
+    %2:fprb(s16) = G_FADD %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fsub_f16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fsub_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $f11_h
+    ; CHECK-NEXT: [[FSUB_H:%[0-9]+]]:fpr16 = nofpexcept FSUB_H [[COPY]], [[COPY1]], 7
+    ; CHECK-NEXT: $f10_h = COPY [[FSUB_H]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:fprb(s16) = COPY $f10_h
+    %1:fprb(s16) = COPY $f11_h
+    %2:fprb(s16) = G_FSUB %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fmul_f16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fmul_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $f11_h
+    ; CHECK-NEXT: [[FMUL_H:%[0-9]+]]:fpr16 = nofpexcept FMUL_H [[COPY]], [[COPY1]], 7
+    ; CHECK-NEXT: $f10_h = COPY [[FMUL_H]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:fprb(s16) = COPY $f10_h
+    %1:fprb(s16) = COPY $f11_h
+    %2:fprb(s16) = G_FMUL %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fdiv_f16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fdiv_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $f11_h
+    ; CHECK-NEXT: [[FDIV_H:%[0-9]+]]:fpr16 = nofpexcept FDIV_H [[COPY]], [[COPY1]], 7
+    ; CHECK-NEXT: $f10_h = COPY [[FDIV_H]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:fprb(s16) = COPY $f10_h
+    %1:fprb(s16) = COPY $f11_h
+    %2:fprb(s16) = G_FDIV %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fma_f16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h, $f12_h
+
+    ; CHECK-LABEL: name: fma_f16
+    ; CHECK: liveins: $f10_h, $f11_h, $f12_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY $f11_h
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr16 = COPY $f12_h
+    ; CHECK-NEXT: [[FMADD_H:%[0-9]+]]:fpr16 = nofpexcept FMADD_H [[COPY]], [[COPY1]], [[COPY2]], 7
+    ; CHECK-NEXT: $f10_h = COPY [[FMADD_H]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:fprb(s16) = COPY $f10_h
+    %1:fprb(s16) = COPY $f11_h
+    %2:fprb(s16) = COPY $f12_h
+    %3:fprb(s16) = G_FMA %0, %1, %2
+    $f10_h = COPY %3(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fneg_f16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h, $f12_h
+
+    ; CHECK-LABEL: name: fneg_f16
+    ; CHECK: liveins: $f10_h, $f11_h, $f12_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $f10_h
+    ; CHECK-NEXT: [[FSGNJN_H:%[0-9]+]]:fpr16 = FSGNJN_H [[COPY]], [[COPY]]
+    ; CHECK-NEXT: $f10_h = COPY [[FSGNJN_H]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:fprb(s16) = COPY $f10_h
+    %1:fprb(s16) = G_FNEG %0
+    $f10_h = COPY %1(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fabs_f16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h, $f12_h
+
+    ; CHECK-LABEL: name: fabs_f16
+    ; CHECK: liveins: $f10_h, $f11_h, $f12_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $f10_h
+    ; CHECK-NEXT: [[FSGNJX_H:%[0-9]+]]:fpr16 = FSGNJX_H [[COPY]], [[COPY]]
+    ; CHECK-NEXT: $f10_h = COPY [[FSGNJX_H]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:fprb(s16) = COPY $f10_h
+    %1:fprb(s16) = G_FABS %0
+    $f10_h = COPY %1(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fsqrt_f16
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h, $f12_h
+
+    ; CHECK-LABEL: name: fsqrt_f16
+    ; CHECK: liveins: $f10_h, $f11_h, $f12_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr16 = COPY $f10_h
+    ; CHECK-NEXT: [[FSQRT_H:%[0-9]+]]:fpr16 = nofpexcept FSQRT_H [[COPY]], 7
+    ; CHECK-NEXT: $f10_h = COPY [[FSQRT_H]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:fprb(s16) = COPY $f10_h
+    %1:fprb(s16) = G_FSQRT %0
+    $f10_h = COPY %1(s16)
+    PseudoRET implicit $f10_h
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fp-arith-f16.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fp-arith-f16.mir
new file mode 100644
index 0000000000000..f1777e945b12d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fp-arith-f16.mir
@@ -0,0 +1,233 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+zfh -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+# RUN: llc -mtriple=riscv64 -mattr=+zfh -run-pass=legalizer %s -o - \
+# RUN: | FileCheck %s
+
+---
+name:            fadd_f16
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fadd_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s16) = G_FADD [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $f10_h = COPY [[FADD]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FADD %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fsub_f16
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fsub_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FSUB:%[0-9]+]]:_(s16) = G_FSUB [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $f10_h = COPY [[FSUB]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FSUB %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fmul_f16
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fmul_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FMUL:%[0-9]+]]:_(s16) = G_FMUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $f10_h = COPY [[FMUL]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FMUL %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fdiv_f16
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fdiv_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FDIV:%[0-9]+]]:_(s16) = G_FDIV [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $f10_h = COPY [[FDIV]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FDIV %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fma_f16
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h, $f12_h
+
+    ; CHECK-LABEL: name: fma_f16
+    ; CHECK: liveins: $f10_h, $f11_h, $f12_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s16) = COPY $f12_h
+    ; CHECK-NEXT: [[FMA:%[0-9]+]]:_(s16) = G_FMA [[COPY]], [[COPY1]], [[COPY2]]
+    ; CHECK-NEXT: $f10_h = COPY [[FMA]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = COPY $f12_h
+    %3:_(s16) = G_FMA %0, %1, %2
+    $f10_h = COPY %3(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fneg_f16
+body:             |
+  bb.0:
+    liveins: $f10_h
+
+    ; CHECK-LABEL: name: fneg_f16
+    ; CHECK: liveins: $f10_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[FNEG:%[0-9]+]]:_(s16) = G_FNEG [[COPY]]
+    ; CHECK-NEXT: $f10_h = COPY [[FNEG]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = G_FNEG %0
+    $f10_h = COPY %1(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fabs_f16
+body:             |
+  bb.0:
+    liveins: $f10_h
+
+    ; CHECK-LABEL: name: fabs_f16
+    ; CHECK: liveins: $f10_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[FABS:%[0-9]+]]:_(s16) = G_FABS [[COPY]]
+    ; CHECK-NEXT: $f10_h = COPY [[FABS]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = G_FABS %0
+    $f10_h = COPY %1(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fsqrt_f16
+body:             |
+  bb.0:
+    liveins: $f10_h
+
+    ; CHECK-LABEL: name: fsqrt_f16
+    ; CHECK: liveins: $f10_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[FSQRT:%[0-9]+]]:_(s16) = G_FSQRT [[COPY]]
+    ; CHECK-NEXT: $f10_h = COPY [[FSQRT]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = G_FSQRT %0
+    $f10_h = COPY %1(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fmaxnum_f16
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fmaxnum_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FMAXNUM:%[0-9]+]]:_(s16) = G_FMAXNUM [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $f10_h = COPY [[FMAXNUM]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FMAXNUM %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fminnum_f16
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fminnum_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FMINNUM:%[0-9]+]]:_(s16) = G_FMINNUM [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $f10_h = COPY [[FMINNUM]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FMINNUM %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fcopysign_f16
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fcopysign_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FCOPYSIGN:%[0-9]+]]:_(s16) = G_FCOPYSIGN [[COPY]], [[COPY1]](s16)
+    ; CHECK-NEXT: $f10_h = COPY [[FCOPYSIGN]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FCOPYSIGN %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-arith-f16.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-arith-f16.mir
new file mode 100644
index 0000000000000..ace4aa542377b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-arith-f16.mir
@@ -0,0 +1,257 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+zfh -run-pass=regbankselect \
+# RUN:   -simplify-mir -verify-machineinstrs %s \
+# RUN:   -o - | FileCheck %s
+# RUN: llc -mtriple=riscv64 -mattr=+zfh -run-pass=regbankselect \
+# RUN:   -simplify-mir -verify-machineinstrs %s \
+# RUN:   -o - | FileCheck %s
+
+---
+name:            fadd_f16
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fadd_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fprb(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fprb(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FADD:%[0-9]+]]:fprb(s16) = G_FADD [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $f10_h = COPY [[FADD]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FADD %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fsub_f16
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fsub_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fprb(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fprb(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FSUB:%[0-9]+]]:fprb(s16) = G_FSUB [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $f10_h = COPY [[FSUB]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FSUB %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fmul_f16
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+    ; CHECK-LABEL: name: fmul_f16
+    ; CHECK: liveins: $f10_h, $f11_h
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:fprb(s16) = COPY $f10_h
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fprb(s16) = COPY $f11_h
+    ; CHECK-NEXT: [[FMUL:%[0-9]+]]:fprb(s16) = G_FMUL [[COPY]], [[COPY1]]
+    ; CHECK-NEXT: $f10_h = COPY [[FMUL]](s16)
+    ; CHECK-NEXT: PseudoRET implicit $f10_h
+    %0:_(s16) = COPY $f10_h
+    %1:_(s16) = COPY $f11_h
+    %2:_(s16) = G_FMUL %0, %1
+    $f10_h = COPY %2(s16)
+    PseudoRET implicit $f10_h
+
+...
+---
+name:            fdiv_f16
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $f10_h, $f11_h
+
+  ...
[truncated]

Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I already have an unsubmitted patch for half fp arith :) It was blocked by supporting half fp with only F or F + Zfhmin.

Do you plan to support other ops (fcmp/fconstant/fp<->fp/fp<->int)?

G_FABS, G_FSQRT, G_FMAXNUM, G_FMINNUM})
.legalIf(typeIsScalarFPArith(0, ST));
// TODO: Fold this into typeIsScalarFPArith.
if (ST.hasStdExtZfh())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't it work?

static LegalityPredicate typeIsScalarFPArith(unsigned TypeIdx,
                                             const RISCVSubtarget &ST) {
  return [=, &ST](const LegalityQuery &Query) {
    return Query.Types[TypeIdx].isScalar() &&
           ((ST.hasStdExtF() && Query.Types[TypeIdx].getSizeInBits() == 32) ||
            (ST.hasStdExtD() && Query.Types[TypeIdx].getSizeInBits() == 64) ||
            (ST.hasStdExtZfh() && Query.Types[TypeIdx].getSizeInBits() == 16));
  };
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should, but it requires many more tests to cover every other call to typeIsScalarFPArith

@topperc
Copy link
Collaborator Author

topperc commented Jun 25, 2024

Oops, I already have an unsubmitted patch for half fp arith :) It was blocked by supporting half fp with only F or F + Zfhmin.

Why is that blocking?

Do you plan to support other ops (fcmp/fconstant/fp<->fp/fp<->int)?

Yes.

@dtcxzyw
Copy link
Member

dtcxzyw commented Jun 25, 2024

Oops, I already have an unsubmitted patch for half fp arith :) It was blocked by supporting half fp with only F or F + Zfhmin.

Why is that blocking?

As we widen the type from f16 to f32, we need to implement G_FPTRUNC/G_FPEXT/G_ANYEXT for s16<->s32.

Do you plan to support other ops (fcmp/fconstant/fp<->fp/fp<->int)?

Yes.

Great! TBH I don't have enough bandwidth to work on this. I will post my existing code later. Hope this helps you.

@dtcxzyw
Copy link
Member

dtcxzyw commented Jun 25, 2024

Oops, I already have an unsubmitted patch for half fp arith :) It was blocked by supporting half fp with only F or F + Zfhmin.

Why is that blocking?

As we widen the type from f16 to f32, we need to implement G_FPTRUNC/G_FPEXT/G_ANYEXT for s16<->s32.

Do you plan to support other ops (fcmp/fconstant/fp<->fp/fp<->int)?

Yes.

Great! TBH I don't have enough bandwidth to work on this. I will post my existing code later. Hope this helps you.

See dtcxzyw@7948041

@dtcxzyw dtcxzyw requested a review from arsenm June 25, 2024 10:22
Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you!
Wait for an additional approval from other reviewers.

Copy link
Contributor

@michaelmaitland michaelmaitland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@topperc topperc merged commit dddef9d into llvm:main Jun 25, 2024
@topperc topperc deleted the pr/fp16-gisel branch June 25, 2024 15:18
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants