[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