[llvm] 5ecb37b - [RISCV] Make InitUndef handle undef operand (#65755)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 23:04:50 PST 2023
Author: Piyou Chen
Date: 2023-12-01T01:04:42-06:00
New Revision: 5ecb37b45aa059cadd97ab6aedc1320da609c636
URL: https://github.com/llvm/llvm-project/commit/5ecb37b45aa059cadd97ab6aedc1320da609c636
DIFF: https://github.com/llvm/llvm-project/commit/5ecb37b45aa059cadd97ab6aedc1320da609c636.diff
LOG: [RISCV] Make InitUndef handle undef operand (#65755)
Address https://github.com/llvm/llvm-project/issues/65704.
If the operand is marked as undef, the InitUndef misses this case. This patch makes InitUndef pass handle the undef operand case.
Added:
llvm/test/CodeGen/RISCV/65704-illegal-instruction.ll
Modified:
llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp
llvm/test/CodeGen/RISCV/rvv/handle-noreg-with-implicit-def.mir
llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp b/llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp
index f519e3b2fd3b111..ff7718c9ef6d937 100644
--- a/llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp
@@ -80,13 +80,13 @@ class RISCVInitUndef : public MachineFunctionPass {
private:
bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB,
const DeadLaneDetector &DLD);
- bool handleImplicitDef(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator &Inst);
bool isVectorRegClass(const Register R);
const TargetRegisterClass *
getVRLargestSuperClass(const TargetRegisterClass *RC) const;
bool handleSubReg(MachineFunction &MF, MachineInstr &MI,
const DeadLaneDetector &DLD);
+ bool fixupIllOperand(MachineInstr *MI, MachineOperand &MO);
+ bool handleReg(MachineInstr *MI);
};
} // end anonymous namespace
@@ -137,53 +137,30 @@ static bool isEarlyClobberMI(MachineInstr &MI) {
});
}
-bool RISCVInitUndef::handleImplicitDef(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator &Inst) {
- assert(Inst->getOpcode() == TargetOpcode::IMPLICIT_DEF);
-
- Register Reg = Inst->getOperand(0).getReg();
- if (!Reg.isVirtual())
- return false;
-
- bool HasOtherUse = false;
- SmallVector<MachineOperand *, 1> UseMOs;
- for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
- if (isEarlyClobberMI(*MO.getParent())) {
- if (MO.isUse() && !MO.isTied())
- UseMOs.push_back(&MO);
- else
- HasOtherUse = true;
- }
+static bool findImplictDefMIFromReg(Register Reg, MachineRegisterInfo *MRI) {
+ for (auto &DefMI : MRI->def_instructions(Reg)) {
+ if (DefMI.getOpcode() == TargetOpcode::IMPLICIT_DEF)
+ return true;
}
+ return false;
+}
- if (UseMOs.empty())
- return false;
-
- LLVM_DEBUG(
- dbgs() << "Emitting PseudoRVVInitUndef for implicit vector register "
- << Reg << '\n');
-
- const TargetRegisterClass *TargetRegClass =
- getVRLargestSuperClass(MRI->getRegClass(Reg));
- unsigned Opcode = getUndefInitOpcode(TargetRegClass->getID());
-
- Register NewDest = Reg;
- if (HasOtherUse) {
- NewDest = MRI->createVirtualRegister(TargetRegClass);
- // We don't have a way to update dead lanes, so keep track of the
- // new register so that we avoid querying it later.
- NewRegs.insert(NewDest);
- }
- BuildMI(MBB, Inst, Inst->getDebugLoc(), TII->get(Opcode), NewDest);
-
- if (!HasOtherUse)
- DeadInsts.push_back(&(*Inst));
+bool RISCVInitUndef::handleReg(MachineInstr *MI) {
+ bool Changed = false;
+ for (auto &UseMO : MI->uses()) {
+ if (!UseMO.isReg())
+ continue;
+ if (UseMO.isTied())
+ continue;
+ if (!UseMO.getReg().isVirtual())
+ continue;
+ if (!isVectorRegClass(UseMO.getReg()))
+ continue;
- for (auto MO : UseMOs) {
- MO->setReg(NewDest);
- MO->setIsUndef(false);
+ if (UseMO.isUndef() || findImplictDefMIFromReg(UseMO.getReg(), MRI))
+ Changed |= fixupIllOperand(MI, UseMO);
}
- return true;
+ return Changed;
}
bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
@@ -248,6 +225,23 @@ bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
return Changed;
}
+bool RISCVInitUndef::fixupIllOperand(MachineInstr *MI, MachineOperand &MO) {
+
+ LLVM_DEBUG(
+ dbgs() << "Emitting PseudoRVVInitUndef for implicit vector register "
+ << MO.getReg() << '\n');
+
+ const TargetRegisterClass *TargetRegClass =
+ getVRLargestSuperClass(MRI->getRegClass(MO.getReg()));
+ unsigned Opcode = getUndefInitOpcode(TargetRegClass->getID());
+ Register NewReg = MRI->createVirtualRegister(TargetRegClass);
+ BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), TII->get(Opcode), NewReg);
+ MO.setReg(NewReg);
+ if (MO.isUndef())
+ MO.setIsUndef(false);
+ return true;
+}
+
bool RISCVInitUndef::processBasicBlock(MachineFunction &MF,
MachineBasicBlock &MBB,
const DeadLaneDetector &DLD) {
@@ -274,12 +268,10 @@ bool RISCVInitUndef::processBasicBlock(MachineFunction &MF,
}
}
- if (ST->enableSubRegLiveness() && isEarlyClobberMI(MI))
- Changed |= handleSubReg(MF, MI, DLD);
- if (MI.isImplicitDef()) {
- auto DstReg = MI.getOperand(0).getReg();
- if (DstReg.isVirtual() && isVectorRegClass(DstReg))
- Changed |= handleImplicitDef(MBB, I);
+ if (isEarlyClobberMI(MI)) {
+ if (ST->enableSubRegLiveness())
+ Changed |= handleSubReg(MF, MI, DLD);
+ Changed |= handleReg(&MI);
}
}
return Changed;
diff --git a/llvm/test/CodeGen/RISCV/65704-illegal-instruction.ll b/llvm/test/CodeGen/RISCV/65704-illegal-instruction.ll
new file mode 100644
index 000000000000000..3181fa60cfa23af
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/65704-illegal-instruction.ll
@@ -0,0 +1,57 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc -mtriple=riscv64 -mattr=+v,+f,+m,+zfh,+zvfh \
+; RUN: < %s | FileCheck %s
+
+declare <16 x i8> @llvm.vector.extract.v16i8.nxv8i8(<vscale x 8 x i8>, i64 immarg)
+declare <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v16i8(<vscale x 8 x i8>, <16 x i8>, i64 immarg)
+declare <vscale x 8 x i8> @llvm.riscv.vslideup.nxv8i8.i64(<vscale x 8 x i8>, <vscale x 8 x i8>, i64, i64, i64 immarg)
+declare <vscale x 2 x i32> @llvm.vector.insert.nxv2i32.v4i32(<vscale x 2 x i32>, <4 x i32>, i64 immarg)
+
+define void @foo(<vscale x 8 x i8> %0) {
+; CHECK-LABEL: foo:
+; CHECK: # %bb.0:
+; CHECK-NEXT: addi sp, sp, -32
+; CHECK-NEXT: .cfi_def_cfa_offset 32
+; CHECK-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; CHECK-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; CHECK-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
+; CHECK-NEXT: .cfi_offset ra, -8
+; CHECK-NEXT: .cfi_offset s0, -16
+; CHECK-NEXT: .cfi_offset s1, -24
+; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
+; CHECK-NEXT: vmv.v.i v9, 0
+; CHECK-NEXT: vsetivli zero, 0, e8, m1, tu, ma
+; CHECK-NEXT: vslideup.vi v9, v10, 0
+; CHECK-NEXT: vsetivli zero, 1, e64, m1, ta, ma
+; CHECK-NEXT: vmv.x.s s0, v9
+; CHECK-NEXT: vsetivli zero, 0, e8, m1, tu, ma
+; CHECK-NEXT: vslideup.vi v8, v9, 0
+; CHECK-NEXT: vsetivli zero, 1, e64, m1, ta, ma
+; CHECK-NEXT: vmv.x.s s1, v8
+; CHECK-NEXT: .LBB0_1: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: li a1, 0
+; CHECK-NEXT: mv a0, s0
+; CHECK-NEXT: mv a2, s1
+; CHECK-NEXT: li a3, 0
+; CHECK-NEXT: li a4, 0
+; CHECK-NEXT: li a5, 0
+; CHECK-NEXT: jalr a1
+; CHECK-NEXT: j .LBB0_1
+ %2 = tail call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v16i8(<vscale x 8 x i8> undef, <16 x i8> undef, i64 0)
+ %3 = tail call <vscale x 8 x i8> @llvm.vector.insert.nxv8i8.v16i8(<vscale x 8 x i8> undef, <16 x i8> poison, i64 0)
+ br label %4
+
+4: ; preds = %4, %1
+ %5 = tail call <vscale x 8 x i8> @llvm.riscv.vslideup.nxv8i8.i64(<vscale x 8 x i8> zeroinitializer, <vscale x 8 x i8> %2, i64 0, i64 0, i64 0)
+ %6 = tail call <16 x i8> @llvm.vector.extract.v16i8.nxv8i8(<vscale x 8 x i8> %5, i64 0)
+ %7 = bitcast <16 x i8> %6 to <2 x i64>
+ %8 = extractelement <2 x i64> %7, i64 0
+ %9 = insertvalue [2 x i64] zeroinitializer, i64 %8, 0
+ %10 = tail call <vscale x 8 x i8> @llvm.riscv.vslideup.nxv8i8.i64(<vscale x 8 x i8> %0, <vscale x 8 x i8> %3, i64 0, i64 0, i64 0)
+ %11 = tail call <16 x i8> @llvm.vector.extract.v16i8.nxv8i8(<vscale x 8 x i8> %10, i64 0)
+ %12 = bitcast <16 x i8> %11 to <2 x i64>
+ %13 = extractelement <2 x i64> %12, i64 0
+ %14 = insertvalue [2 x i64] zeroinitializer, i64 %13, 0
+ %15 = tail call fastcc [2 x i64] null([2 x i64] %9, [2 x i64] %14, [2 x i64] zeroinitializer)
+ br label %4
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/handle-noreg-with-implicit-def.mir b/llvm/test/CodeGen/RISCV/rvv/handle-noreg-with-implicit-def.mir
index 9ed3de951d03a0d..4102aa8aa4d723f 100644
--- a/llvm/test/CodeGen/RISCV/rvv/handle-noreg-with-implicit-def.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/handle-noreg-with-implicit-def.mir
@@ -7,9 +7,10 @@ tracksRegLiveness: true
body: |
bb.0.entry:
; MIR-LABEL: name: vrgather_all_undef
- ; MIR: [[PseudoRVVInitUndefM1_:%[0-9]+]]:vr = PseudoRVVInitUndefM1
- ; MIR-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
- ; MIR-NEXT: early-clobber %1:vr = PseudoVRGATHER_VI_M1 [[DEF]], killed [[PseudoRVVInitUndefM1_]], 0, 0, 5 /* e32 */, 0 /* tu, mu */
+ ; MIR: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; MIR-NEXT: [[DEF1:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; MIR-NEXT: [[PseudoRVVInitUndefM1_:%[0-9]+]]:vr = PseudoRVVInitUndefM1
+ ; MIR-NEXT: early-clobber %1:vr = PseudoVRGATHER_VI_M1 [[DEF1]], killed [[PseudoRVVInitUndefM1_]], 0, 0, 5 /* e32 */, 0 /* tu, mu */
; MIR-NEXT: $v8 = COPY %1
; MIR-NEXT: PseudoRET implicit $v8
%2:vr = IMPLICIT_DEF
diff --git a/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir b/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir
index 08ea967179ebf83..58b2687824aa146 100644
--- a/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir
@@ -76,9 +76,9 @@ machineFunctionInfo:
body: |
bb.0.entry:
; CHECK-LABEL: name: undef_early_clobber_chain
- ; CHECK: [[PseudoRVVInitUndefM1_:%[0-9]+]]:vr = PseudoRVVInitUndefM1
- ; CHECK-NEXT: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
+ ; CHECK: [[DEF:%[0-9]+]]:vr = IMPLICIT_DEF
; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 0, 208 /* e32, m1, ta, ma */, implicit-def $vl, implicit-def $vtype
+ ; CHECK-NEXT: [[PseudoRVVInitUndefM1_:%[0-9]+]]:vr = PseudoRVVInitUndefM1
; CHECK-NEXT: early-clobber %1:vr = PseudoVRGATHER_VI_M1 undef [[DEF]], [[PseudoRVVInitUndefM1_]], 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: $v8 = COPY %1
; CHECK-NEXT: PseudoRET implicit $v8
More information about the llvm-commits
mailing list