diff options
author | Carl Ritson <carl.ritson@amd.com> | 2024-02-07 16:46:00 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-07 16:46:00 +0900 |
commit | 9bda1de0b6096d26e87fed18cb681cc3e5b8319a (patch) | |
tree | da4f16feb6363ccd0b85ffb5fd97e930291c6059 /llvm/lib/CodeGen/TwoAddressInstructionPass.cpp | |
parent | ea4f44e85f7ca884d42b9b12bd13bab47c3e5d3c (diff) | |
download | llvm-9bda1de0b6096d26e87fed18cb681cc3e5b8319a.zip llvm-9bda1de0b6096d26e87fed18cb681cc3e5b8319a.tar.gz llvm-9bda1de0b6096d26e87fed18cb681cc3e5b8319a.tar.bz2 |
[TwoAddressInstruction] Propagate undef flags for partial defs (#79286)
If part of a register (lowered from REG_SEQUENCE) is undefined then we
should propagate undef flags to uses of those lanes. This is only
performed when live intervals are present as it requires live intervals
to correctly match uses to defs, and the primary goal is to allow
precise computation of subrange intervals.
Diffstat (limited to 'llvm/lib/CodeGen/TwoAddressInstructionPass.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TwoAddressInstructionPass.cpp | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index 74d7904..ebacbc4 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1929,21 +1929,27 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { Register DstReg = MI.getOperand(0).getReg(); SmallVector<Register, 4> OrigRegs; + VNInfo *DefVN = nullptr; if (LIS) { OrigRegs.push_back(MI.getOperand(0).getReg()); for (unsigned i = 1, e = MI.getNumOperands(); i < e; i += 2) OrigRegs.push_back(MI.getOperand(i).getReg()); + if (LIS->hasInterval(DstReg)) { + DefVN = LIS->getInterval(DstReg) + .Query(LIS->getInstructionIndex(MI)) + .valueOut(); + } } + LaneBitmask UndefLanes = LaneBitmask::getNone(); bool DefEmitted = false; - bool DefIsPartial = false; for (unsigned i = 1, e = MI.getNumOperands(); i < e; i += 2) { MachineOperand &UseMO = MI.getOperand(i); Register SrcReg = UseMO.getReg(); unsigned SubIdx = MI.getOperand(i+1).getImm(); // Nothing needs to be inserted for undef operands. if (UseMO.isUndef()) { - DefIsPartial = true; + UndefLanes |= TRI->getSubRegIndexLaneMask(SubIdx); continue; } @@ -1991,11 +1997,25 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { MI.removeOperand(j); } else { if (LIS) { - // Force interval recomputation if we moved from full definition - // of register to partial. - if (DefIsPartial && LIS->hasInterval(DstReg) && - MRI->shouldTrackSubRegLiveness(DstReg)) + // Force live interval recomputation if we moved to a partial definition + // of the register. Undef flags must be propagate to uses of undefined + // subregister for accurate interval computation. + if (UndefLanes.any() && DefVN && MRI->shouldTrackSubRegLiveness(DstReg)) { + auto &LI = LIS->getInterval(DstReg); + for (MachineOperand &UseOp : MRI->use_operands(DstReg)) { + unsigned SubReg = UseOp.getSubReg(); + if (UseOp.isUndef() || !SubReg) + continue; + auto *VN = + LI.getVNInfoAt(LIS->getInstructionIndex(*UseOp.getParent())); + if (DefVN != VN) + continue; + LaneBitmask LaneMask = TRI->getSubRegIndexLaneMask(SubReg); + if ((UndefLanes & LaneMask).any()) + UseOp.setIsUndef(true); + } LIS->removeInterval(DstReg); + } LIS->RemoveMachineInstrFromMaps(MI); } |