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

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


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/67359.diff


5 Files Affected:

- (modified) llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp (+29) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+6) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZb.td (+2) 
- (added) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/sext-rv64.mir (+32) 
- (added) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/zext-rv64.mir (+24) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 4a4be79528545f8..0149a8772f7d5e2 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,32 @@ 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);
+  assert(Src.isReg() && Dst.isReg());
+  // addiw rd, rs, 0 (i.e. sext.w rd, rs)
+  MachineInstr *NewMI = MIB.buildInstr(RISCV::ADDIW)
+                            .addDef(Dst.getReg())
+                            .addReg(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/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index abbeff78b6e2864..12ec4e2c9b46b2c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1774,6 +1774,12 @@ let Predicates = [IsRV64], hasSideEffects = 0, mayLoad = 0, mayStore = 0,
 def PseudoZEXT_W : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.w", "$rd, $rs">;
 } // Predicates = [IsRV64], ...
 
+let Predicates = [IsRV64] in
+def: Pat<(i64 (sext i32:$rs)), (ADDIW GPR:$rs, 0)>;
+
+let Predicates = [IsRV64, NotHasStdExtZba] in
+def: Pat<(i64 (zext i32:$rs)), (SRLI (SLLI GPR:$rs, 32), 32)>;
+
 /// Loads
 
 class LdPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT>
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
index a21c3d132636bea..8467acdd8148411 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
@@ -727,6 +727,8 @@ def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)),
 } // Predicates = [HasStdExtZba]
 
 let Predicates = [HasStdExtZba, IsRV64] in {
+def : Pat<(i64 (zext i32:$rs)), (ADD_UW GPR:$rs, (XLenVT X0))>;
+
 def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
           (SLLI_UW GPR:$rs1, uimm5:$shamt)>;
 // Match a shifted 0xffffffff mask. Use SRLI to clear the LSBs and SLLI_UW to
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)
+...

``````````

</details>


https://github.com/llvm/llvm-project/pull/67359


More information about the llvm-commits mailing list