Skip to content

Commit 0d7c340

Browse files
authored
[RISCV][GISel] Add instruction selection for G_SEXT, G_ZEXT, and G_SEXT_INREG (llvm#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.
1 parent f958381 commit 0d7c340

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class RISCVInstructionSelector : public InstructionSelector {
4848
bool selectCopy(MachineInstr &MI, MachineRegisterInfo &MRI) const;
4949
bool selectConstant(MachineInstr &MI, MachineIRBuilder &MIB,
5050
MachineRegisterInfo &MRI) const;
51+
bool selectSExtInreg(MachineInstr &MI, MachineIRBuilder &MIB) const;
5152

5253
bool earlySelectShift(unsigned Opc, MachineInstr &I, MachineIRBuilder &MIB,
5354
const MachineRegisterInfo &MRI);
@@ -237,6 +238,8 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
237238
MI.eraseFromParent();
238239
return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
239240
}
241+
case TargetOpcode::G_SEXT_INREG:
242+
return selectSExtInreg(MI, MIB);
240243
default:
241244
return false;
242245
}
@@ -363,6 +366,29 @@ bool RISCVInstructionSelector::selectConstant(MachineInstr &MI,
363366
return true;
364367
}
365368

369+
bool RISCVInstructionSelector::selectSExtInreg(MachineInstr &MI,
370+
MachineIRBuilder &MIB) const {
371+
if (!STI.isRV64())
372+
return false;
373+
374+
const MachineOperand &Size = MI.getOperand(2);
375+
// Only Size == 32 (i.e. shift by 32 bits) is acceptable at this point.
376+
if (!Size.isImm() || Size.getImm() != 32)
377+
return false;
378+
379+
const MachineOperand &Src = MI.getOperand(1);
380+
const MachineOperand &Dst = MI.getOperand(0);
381+
// addiw rd, rs, 0 (i.e. sext.w rd, rs)
382+
MachineInstr *NewMI =
383+
MIB.buildInstr(RISCV::ADDIW, {Dst.getReg()}, {Src.getReg()}).addImm(0U);
384+
385+
if (!constrainSelectedInstRegOperands(*NewMI, TII, TRI, RBI))
386+
return false;
387+
388+
MI.eraseFromParent();
389+
return true;
390+
}
391+
366392
namespace llvm {
367393
InstructionSelector *
368394
createRISCVInstructionSelector(const RISCVTargetMachine &TM,

llvm/lib/Target/RISCV/RISCVGISel.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ def : Pat<(i32 (sub GPR:$rs1, GPR:$rs2)), (SUBW GPR:$rs1, GPR:$rs2)>;
4242
def : Pat<(i32 (shl GPR:$rs1, (i32 GPR:$rs2))), (SLLW GPR:$rs1, GPR:$rs2)>;
4343
def : Pat<(i32 (sra GPR:$rs1, (i32 GPR:$rs2))), (SRAW GPR:$rs1, GPR:$rs2)>;
4444
def : Pat<(i32 (srl GPR:$rs1, (i32 GPR:$rs2))), (SRLW GPR:$rs1, GPR:$rs2)>;
45+
46+
def: Pat<(i64 (sext i32:$rs)), (ADDIW GPR:$rs, 0)>;
4547
}
4648

4749
let Predicates = [HasStdExtMOrZmmul, IsRV64] in {
@@ -54,3 +56,9 @@ def : Pat<(i32 (srem GPR:$rs1, GPR:$rs2)), (REMW GPR:$rs1, GPR:$rs2)>;
5456
def : Pat<(i32 (udiv GPR:$rs1, GPR:$rs2)), (DIVUW GPR:$rs1, GPR:$rs2)>;
5557
def : Pat<(i32 (urem GPR:$rs1, GPR:$rs2)), (REMUW GPR:$rs1, GPR:$rs2)>;
5658
}
59+
60+
let Predicates = [HasStdExtZba, IsRV64] in
61+
def : Pat<(i64 (zext i32:$rs)), (ADD_UW GPR:$rs, (XLenVT X0))>;
62+
63+
let Predicates = [IsRV64, NotHasStdExtZba] in
64+
def: Pat<(i64 (zext i32:$rs)), (SRLI (SLLI GPR:$rs, 32), 32)>;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
2+
# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
3+
---
4+
name: sext_32_64
5+
legalized: true
6+
regBankSelected: true
7+
tracksRegLiveness: true
8+
body: |
9+
bb.0:
10+
; CHECK-LABEL: name: sext_32_64
11+
; CHECK: [[LUI:%[0-9]+]]:gpr = LUI 524288
12+
; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], 0
13+
; CHECK-NEXT: $x8 = COPY [[ADDIW]]
14+
%0:gprb(s32) = G_CONSTANT i32 -2147483648
15+
%1:gprb(s64) = G_SEXT %0
16+
$x8 = COPY %1(s64)
17+
...
18+
---
19+
name: sext_inreg_64_32
20+
legalized: true
21+
regBankSelected: true
22+
tracksRegLiveness: true
23+
body: |
24+
bb.0:
25+
; CHECK-LABEL: name: sext_inreg_64_32
26+
; CHECK: [[LUI:%[0-9]+]]:gpr = LUI 524288
27+
; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LUI]], 0
28+
; CHECK-NEXT: $x8 = COPY [[ADDIW]]
29+
%0:gprb(s64) = G_CONSTANT i64 -2147483648
30+
%1:gprb(s64) = G_SEXT_INREG %0, 32
31+
$x8 = COPY %1(s64)
32+
...
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
2+
# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
3+
# RUN: llc -mtriple=riscv64 -run-pass=instruction-select -verify-machineinstrs -mattr='+zba' %s -o - | FileCheck %s --check-prefix=ZBA
4+
---
5+
name: zext_32_64
6+
legalized: true
7+
regBankSelected: true
8+
tracksRegLiveness: true
9+
body: |
10+
bb.0:
11+
; CHECK-LABEL: name: zext_32_64
12+
; CHECK: [[LUI:%[0-9]+]]:gpr = LUI 524288
13+
; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[LUI]], 32
14+
; CHECK-NEXT: [[SRLI:%[0-9]+]]:gpr = SRLI [[SLLI]], 32
15+
; CHECK-NEXT: $x8 = COPY [[SRLI]]
16+
;
17+
; ZBA-LABEL: name: zext_32_64
18+
; ZBA: [[LUI:%[0-9]+]]:gpr = LUI 524288
19+
; ZBA-NEXT: [[ADD_UW:%[0-9]+]]:gpr = ADD_UW [[LUI]], $x0
20+
; ZBA-NEXT: $x8 = COPY [[ADD_UW]]
21+
%0:gprb(s32) = G_CONSTANT i32 -2147483648
22+
%1:gprb(s64) = G_ZEXT %0
23+
$x8 = COPY %1(s64)
24+
...

0 commit comments

Comments
 (0)