[llvm] [RISCV] Add register bank and instruction selection support for FP G_SELECT. (PR #72726)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 27 10:24:30 PST 2023


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/72726

>From 0792f67e48b689a85e1ae1018f6d6709abf6e61d Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 17 Nov 2023 15:59:13 -0800
Subject: [PATCH 1/6] [RISCV] Add register bank and instruction selection
 support for G_SELECT.

Try to pick the FP register bank based on surrounding use/defs. Code
is basically copied from AArch64.

Need legalizer changes to make this more useful. Right now we're stuck
with only being able to FP typs the same size as XLen.
---
 .../RISCV/GISel/RISCVInstructionSelector.cpp  | 12 ++++-
 .../RISCV/GISel/RISCVRegisterBankInfo.cpp     | 51 +++++++++++++++++--
 .../instruction-select/fp-select-rv32.mir     | 33 ++++++++++++
 .../instruction-select/fp-select-rv64.mir     | 34 +++++++++++++
 .../regbankselect/fp-select-rv32.mir          | 34 +++++++++++++
 .../regbankselect/fp-select-rv64.mir          | 34 +++++++++++++
 6 files changed, 192 insertions(+), 6 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv32.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv64.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir
 create mode 100644 llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 97fa5106cf7d6c8..e37548cddda3536 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -912,8 +912,16 @@ bool RISCVInstructionSelector::selectSelect(MachineInstr &MI,
   RISCVCC::CondCode CC;
   getOperandsForBranch(SelectMI.getCondReg(), MRI, CC, LHS, RHS);
 
-  MachineInstr *Result = MIB.buildInstr(RISCV::Select_GPR_Using_CC_GPR)
-                             .addDef(SelectMI.getReg(0))
+  Register DstReg = SelectMI.getReg(0);
+
+  unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
+  if (RBI.getRegBank(DstReg, MRI, TRI)->getID() == RISCV::FPRBRegBankID) {
+    unsigned Size = MRI.getType(DstReg).getSizeInBits();
+    Opc = Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR : RISCV::Select_FPR64_Using_CC_GPR;
+  }
+
+  MachineInstr *Result = MIB.buildInstr(Opc)
+                             .addDef(DstReg)
                              .addReg(LHS)
                              .addReg(RHS)
                              .addImm(CC)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index c2f07e1aa651fe9..afb14ce39727e55 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -323,12 +323,55 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
       OpdsMapping[0] = getFPValueMapping(Ty.getSizeInBits());
     break;
   }
-  case TargetOpcode::G_SELECT:
-    OpdsMapping[0] = GPRValueMapping;
+  case TargetOpcode::G_SELECT: {
+    LLT Ty = MRI.getType(MI.getOperand(0).getReg());
+
+    // Try to minimize the number of copies. If we have more floating point
+    // constrained values than not, then we'll put everything on FPR. Otherwise,
+    // everything has to be on GPR.
+    unsigned NumFP = 0;
+
+    // Check if the uses of the result always produce floating point values.
+    //
+    // For example:
+    //
+    // %z = G_SELECT %cond %x %y
+    // fpr = G_FOO %z ...
+    if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
+               [&](const MachineInstr &UseMI) { return onlyUsesFP(UseMI, MRI, TRI); }))
+      ++NumFP;
+
+    // Check if the defs of the source values always produce floating point
+    // values.
+    //
+    // For example:
+    //
+    // %x = G_SOMETHING_ALWAYS_FLOAT %a ...
+    // %z = G_SELECT %cond %x %y
+    //
+    // Also check whether or not the sources have already been decided to be
+    // FPR. Keep track of this.
+    //
+    // This doesn't check the condition, since it's just whatever is in NZCV.
+    // This isn't passed explicitly in a register to fcsel/csel.
+    for (unsigned Idx = 2; Idx < 4; ++Idx) {
+      Register VReg = MI.getOperand(Idx).getReg();
+      MachineInstr *DefMI = MRI.getVRegDef(VReg);
+      if (getRegBank(VReg, MRI, TRI) == &RISCV::FPRBRegBank ||
+          onlyDefinesFP(*DefMI, MRI, TRI))
+        ++NumFP;
+    }
+
+    // Condition operand is always GPR.
     OpdsMapping[1] = GPRValueMapping;
-    OpdsMapping[2] = GPRValueMapping;
-    OpdsMapping[3] = GPRValueMapping;
+
+    const ValueMapping *Mapping = GPRValueMapping;
+    if (NumFP >= 2)
+      Mapping = getFPValueMapping(Ty.getSizeInBits());
+
+    OpdsMapping[0] = OpdsMapping[2] = OpdsMapping[3] = Mapping;
     break;
+  }
   case TargetOpcode::G_FPTOSI:
   case TargetOpcode::G_FPTOUI:
   case RISCV::G_FCLASS: {
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv32.mir
new file mode 100644
index 000000000000000..4fffbc42b2cff34
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv32.mir
@@ -0,0 +1,33 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+d -run-pass=instruction-select \
+# RUN:   -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name:            fp_select_s32
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $f10_f, $f11_f
+
+    ; CHECK-LABEL: name: fp_select_s32
+    ; CHECK: liveins: $x10, $f10_f, $f11_f
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY $f10_f
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr32 = COPY $f11_f
+    ; CHECK-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
+    ; CHECK-NEXT: [[Select_FPR32_Using_CC_GPR:%[0-9]+]]:fpr32 = Select_FPR32_Using_CC_GPR [[ANDI]], $x0, 1, [[COPY1]], [[COPY2]]
+    ; CHECK-NEXT: $f10_f = COPY [[Select_FPR32_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_f
+    %0:gprb(s32) = COPY $x10
+    %1:fprb(s32) = COPY $f10_f
+    %2:fprb(s32) = COPY $f11_f
+    %3:gprb(s32) = G_CONSTANT i32 1
+    %4:gprb(s32) = G_AND %0, %3
+    %5:fprb(s32) = G_SELECT %4(s32), %1, %2
+    $f10_f = COPY %5(s32)
+    PseudoRET implicit $f10_f
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv64.mir
new file mode 100644
index 000000000000000..8efb8b10d8a931d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv64.mir
@@ -0,0 +1,34 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -mattr=+d -run-pass=instruction-select \
+# RUN:   -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name:            fp_select_s64
+alignment:       1
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $f10_d, $f11_d
+
+    ; CHECK-LABEL: name: fp_select_s64
+    ; CHECK: liveins: $x10, $f10_d, $f11_d
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $f10_d
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY $f11_d
+    ; CHECK-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
+    ; CHECK-NEXT: [[Select_FPR64_Using_CC_GPR:%[0-9]+]]:fpr64 = Select_FPR64_Using_CC_GPR [[ANDI]], $x0, 1, [[COPY1]], [[COPY2]]
+    ; CHECK-NEXT: $f10_d = COPY [[Select_FPR64_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_d
+    %0:gprb(s64) = COPY $x10
+    %1:fprb(s64) = COPY $f10_d
+    %2:fprb(s64) = COPY $f11_d
+    %3:gprb(s64) = G_CONSTANT i64 1
+    %4:gprb(s64) = G_AND %0, %3
+    %5:fprb(s64) = G_SELECT %4(s64), %1, %2
+    $f10_d = COPY %5(s64)
+    PseudoRET implicit $f10_d
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir
new file mode 100644
index 000000000000000..312fadca866206c
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir
@@ -0,0 +1,34 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+d -run-pass=regbankselect \
+# RUN:   -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN:   -o - | FileCheck -check-prefix=RV32I %s
+
+---
+name:            fp_select_s32
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $f10_f, $f11_f
+
+    ; RV32I-LABEL: name: fp_select_s32
+    ; RV32I: liveins: $x10, $f10_f, $f11_f
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:fprb(s32) = COPY $f11_f
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY2]]
+    ; RV32I-NEXT: $f10_f = COPY [[SELECT]](s32)
+    ; RV32I-NEXT: PseudoRET implicit $f10_f
+    %3:_(s32) = COPY $x10
+    %4:_(s32) = COPY $f10_f
+    %5:_(s32) = COPY $f11_f
+    %12:_(s32) = G_CONSTANT i32 1
+    %11:_(s32) = G_AND %3, %12
+    %10:_(s32) = G_SELECT %11(s32), %4, %5
+    $f10_f = COPY %10(s32)
+    PseudoRET implicit $f10_f
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir
new file mode 100644
index 000000000000000..22ebd5e93b01407
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir
@@ -0,0 +1,34 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv64 -mattr=+d -run-pass=regbankselect \
+# RUN:   -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
+# RUN:   -o - | FileCheck -check-prefix=RV32I %s
+
+---
+name:            fp_select_s64
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $f10_d, $f11_d
+
+    ; RV32I-LABEL: name: fp_select_s64
+    ; RV32I: liveins: $x10, $f10_d, $f11_d
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s64) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s64) = COPY $f10_d
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:fprb(s64) = COPY $f11_d
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s64) = G_CONSTANT i64 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s64) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s64) = G_SELECT [[AND]](s64), [[COPY1]], [[COPY2]]
+    ; RV32I-NEXT: $f10_d = COPY [[SELECT]](s64)
+    ; RV32I-NEXT: PseudoRET implicit $f10_d
+    %3:_(s64) = COPY $x10
+    %4:_(s64) = COPY $f10_d
+    %5:_(s64) = COPY $f11_d
+    %12:_(s64) = G_CONSTANT i64 1
+    %11:_(s64) = G_AND %3, %12
+    %10:_(s64) = G_SELECT %11(s64), %4, %5
+    $f10_d = COPY %10(s64)
+    PseudoRET implicit $f10_d
+
+...

>From 4704a36ef89763d3af50d67678f15d55f4fe6682 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 17 Nov 2023 16:41:14 -0800
Subject: [PATCH 2/6] fixup! clang-format

---
 llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 3 ++-
 llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp    | 4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index e37548cddda3536..3433c3e859b12b5 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -917,7 +917,8 @@ bool RISCVInstructionSelector::selectSelect(MachineInstr &MI,
   unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
   if (RBI.getRegBank(DstReg, MRI, TRI)->getID() == RISCV::FPRBRegBankID) {
     unsigned Size = MRI.getType(DstReg).getSizeInBits();
-    Opc = Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR : RISCV::Select_FPR64_Using_CC_GPR;
+    Opc = Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
+                     : RISCV::Select_FPR64_Using_CC_GPR;
   }
 
   MachineInstr *Result = MIB.buildInstr(Opc)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index afb14ce39727e55..fd1a195161f6be4 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -338,7 +338,9 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     // %z = G_SELECT %cond %x %y
     // fpr = G_FOO %z ...
     if (any_of(MRI.use_nodbg_instructions(MI.getOperand(0).getReg()),
-               [&](const MachineInstr &UseMI) { return onlyUsesFP(UseMI, MRI, TRI); }))
+               [&](const MachineInstr &UseMI) {
+                 return onlyUsesFP(UseMI, MRI, TRI);
+               }))
       ++NumFP;
 
     // Check if the defs of the source values always produce floating point

>From 3b69d374ec07298c15d95b0c8c8c77f34466f742 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Sat, 18 Nov 2023 11:39:32 -0800
Subject: [PATCH 3/6] Add f32 test for rv64.

---
 .../instruction-select/fp-select-rv64.mir     | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv64.mir
index 8efb8b10d8a931d..e291c352e5a8573 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-select-rv64.mir
@@ -2,6 +2,36 @@
 # RUN: llc -mtriple=riscv64 -mattr=+d -run-pass=instruction-select \
 # RUN:   -simplify-mir -verify-machineinstrs %s -o - | FileCheck %s
 
+---
+name:            fp_select_s32
+alignment:       1
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $f10_d, $f11_d
+
+    ; CHECK-LABEL: name: fp_select_s32
+    ; CHECK: liveins: $x10, $f10_d, $f11_d
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY $f10_f
+    ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr32 = COPY $f11_f
+    ; CHECK-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY]], 1
+    ; CHECK-NEXT: [[Select_FPR32_Using_CC_GPR:%[0-9]+]]:fpr32 = Select_FPR32_Using_CC_GPR [[ANDI]], $x0, 1, [[COPY1]], [[COPY2]]
+    ; CHECK-NEXT: $f10_f = COPY [[Select_FPR32_Using_CC_GPR]]
+    ; CHECK-NEXT: PseudoRET implicit $f10_f
+    %0:gprb(s64) = COPY $x10
+    %1:fprb(s32) = COPY $f10_f
+    %2:fprb(s32) = COPY $f11_f
+    %3:gprb(s64) = G_CONSTANT i64 1
+    %4:gprb(s64) = G_AND %0, %3
+    %5:fprb(s32) = G_SELECT %4(s64), %1, %2
+    $f10_f = COPY %5(s32)
+    PseudoRET implicit $f10_f
+
+...
 ---
 name:            fp_select_s64
 alignment:       1

>From 335337536524d86d9f6110d889d9b74ca9d604ef Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 27 Nov 2023 09:27:05 -0800
Subject: [PATCH 4/6] fixup! Update comment copy/pasted from AArch64.

---
 llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index fd1a195161f6be4..a5e453fa5821e5c 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -354,8 +354,8 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
     // Also check whether or not the sources have already been decided to be
     // FPR. Keep track of this.
     //
-    // This doesn't check the condition, since it's just whatever is in NZCV.
-    // This isn't passed explicitly in a register to fcsel/csel.
+    // This doesn't check the condition, since the condition is always an
+    // integer.
     for (unsigned Idx = 2; Idx < 4; ++Idx) {
       Register VReg = MI.getOperand(Idx).getReg();
       MachineInstr *DefMI = MRI.getVRegDef(VReg);

>From 0d20ddf35440936118807b9670c2c9ec5436b4d7 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 27 Nov 2023 09:40:31 -0800
Subject: [PATCH 5/6] fixup! Add s32 regbank test for rv64.

---
 .../regbankselect/fp-select-rv64.mir          | 29 +++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir
index 22ebd5e93b01407..9342e9d7257a192 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir
@@ -3,6 +3,35 @@
 # RUN:   -disable-gisel-legality-check -simplify-mir -verify-machineinstrs %s \
 # RUN:   -o - | FileCheck -check-prefix=RV32I %s
 
+---
+name:            fp_select_s32
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $f10_f, $f11_f
+
+    ; RV32I-LABEL: name: fp_select_s32
+    ; RV32I: liveins: $x10, $f10_f, $f11_f
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s64) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:fprb(s32) = COPY $f11_f
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s64) = G_CONSTANT i64 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s64) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s64), [[COPY1]], [[COPY2]]
+    ; RV32I-NEXT: $f10_f = COPY [[SELECT]](s32)
+    ; RV32I-NEXT: PseudoRET implicit $f10_f
+    %3:_(s64) = COPY $x10
+    %4:_(s32) = COPY $f10_f
+    %5:_(s32) = COPY $f11_f
+    %12:_(s64) = G_CONSTANT i64 1
+    %11:_(s64) = G_AND %3, %12
+    %10:_(s32) = G_SELECT %11(s64), %4(s32), %5
+    $f10_f = COPY %10(s32)
+    PseudoRET implicit $f10_f
+
+...
 ---
 name:            fp_select_s64
 legalized:       true

>From fa54dde54de7358d4efb3621f0fab022c491b01b Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 27 Nov 2023 10:12:43 -0800
Subject: [PATCH 6/6] fixup! add more tests.

---
 .../regbankselect/fp-select-rv32.mir          | 118 ++++++++++++
 .../regbankselect/fp-select-rv64.mir          | 182 ++++++++++++++++++
 2 files changed, 300 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir
index 312fadca866206c..6d8ca3eb6d8271a 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv32.mir
@@ -32,3 +32,121 @@ body:             |
     PseudoRET implicit $f10_f
 
 ...
+---
+name:            fp_select_gpr_use_s32
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $f10_f, $f11_f
+
+    ; RV32I-LABEL: name: fp_select_gpr_use_s32
+    ; RV32I: liveins: $x10, $f10_f, $f11_f
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:fprb(s32) = COPY $f11_f
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY2]]
+    ; RV32I-NEXT: $x10 = COPY [[SELECT]](s32)
+    ; RV32I-NEXT: PseudoRET implicit $x10
+    %3:_(s32) = COPY $x10
+    %4:_(s32) = COPY $f10_f
+    %5:_(s32) = COPY $f11_f
+    %12:_(s32) = G_CONSTANT i32 1
+    %11:_(s32) = G_AND %3, %12
+    %10:_(s32) = G_SELECT %11(s32), %4, %5
+    $x10 = COPY %10(s32)
+    PseudoRET implicit $x10
+
+...
+---
+name:            fp_select_gpr_def_s32
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11, $f10_f
+
+    ; RV32I-LABEL: name: fp_select_gpr_def_s32
+    ; RV32I: liveins: $x10, $x11, $f10_f
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $x11
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[COPY3:%[0-9]+]]:fprb(s32) = COPY [[COPY2]](s32)
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY3]]
+    ; RV32I-NEXT: $f10_f = COPY [[SELECT]](s32)
+    ; RV32I-NEXT: PseudoRET implicit $f10_f
+    %3:_(s32) = COPY $x10
+    %4:_(s32) = COPY $f10_f
+    %5:_(s32) = COPY $x11
+    %12:_(s32) = G_CONSTANT i32 1
+    %11:_(s32) = G_AND %3, %12
+    %10:_(s32) = G_SELECT %11(s32), %4, %5
+    $f10_f = COPY %10(s32)
+    PseudoRET implicit $f10_f
+
+...
+---
+name:            fp_select_only_fpr_use_s32
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11, $x12
+
+    ; RV32I-LABEL: name: fp_select_only_fpr_use_s32
+    ; RV32I: liveins: $x10, $x11, $x12
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $x11
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $x12
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:gprb(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[COPY2]]
+    ; RV32I-NEXT: $f10_f = COPY [[SELECT]](s32)
+    ; RV32I-NEXT: PseudoRET implicit $f10_f
+    %3:_(s32) = COPY $x10
+    %4:_(s32) = COPY $x11
+    %5:_(s32) = COPY $x12
+    %12:_(s32) = G_CONSTANT i32 1
+    %11:_(s32) = G_AND %3, %12
+    %10:_(s32) = G_SELECT %11(s32), %4, %5
+    $f10_f = COPY %10(s32)
+    PseudoRET implicit $f10_f
+
+...
+---
+name:            fp_select_only_one_fpr_def_s32
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11, $f10_f
+
+    ; RV32I-LABEL: name: fp_select_only_one_fpr_def_s32
+    ; RV32I: liveins: $x10, $x11, $f10_f
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s32) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $x11
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[COPY3:%[0-9]+]]:gprb(s32) = COPY [[COPY1]](s32)
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:gprb(s32) = G_SELECT [[AND]](s32), [[COPY3]], [[COPY2]]
+    ; RV32I-NEXT: $x10 = COPY [[SELECT]](s32)
+    ; RV32I-NEXT: PseudoRET implicit $x10
+    %3:_(s32) = COPY $x10
+    %4:_(s32) = COPY $f10_f
+    %5:_(s32) = COPY $x11
+    %12:_(s32) = G_CONSTANT i32 1
+    %11:_(s32) = G_AND %3, %12
+    %10:_(s32) = G_SELECT %11(s32), %4, %5
+    $x10 = COPY %10(s32)
+    PseudoRET implicit $x10
+
+...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir
index 9342e9d7257a192..1ecee1643daac9d 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/regbankselect/fp-select-rv64.mir
@@ -61,3 +61,185 @@ body:             |
     PseudoRET implicit $f10_d
 
 ...
+---
+name:            fp_select_gpr_use_s32
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $f10_f, $f11_f
+
+    ; RV32I-LABEL: name: fp_select_gpr_use_s32
+    ; RV32I: liveins: $x10, $f10_f, $f11_f
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s64) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:fprb(s32) = COPY $f11_f
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s64) = G_CONSTANT i64 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s64) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s64), [[COPY1]], [[COPY2]]
+    ; RV32I-NEXT: [[COPY3:%[0-9]+]]:gprb(s32) = COPY [[SELECT]](s32)
+    ; RV32I-NEXT: [[ANYEXT:%[0-9]+]]:gprb(s64) = G_ANYEXT [[COPY3]](s32)
+    ; RV32I-NEXT: $x10 = COPY [[ANYEXT]](s64)
+    ; RV32I-NEXT: PseudoRET implicit $x10
+    %3:_(s64) = COPY $x10
+    %4:_(s32) = COPY $f10_f
+    %5:_(s32) = COPY $f11_f
+    %12:_(s64) = G_CONSTANT i64 1
+    %11:_(s64) = G_AND %3, %12
+    %10:_(s32) = G_SELECT %11(s64), %4(s32), %5
+    %13:_(s64) = G_ANYEXT %10(s32)
+    $x10 = COPY %13(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            fp_select_gpr_use_s64
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $f10_d, $f11_d
+
+    ; RV32I-LABEL: name: fp_select_gpr_use_s64
+    ; RV32I: liveins: $x10, $f10_d, $f11_d
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s64) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s64) = COPY $f10_d
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:fprb(s64) = COPY $f11_d
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s64) = G_CONSTANT i64 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s64) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s64) = G_SELECT [[AND]](s64), [[COPY1]], [[COPY2]]
+    ; RV32I-NEXT: $x10 = COPY [[SELECT]](s64)
+    ; RV32I-NEXT: PseudoRET implicit $x10
+    %3:_(s64) = COPY $x10
+    %4:_(s64) = COPY $f10_d
+    %5:_(s64) = COPY $f11_d
+    %12:_(s64) = G_CONSTANT i64 1
+    %11:_(s64) = G_AND %3, %12
+    %10:_(s64) = G_SELECT %11(s64), %4, %5
+    $x10 = COPY %10(s64)
+    PseudoRET implicit $x10
+
+...
+---
+name:            fp_select_gpr_def_s32
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11, $f10_f
+
+    ; RV32I-LABEL: name: fp_select_gpr_def_s32
+    ; RV32I: liveins: $x10, $x11, $f10_f
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s64) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s32) = COPY $f10_f
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s64) = COPY $x11
+    ; RV32I-NEXT: [[TRUNC:%[0-9]+]]:gprb(s32) = G_TRUNC [[COPY2]](s64)
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s64) = G_CONSTANT i64 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s64) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[COPY3:%[0-9]+]]:fprb(s32) = COPY [[TRUNC]](s32)
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s64), [[COPY3]], [[COPY1]]
+    ; RV32I-NEXT: $f10_f = COPY [[SELECT]](s32)
+    ; RV32I-NEXT: PseudoRET implicit $f10_f
+    %3:_(s64) = COPY $x10
+    %4:_(s32) = COPY $f10_f
+    %5:_(s64) = COPY $x11
+    %6:_(s32) = G_TRUNC %5(s64)
+    %12:_(s64) = G_CONSTANT i64 1
+    %11:_(s64) = G_AND %3, %12
+    %10:_(s32) = G_SELECT %11(s64), %6(s32), %4
+    $f10_f = COPY %10(s32)
+    PseudoRET implicit $f10_f
+
+...
+---
+name:            fp_select_gpr_def_s64
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11, $f10_d
+
+    ; RV32I-LABEL: name: fp_select_gpr_def_s64
+    ; RV32I: liveins: $x10, $x11, $f10_d
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s64) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s64) = COPY $f10_d
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s64) = COPY $x11
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s64) = G_CONSTANT i64 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s64) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[COPY3:%[0-9]+]]:fprb(s64) = COPY [[COPY2]](s64)
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:fprb(s64) = G_SELECT [[AND]](s64), [[COPY1]], [[COPY3]]
+    ; RV32I-NEXT: $f10_d = COPY [[SELECT]](s64)
+    ; RV32I-NEXT: PseudoRET implicit $f10_d
+    %3:_(s64) = COPY $x10
+    %4:_(s64) = COPY $f10_d
+    %5:_(s64) = COPY $x11
+    %12:_(s64) = G_CONSTANT i64 1
+    %11:_(s64) = G_AND %3, %12
+    %10:_(s64) = G_SELECT %11(s64), %4, %5
+    $f10_d = COPY %10(s64)
+    PseudoRET implicit $f10_d
+
+...
+---
+name:            fp_select_only_fpr_use_s64
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11, $x12
+
+    ; RV32I-LABEL: name: fp_select_only_fpr_use_s64
+    ; RV32I: liveins: $x10, $x11, $x12
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s64) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:gprb(s64) = COPY $x11
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s64) = COPY $x12
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s64) = G_CONSTANT i64 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s64) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:gprb(s64) = G_SELECT [[AND]](s64), [[COPY1]], [[COPY2]]
+    ; RV32I-NEXT: $f10_d = COPY [[SELECT]](s64)
+    ; RV32I-NEXT: PseudoRET implicit $f10_d
+    %3:_(s64) = COPY $x10
+    %4:_(s64) = COPY $x11
+    %5:_(s64) = COPY $x12
+    %12:_(s64) = G_CONSTANT i64 1
+    %11:_(s64) = G_AND %3, %12
+    %10:_(s64) = G_SELECT %11(s64), %4, %5
+    $f10_d = COPY %10(s64)
+    PseudoRET implicit $f10_d
+
+...
+---
+name:            fp_select_only_one_fpr_def_s64
+legalized:       true
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10, $x11, $f10_d
+
+    ; RV32I-LABEL: name: fp_select_only_one_fpr_def_s64
+    ; RV32I: liveins: $x10, $x11, $f10_d
+    ; RV32I-NEXT: {{  $}}
+    ; RV32I-NEXT: [[COPY:%[0-9]+]]:gprb(s64) = COPY $x10
+    ; RV32I-NEXT: [[COPY1:%[0-9]+]]:fprb(s64) = COPY $f10_d
+    ; RV32I-NEXT: [[COPY2:%[0-9]+]]:gprb(s64) = COPY $x11
+    ; RV32I-NEXT: [[C:%[0-9]+]]:gprb(s64) = G_CONSTANT i64 1
+    ; RV32I-NEXT: [[AND:%[0-9]+]]:gprb(s64) = G_AND [[COPY]], [[C]]
+    ; RV32I-NEXT: [[COPY3:%[0-9]+]]:gprb(s64) = COPY [[COPY1]](s64)
+    ; RV32I-NEXT: [[SELECT:%[0-9]+]]:gprb(s64) = G_SELECT [[AND]](s64), [[COPY3]], [[COPY2]]
+    ; RV32I-NEXT: $x10 = COPY [[SELECT]](s64)
+    ; RV32I-NEXT: PseudoRET implicit $x10
+    %3:_(s64) = COPY $x10
+    %4:_(s64) = COPY $f10_d
+    %5:_(s64) = COPY $x11
+    %12:_(s64) = G_CONSTANT i64 1
+    %11:_(s64) = G_AND %3, %12
+    %10:_(s64) = G_SELECT %11(s64), %4, %5
+    $x10 = COPY %10(s64)
+    PseudoRET implicit $x10
+
+...



More information about the llvm-commits mailing list