[llvm] 0d7c340 - [RISCV][GISel] Add instruction selection for G_SEXT, G_ZEXT, and G_SEXT_INREG (#67359)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 25 15:08:25 PDT 2023


Author: Min-Yih Hsu
Date: 2023-09-25T15:08:21-07:00
New Revision: 0d7c340c2cc89b71d398479c9adcac77f0336c6e

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

LOG: [RISCV][GISel] Add instruction selection for G_SEXT, G_ZEXT, and G_SEXT_INREG (#67359)

G_SEXT and G_ZEXT are supported via patterns imported from SDISel;
G_SEXT_INREG is selected using hand-written code as there is no
(functional) rule at this moment to import G_SEXT_INREG from
ISD::SEXT_INREG.

Credit helps from @topperc on G_SEXT and G_ZEXT.

Added: 
    llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/sext-rv64.mir
    llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/zext-rv64.mir

Modified: 
    llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
    llvm/lib/Target/RISCV/RISCVGISel.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 4a4be79528545f8..2e690a3624edcb3 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -48,6 +48,7 @@ class RISCVInstructionSelector : public InstructionSelector {
   bool selectCopy(MachineInstr &MI, MachineRegisterInfo &MRI) const;
   bool selectConstant(MachineInstr &MI, MachineIRBuilder &MIB,
                       MachineRegisterInfo &MRI) const;
+  bool selectSExtInreg(MachineInstr &MI, MachineIRBuilder &MIB) const;
 
   bool earlySelectShift(unsigned Opc, MachineInstr &I, MachineIRBuilder &MIB,
                         const MachineRegisterInfo &MRI);
@@ -237,6 +238,8 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
     MI.eraseFromParent();
     return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
   }
+  case TargetOpcode::G_SEXT_INREG:
+    return selectSExtInreg(MI, MIB);
   default:
     return false;
   }
@@ -363,6 +366,29 @@ bool RISCVInstructionSelector::selectConstant(MachineInstr &MI,
   return true;
 }
 
+bool RISCVInstructionSelector::selectSExtInreg(MachineInstr &MI,
+                                               MachineIRBuilder &MIB) const {
+  if (!STI.isRV64())
+    return false;
+
+  const MachineOperand &Size = MI.getOperand(2);
+  // Only Size == 32 (i.e. shift by 32 bits) is acceptable at this point.
+  if (!Size.isImm() || Size.getImm() != 32)
+    return false;
+
+  const MachineOperand &Src = MI.getOperand(1);
+  const MachineOperand &Dst = MI.getOperand(0);
+  // addiw rd, rs, 0 (i.e. sext.w rd, rs)
+  MachineInstr *NewMI =
+      MIB.buildInstr(RISCV::ADDIW, {Dst.getReg()}, {Src.getReg()}).addImm(0U);
+
+  if (!constrainSelectedInstRegOperands(*NewMI, TII, TRI, RBI))
+    return false;
+
+  MI.eraseFromParent();
+  return true;
+}
+
 namespace llvm {
 InstructionSelector *
 createRISCVInstructionSelector(const RISCVTargetMachine &TM,

diff  --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td
index 070bb3b42a07c54..8059b517f26ba3c 100644
--- a/llvm/lib/Target/RISCV/RISCVGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVGISel.td
@@ -42,6 +42,8 @@ def : Pat<(i32 (sub GPR:$rs1, GPR:$rs2)), (SUBW GPR:$rs1, GPR:$rs2)>;
 def : Pat<(i32 (shl GPR:$rs1, (i32 GPR:$rs2))), (SLLW GPR:$rs1, GPR:$rs2)>;
 def : Pat<(i32 (sra GPR:$rs1, (i32 GPR:$rs2))), (SRAW GPR:$rs1, GPR:$rs2)>;
 def : Pat<(i32 (srl GPR:$rs1, (i32 GPR:$rs2))), (SRLW GPR:$rs1, GPR:$rs2)>;
+
+def: Pat<(i64 (sext i32:$rs)), (ADDIW GPR:$rs, 0)>;
 }
 
 let Predicates = [HasStdExtMOrZmmul, IsRV64] in {
@@ -54,3 +56,9 @@ def : Pat<(i32 (srem GPR:$rs1, GPR:$rs2)), (REMW GPR:$rs1, GPR:$rs2)>;
 def : Pat<(i32 (udiv GPR:$rs1, GPR:$rs2)), (DIVUW GPR:$rs1, GPR:$rs2)>;
 def : Pat<(i32 (urem GPR:$rs1, GPR:$rs2)), (REMUW GPR:$rs1, GPR:$rs2)>;
 }
+
+let Predicates = [HasStdExtZba, IsRV64] in
+def : Pat<(i64 (zext i32:$rs)), (ADD_UW GPR:$rs, (XLenVT X0))>;
+
+let Predicates = [IsRV64, NotHasStdExtZba] in
+def: Pat<(i64 (zext i32:$rs)), (SRLI (SLLI GPR:$rs, 32), 32)>;

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/sext-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/sext-rv64.mir
new file mode 100644
index 000000000000000..50b1257c4ffec74
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/sext-rv64.mir
@@ -0,0 +1,32 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
+# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+---
+name:            sext_32_64
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    ; CHECK-LABEL: name: sext_32_64
+    ; CHECK: [[LUI:%[0-9]+]]:gpr = LUI 524288
+    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], 0
+    ; CHECK-NEXT: $x8 = COPY [[ADDIW]]
+    %0:gprb(s32) = G_CONSTANT i32 -2147483648
+    %1:gprb(s64) = G_SEXT %0
+    $x8 = COPY %1(s64)
+...
+---
+name:            sext_inreg_64_32
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    ; CHECK-LABEL: name: sext_inreg_64_32
+    ; CHECK: [[LUI:%[0-9]+]]:gpr = LUI 524288
+    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], 0
+    ; CHECK-NEXT: $x8 = COPY [[ADDIW]]
+    %0:gprb(s64) = G_CONSTANT i64 -2147483648
+    %1:gprb(s64) = G_SEXT_INREG %0, 32
+    $x8 = COPY %1(s64)
+...

diff  --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/zext-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/zext-rv64.mir
new file mode 100644
index 000000000000000..687be8a13932fe0
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/zext-rv64.mir
@@ -0,0 +1,24 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
+# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -verify-machineinstrs -mattr='+zba' %s -o - | FileCheck %s --check-prefix=ZBA
+---
+name:            zext_32_64
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+body:            |
+  bb.0:
+    ; CHECK-LABEL: name: zext_32_64
+    ; CHECK: [[LUI:%[0-9]+]]:gpr = LUI 524288
+    ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[LUI]], 32
+    ; CHECK-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[SLLI]], 32
+    ; CHECK-NEXT: $x8 = COPY [[SRLI]]
+    ;
+    ; ZBA-LABEL: name: zext_32_64
+    ; ZBA: [[LUI:%[0-9]+]]:gpr = LUI 524288
+    ; ZBA-NEXT: [[ADD_UW:%[0-9]+]]:gpr = ADD_UW [[LUI]], $x0
+    ; ZBA-NEXT: $x8 = COPY [[ADD_UW]]
+    %0:gprb(s32) = G_CONSTANT i32 -2147483648
+    %1:gprb(s64) = G_ZEXT %0
+    $x8 = COPY %1(s64)
+...


        


More information about the llvm-commits mailing list