[llvm] 9cf6759 - [RISCVRVVInitUndef] Remove implicit single use assumption for IMPLICIT_DEF
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 27 16:31:13 PDT 2023
Author: Philip Reames
Date: 2023-07-27T16:25:56-07:00
New Revision: 9cf675923afa73a3dbe575803ebbbe9146701df8
URL: https://github.com/llvm/llvm-project/commit/9cf675923afa73a3dbe575803ebbbe9146701df8
DIFF: https://github.com/llvm/llvm-project/commit/9cf675923afa73a3dbe575803ebbbe9146701df8.diff
LOG: [RISCVRVVInitUndef] Remove implicit single use assumption for IMPLICIT_DEF
The code was written with the implicit assumption that each IMPLICIT_DEF either a) the tied operand, or b) an untied source, but not both. This is true right now, but an upcoming change may allow CSE of IMPLICIT_DEFs in some cases, so let's rewrite the code to handle that possibility.
I added an MIR case which demonstrates the multiple use IMPLICIT_DEF. To my knowledge, this is not a reachable configuration from IR right now.
As an aside, this makes the structure a much closer match with the sub-reg liveness case, and we can probably just merge these routines. (Future work.)
Differential Revision: https://reviews.llvm.org/D156477
Added:
llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir
Modified:
llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp
llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp b/llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp
index fed3fa2987e52f..3bb1161f9b7042 100644
--- a/llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRVVInitUndef.cpp
@@ -118,65 +118,57 @@ static unsigned getUndefInitOpcode(unsigned RegClassID) {
}
}
+static bool isEarlyClobberMI(MachineInstr &MI) {
+ return llvm::any_of(MI.defs(), [](const MachineOperand &DefMO) {
+ return DefMO.isReg() && DefMO.isEarlyClobber();
+ });
+}
+
bool RISCVInitUndef::handleImplicitDef(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &Inst) {
- const TargetRegisterInfo &TRI =
- *MBB.getParent()->getSubtarget().getRegisterInfo();
-
assert(Inst->getOpcode() == TargetOpcode::IMPLICIT_DEF);
Register Reg = Inst->getOperand(0).getReg();
if (!Reg.isVirtual())
return false;
- bool NeedPseudoInit = false;
+ bool HasOtherUse = false;
SmallVector<MachineOperand *, 1> UseMOs;
for (MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
- MachineInstr *UserMI = MO.getParent();
-
- bool HasEarlyClobber = false;
- bool TiedToDef = false;
- for (MachineOperand &UserMO : UserMI->operands()) {
- if (!UserMO.isReg())
- continue;
- if (UserMO.isEarlyClobber())
- HasEarlyClobber = true;
- if (UserMO.isUse() && UserMO.isTied() &&
- TRI.regsOverlap(UserMO.getReg(), Reg))
- TiedToDef = true;
- }
- if (HasEarlyClobber && !TiedToDef) {
- NeedPseudoInit = true;
- UseMOs.push_back(&MO);
+ if (isEarlyClobberMI(*MO.getParent())) {
+ if (MO.isUse() && !MO.isTied())
+ UseMOs.push_back(&MO);
+ else
+ HasOtherUse = true;
}
}
- if (!NeedPseudoInit)
+ if (UseMOs.empty())
return false;
LLVM_DEBUG(
dbgs() << "Emitting PseudoRVVInitUndef for implicit vector register "
<< Reg << '\n');
- unsigned RegClassID = getVRLargestSuperClass(MRI->getRegClass(Reg))->getID();
- unsigned Opcode = getUndefInitOpcode(RegClassID);
+ const TargetRegisterClass *TargetRegClass =
+ getVRLargestSuperClass(MRI->getRegClass(Reg));
+ unsigned Opcode = getUndefInitOpcode(TargetRegClass->getID());
- BuildMI(MBB, Inst, Inst->getDebugLoc(), TII->get(Opcode), Reg);
+ Register NewDest = Reg;
+ if (HasOtherUse)
+ NewDest = MRI->createVirtualRegister(TargetRegClass);
+ BuildMI(MBB, Inst, Inst->getDebugLoc(), TII->get(Opcode), NewDest);
- Inst = MBB.erase(Inst);
+ if (!HasOtherUse)
+ Inst = MBB.erase(Inst);
- for (auto MO : UseMOs)
+ for (auto MO : UseMOs) {
+ MO->setReg(NewDest);
MO->setIsUndef(false);
-
+ }
return true;
}
-static bool isEarlyClobberMI(MachineInstr &MI) {
- return llvm::any_of(MI.defs(), [](const MachineOperand &DefMO) {
- return DefMO.isReg() && DefMO.isEarlyClobber();
- });
-}
-
bool RISCVInitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
const DeadLaneDetector &DLD) {
bool Changed = false;
diff --git a/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.ll b/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.ll
index 336136c0aa28c2..1fe6ecd6fcbc68 100644
--- a/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.ll
@@ -1,6 +1,17 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple riscv64 -mattr=+v -riscv-enable-subreg-liveness < %s | FileCheck %s
+define <vscale x 2 x float> @vrgather_all_undef(ptr %p) {
+; CHECK-LABEL: vrgather_all_undef:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetivli zero, 0, e32, m1, ta, ma
+; CHECK-NEXT: vrgather.vi v8, v9, 0
+; CHECK-NEXT: ret
+entry:
+ %0 = tail call <vscale x 2 x float> @llvm.riscv.vrgather.vx.nxv2f32.i64(<vscale x 2 x float> undef, <vscale x 2 x float> undef, i64 0, i64 0)
+ ret <vscale x 2 x float> %0
+}
+
define dso_local signext i32 @undef_early_clobber_chain() {
; CHECK-LABEL: undef_early_clobber_chain:
; CHECK: # %bb.0: # %entry
@@ -25,14 +36,14 @@ entry:
define internal void @SubRegLivenessUndefInPhi(i64 %cond) {
; CHECK-LABEL: SubRegLivenessUndefInPhi:
; CHECK: # %bb.0: # %start
-; CHECK-NEXT: blez a0, .LBB1_2
+; CHECK-NEXT: blez a0, .LBB2_2
; CHECK-NEXT: # %bb.1: # %Cond1
; CHECK-NEXT: vsetvli a0, zero, e16, mf4, ta, ma
; CHECK-NEXT: vid.v v8
; CHECK-NEXT: vadd.vi v10, v8, 1
; CHECK-NEXT: vadd.vi v12, v8, 3
-; CHECK-NEXT: j .LBB1_3
-; CHECK-NEXT: .LBB1_2: # %Cond2
+; CHECK-NEXT: j .LBB2_3
+; CHECK-NEXT: .LBB2_2: # %Cond2
; CHECK-NEXT: vsetvli a0, zero, e16, mf4, ta, ma
; CHECK-NEXT: vid.v v9
; CHECK-NEXT: csrr a0, vlenb
@@ -48,7 +59,7 @@ define internal void @SubRegLivenessUndefInPhi(i64 %cond) {
; CHECK-NEXT: vadd.vi v9, v9, 3
; CHECK-NEXT: vsetvli zero, a1, e16, m1, ta, ma
; CHECK-NEXT: vslideup.vx v12, v9, a0
-; CHECK-NEXT: .LBB1_3: # %UseSR
+; CHECK-NEXT: .LBB2_3: # %UseSR
; CHECK-NEXT: vl1r.v v14, (zero)
; CHECK-NEXT: vsetivli zero, 4, e8, m1, ta, ma
; CHECK-NEXT: vrgatherei16.vv v13, v14, v8
@@ -104,7 +115,7 @@ define internal void @SubRegLivenessUndef() {
; CHECK-NEXT: vid.v v8
; CHECK-NEXT: vadd.vi v10, v8, 1
; CHECK-NEXT: vadd.vi v12, v8, 3
-; CHECK-NEXT: .LBB2_1: # %loopIR3.i.i
+; CHECK-NEXT: .LBB3_1: # %loopIR3.i.i
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: vl1r.v v14, (zero)
; CHECK-NEXT: vsetivli zero, 4, e8, m1, ta, ma
@@ -117,7 +128,7 @@ define internal void @SubRegLivenessUndef() {
; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma
; CHECK-NEXT: vand.vv v9, v9, v11
; CHECK-NEXT: vs1r.v v9, (zero)
-; CHECK-NEXT: j .LBB2_1
+; CHECK-NEXT: j .LBB3_1
loopIR.preheader.i.i:
%v15 = tail call <vscale x 1 x i16> @llvm.experimental.stepvector.nxv1i16()
%v17 = tail call <vscale x 8 x i16> @llvm.vector.insert.nxv8i16.nxv1i16(<vscale x 8 x i16> poison, <vscale x 1 x i16> %v15, i64 0)
diff --git a/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir b/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir
new file mode 100644
index 00000000000000..08ea967179ebf8
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/undef-earlyclobber-chain.mir
@@ -0,0 +1,91 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=riscv32 -mattr=+v -riscv-enable-subreg-liveness -run-pass riscv-init-undef -run-pass machineverifier %s -o - | FileCheck %s
+
+--- |
+ source_filename = "<stdin>"
+ target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
+ target triple = "riscv64"
+
+ define <vscale x 2 x float> @undef_early_clobber_chain(ptr %p) #0 {
+ entry:
+ %0 = tail call <vscale x 2 x float> @llvm.riscv.vrgather.vx.nxv2f32.i64(<vscale x 2 x float> undef, <vscale x 2 x float> undef, i64 0, i64 0)
+ ret <vscale x 2 x float> %0
+ }
+
+ declare <vscale x 2 x float> @llvm.riscv.vrgather.vx.nxv2f32.i64(<vscale x 2 x float>, <vscale x 2 x float>, i64, i64) #1
+
+ attributes #0 = { "target-features"="+v" }
+ attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) "target-features"="+v" }
+
+...
+---
+name: undef_early_clobber_chain
+alignment: 4
+exposesReturnsTwice: false
+legalized: false
+regBankSelected: false
+selected: false
+failedISel: false
+tracksRegLiveness: true
+hasWinCFI: false
+callsEHReturn: false
+callsUnwindInit: false
+hasEHCatchret: false
+hasEHScopes: false
+hasEHFunclets: false
+isOutlined: false
+debugInstrRef: false
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+ - { id: 0, class: gpr, preferred-register: '' }
+ - { id: 1, class: vr, preferred-register: '' }
+ - { id: 2, class: vr, preferred-register: '' }
+ - { id: 3, class: vr, preferred-register: '' }
+liveins: []
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 0
+ offsetAdjustment: 0
+ maxAlignment: 1
+ adjustsStack: false
+ hasCalls: false
+ stackProtector: ''
+ functionContext: ''
+ maxCallFrameSize: 4294967295
+ cvBytesOfCalleeSavedRegisters: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+ hasTailCall: false
+ localFrameSize: 0
+ savePoint: ''
+ restorePoint: ''
+fixedStack: []
+stack: []
+entry_values: []
+callSites: []
+debugValueSubstitutions: []
+constants: []
+machineFunctionInfo:
+ varArgsFrameIndex: 0
+ varArgsSaveSize: 0
+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-NEXT: dead $x0 = PseudoVSETIVLI 0, 208 /* e32, m1, ta, ma */, implicit-def $vl, implicit-def $vtype
+ ; 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
+ %2:vr = IMPLICIT_DEF
+ dead $x0 = PseudoVSETIVLI 0, 208 /* e32, m1, ta, ma */, implicit-def $vl, implicit-def $vtype
+ early-clobber %1:vr = PseudoVRGATHER_VI_M1 undef %2, undef %2, 0, 0, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+ $v8 = COPY %1
+ PseudoRET implicit $v8
+
+...
More information about the llvm-commits
mailing list