[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