Skip to content

Commit ce6e5b0

Browse files
authored
[LLVM][XTHeadVector] Fix RISCVInsertVSETVLI: handle hasAVLImm and constrain temporary register to be GPRNoX0 (llvm#121)
* [LLVM][XTHeadVector] Fix `Info.hasAVLImm()` branch and constrain the temporary register to be `GPRNoX0` * [LLVM][XTHeadVector] Update corresponding tests
1 parent c2195e8 commit ce6e5b0

File tree

3 files changed

+121
-16
lines changed

3 files changed

+121
-16
lines changed

llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ static bool hasUndefinedMergeOp(const MachineInstr &MI,
172172
return true;
173173

174174
// If the tied operand is an IMPLICIT_DEF (or a REG_SEQUENCE whose operands
175-
// are solely IMPLICIT_DEFS), the pass through lanes are undefined.
175+
// are solely IMPLICIT_DEFS), the pass through lanes are undefined.
176176
const MachineOperand &UseMO = MI.getOperand(UseOpIdx);
177177
if (MachineInstr *UseMI = MRI.getVRegDef(UseMO.getReg())) {
178178
if (UseMI->isImplicitDef())
@@ -755,6 +755,10 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
755755
void doLocalPostpass(MachineBasicBlock &MBB);
756756
void doPRE(MachineBasicBlock &MBB);
757757
void insertReadVL(MachineBasicBlock &MBB);
758+
void emulateXTHeadVectorVSETIVLI(MachineBasicBlock &MBB,
759+
MachineBasicBlock::iterator &InsertPt,
760+
const DebugLoc &DL, const VSETVLIInfo &Info,
761+
uint64_t UImm);
758762
};
759763

760764
} // end anonymous namespace
@@ -916,11 +920,14 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
916920
}
917921

918922
if (Info.hasAVLImm()) {
919-
assert(!HasVendorXTHeadV && "XTHeadV extension does not support AVLImm");
920-
BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETIVLI))
921-
.addReg(RISCV::X0, RegState::Define | RegState::Dead)
922-
.addImm(Info.getAVLImm())
923-
.addImm(Info.encodeVTYPE());
923+
if (HasVendorXTHeadV) {
924+
emulateXTHeadVectorVSETIVLI(MBB, InsertPt, DL, Info, Info.getAVLImm());
925+
} else {
926+
BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETIVLI))
927+
.addReg(RISCV::X0, RegState::Define | RegState::Dead)
928+
.addImm(Info.getAVLImm())
929+
.addImm(Info.encodeVTYPE());
930+
}
924931
return;
925932
}
926933

@@ -943,15 +950,7 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
943950
}
944951
// Otherwise use an AVL of 0 to avoid depending on previous vl.
945952
if (HasVendorXTHeadV) {
946-
// Generate the equivalent of `vsetivli rd, uimm, vtypei` in RVV 0.7
947-
auto UImmR = MRI->createVirtualRegister(&RISCV::GPRRegClass);
948-
BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoLI))
949-
.addReg(UImmR, RegState::Define)
950-
.addImm(0);
951-
BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoTH_VSETVLI))
952-
.addReg(RISCV::X0, RegState::Define | RegState::Dead)
953-
.addReg(UImmR, RegState::Kill)
954-
.addImm(Info.encodeXTHeadVTYPE());
953+
emulateXTHeadVectorVSETIVLI(MBB, InsertPt, DL, Info, 0);
955954
} else {
956955
BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETIVLI))
957956
.addReg(RISCV::X0, RegState::Define | RegState::Dead)
@@ -980,6 +979,30 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
980979
.addImm(TypeI);
981980
}
982981

982+
void RISCVInsertVSETVLI::emulateXTHeadVectorVSETIVLI(
983+
MachineBasicBlock &MBB, MachineBasicBlock::iterator &InsertPt,
984+
const DebugLoc &DL, const VSETVLIInfo &Info, uint64_t UImm) {
985+
// RVV 1.0:
986+
// vsetvli rd, rs1, vtypei # rd = new vl, rs1 = AVL, vtypei = vtype
987+
// vsetivli rd, uimm, vtypei # rd = new vl, uimm = AVL, vtypei = vtype
988+
989+
// XTHeadVector:
990+
// vsetvli rd, rs1, vtypei # rd = new vl, rs1 = AVL, vtypei = new vtype
991+
992+
// Let's load the AVLImm to a temporary register and use it as AVL in vsetvli
993+
auto UImmR = MRI->createVirtualRegister(&RISCV::GPRRegClass);
994+
// PseudoTH_VSETVLI requires the rs1 to be a GPRNoX0 register.
995+
MRI->constrainRegClass(UImmR, &RISCV::GPRNoX0RegClass);
996+
997+
BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoLI))
998+
.addReg(UImmR, RegState::Define)
999+
.addImm(UImm);
1000+
BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoTH_VSETVLI))
1001+
.addReg(RISCV::X0, RegState::Define | RegState::Dead)
1002+
.addReg(UImmR, RegState::Kill)
1003+
.addImm(Info.encodeXTHeadVTYPE());
1004+
}
1005+
9831006
void RISCVInsertVSETVLI::insertVSETVLIForCOPY(MachineBasicBlock &MBB) {
9841007
auto findRegSequence = [] (const MachineBasicBlock& BB,
9851008
MachineBasicBlock::iterator I,
@@ -1709,7 +1732,7 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
17091732
insertReadVL(MBB);
17101733

17111734
if (HasVendorXTHeadV)
1712-
for (MachineBasicBlock &MBB : MF)
1735+
for (MachineBasicBlock &MBB : MF)
17131736
insertVSETVLIForCOPY(MBB);
17141737

17151738
BlockInfo.clear();

llvm/test/CodeGen/RISCV/rvv0p71/vmfirst.ll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ entry:
2222
ret iXLen %a
2323
}
2424

25+
define iXLen @intrinsic_vmfirst_m_nxv1i1_zero(<vscale x 1 x i1> %0) nounwind {
26+
; CHECK-LABEL: intrinsic_vmfirst_m_nxv1i1_zero:
27+
; CHECK: # %bb.0: # %entry
28+
; CHECK-NEXT: li a0, 0
29+
; CHECK-NEXT: th.vsetvli zero, a0, e64, m1, d1
30+
; CHECK-NEXT: th.vmfirst.m a0, v0
31+
; CHECK-NEXT: ret
32+
entry:
33+
%a = call iXLen @llvm.riscv.th.vmfirst.iXLen.nxv1i1(
34+
<vscale x 1 x i1> %0,
35+
iXLen 0)
36+
37+
ret iXLen %a
38+
}
39+
2540
declare iXLen @llvm.riscv.th.vmfirst.mask.iXLen.nxv1i1(
2641
<vscale x 1 x i1>,
2742
<vscale x 1 x i1>,
@@ -52,6 +67,32 @@ entry:
5267
ret iXLen %a
5368
}
5469

70+
define iXLen @intrinsic_vmfirst_mask_m_nxv1i1_zero(<vscale x 1 x i1> %0, <vscale x 1 x i1> %1) nounwind {
71+
; CHECK-LABEL: intrinsic_vmfirst_mask_m_nxv1i1_zero:
72+
; CHECK: # %bb.0: # %entry
73+
; CHECK-NEXT: csrr a0, vl
74+
; CHECK-NEXT: csrr a1, vtype
75+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
76+
; CHECK-NEXT: th.vmv.v.v v9, v0
77+
; CHECK-NEXT: th.vsetvl zero, a0, a1
78+
; CHECK-NEXT: csrr a0, vl
79+
; CHECK-NEXT: csrr a1, vtype
80+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
81+
; CHECK-NEXT: th.vmv.v.v v0, v8
82+
; CHECK-NEXT: th.vsetvl zero, a0, a1
83+
; CHECK-NEXT: li a0, 0
84+
; CHECK-NEXT: th.vsetvli zero, a0, e64, m1, d1
85+
; CHECK-NEXT: th.vmfirst.m a0, v9, v0.t
86+
; CHECK-NEXT: ret
87+
entry:
88+
%a = call iXLen @llvm.riscv.th.vmfirst.mask.iXLen.nxv1i1(
89+
<vscale x 1 x i1> %0,
90+
<vscale x 1 x i1> %1,
91+
iXLen 0)
92+
93+
ret iXLen %a
94+
}
95+
5596
declare iXLen @llvm.riscv.th.vmfirst.iXLen.nxv2i1(
5697
<vscale x 2 x i1>,
5798
iXLen);

llvm/test/CodeGen/RISCV/rvv0p71/vmpopc.ll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ entry:
2222
ret iXLen %a
2323
}
2424

25+
define iXLen @intrinsic_vmpopc_m_nxv1i1_zero(<vscale x 1 x i1> %0) nounwind {
26+
; CHECK-LABEL: intrinsic_vmpopc_m_nxv1i1_zero:
27+
; CHECK: # %bb.0: # %entry
28+
; CHECK-NEXT: li a0, 0
29+
; CHECK-NEXT: th.vsetvli zero, a0, e64, m1, d1
30+
; CHECK-NEXT: th.vmpopc.m a0, v0
31+
; CHECK-NEXT: ret
32+
entry:
33+
%a = call iXLen @llvm.riscv.th.vmpopc.iXLen.nxv1i1(
34+
<vscale x 1 x i1> %0,
35+
iXLen 0)
36+
37+
ret iXLen %a
38+
}
39+
2540
declare iXLen @llvm.riscv.th.vmpopc.mask.iXLen.nxv1i1(
2641
<vscale x 1 x i1>,
2742
<vscale x 1 x i1>,
@@ -52,6 +67,32 @@ entry:
5267
ret iXLen %a
5368
}
5469

70+
define iXLen @intrinsic_vmpopc_mask_m_nxv1i1_zero(<vscale x 1 x i1> %0, <vscale x 1 x i1> %1) nounwind {
71+
; CHECK-LABEL: intrinsic_vmpopc_mask_m_nxv1i1_zero:
72+
; CHECK: # %bb.0: # %entry
73+
; CHECK-NEXT: csrr a0, vl
74+
; CHECK-NEXT: csrr a1, vtype
75+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
76+
; CHECK-NEXT: th.vmv.v.v v9, v0
77+
; CHECK-NEXT: th.vsetvl zero, a0, a1
78+
; CHECK-NEXT: csrr a0, vl
79+
; CHECK-NEXT: csrr a1, vtype
80+
; CHECK-NEXT: th.vsetvli zero, zero, e8, m1, d1
81+
; CHECK-NEXT: th.vmv.v.v v0, v8
82+
; CHECK-NEXT: th.vsetvl zero, a0, a1
83+
; CHECK-NEXT: li a0, 0
84+
; CHECK-NEXT: th.vsetvli zero, a0, e64, m1, d1
85+
; CHECK-NEXT: th.vmpopc.m a0, v9, v0.t
86+
; CHECK-NEXT: ret
87+
entry:
88+
%a = call iXLen @llvm.riscv.th.vmpopc.mask.iXLen.nxv1i1(
89+
<vscale x 1 x i1> %0,
90+
<vscale x 1 x i1> %1,
91+
iXLen 0)
92+
93+
ret iXLen %a
94+
}
95+
5596
declare iXLen @llvm.riscv.th.vmpopc.iXLen.nxv2i1(
5697
<vscale x 2 x i1>,
5798
iXLen);

0 commit comments

Comments
 (0)