Skip to content

Commit bc7d88f

Browse files
committed
CodeGen: Disable isCopyInstrImpl if there are implicit operands
This is a conservative workaround for broken liveness tracking of SUBREG_TO_REG to speculatively fix all targets. The current reported failures are on X86 only, but this issue should appear for all targets that use SUBREG_TO_REG. The next minimally correct refinement would be to disallow only implicit defs. The coalescer now introduces implicit-defs of the super register to track the dependency on other subregisters. If we see such an implicit operand, we cannot simply treat the subregister def as the result operand in case downstream users depend on the implicitly defined parts. Really target implementations should be considering the implicit defs and trying to interpret them appropriately (maybe with some generic helpers). The full implicit def could possibly be reported as the move result, rather than the subregister def but that requires additional work. Hopefully fixes #64060 as well. This needs to be applied to the release branch. https://reviews.llvm.org/D156346
1 parent e9b33d0 commit bc7d88f

File tree

5 files changed

+70
-51
lines changed

5 files changed

+70
-51
lines changed

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1036,10 +1036,29 @@ class TargetInstrInfo : public MCInstrInfo {
10361036
/// For COPY-instruction the method naturally returns destination and source
10371037
/// registers as machine operands, for all other instructions the method calls
10381038
/// target-dependent implementation.
1039-
std::optional<DestSourcePair> isCopyInstr(const MachineInstr &MI) const {
1039+
std::optional<DestSourcePair>
1040+
isCopyInstr(const MachineInstr &MI,
1041+
bool ForbidImplicitOperands = true) const {
10401042
if (MI.isCopy()) {
1043+
// TODO: Should validate implicit operands here?
10411044
return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
10421045
}
1046+
1047+
// TODO: This is a conservative hack to ensure correctness when extra
1048+
// operands are added for special liveness tracking, while also not changing
1049+
// debug info. In particular SUBREG_TO_REG may introduce an implicit-def of
1050+
// a super register after coalescing. This may manifest as a copy-like
1051+
// instruction with an undef subregister def, and a full register
1052+
// implicit-def appended to the operand list.
1053+
1054+
// Really, implementations of this should be considering extra implicit
1055+
// operands. A more sophisticated implementation would recognize an
1056+
// implicit-def of the full register, and report that as the
1057+
// destination. This should be removed when all targets are validated for
1058+
// correct SUBREG_TO_REG liveness handling.
1059+
if (ForbidImplicitOperands && MI.getNumImplicitOperands() != 0)
1060+
return std::nullopt;
1061+
10431062
return isCopyInstrImpl(MI);
10441063
}
10451064

llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2116,7 +2116,7 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
21162116
}
21172117

21182118
bool InstrRefBasedLDV::transferRegisterCopy(MachineInstr &MI) {
2119-
auto DestSrc = TII->isCopyInstr(MI);
2119+
auto DestSrc = TII->isCopyInstr(MI, false);
21202120
if (!DestSrc)
21212121
return false;
21222122

llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,7 @@ void VarLocBasedLDV::removeEntryValue(const MachineInstr &MI,
13641364
// TODO: Try to keep tracking of an entry value if we encounter a propagated
13651365
// DBG_VALUE describing the copy of the entry value. (Propagated entry value
13661366
// does not indicate the parameter modification.)
1367-
auto DestSrc = TII->isCopyInstr(*TransferInst);
1367+
auto DestSrc = TII->isCopyInstr(*TransferInst, false);
13681368
if (DestSrc) {
13691369
const MachineOperand *SrcRegOp, *DestRegOp;
13701370
SrcRegOp = DestSrc->Source;
@@ -1840,7 +1840,7 @@ void VarLocBasedLDV::transferRegisterCopy(MachineInstr &MI,
18401840
OpenRangesSet &OpenRanges,
18411841
VarLocMap &VarLocIDs,
18421842
TransferMap &Transfers) {
1843-
auto DestSrc = TII->isCopyInstr(MI);
1843+
auto DestSrc = TII->isCopyInstr(MI, false);
18441844
if (!DestSrc)
18451845
return;
18461846

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9176,7 +9176,7 @@ static std::optional<ParamLoadedValue>
91769176
describeORRLoadedValue(const MachineInstr &MI, Register DescribedReg,
91779177
const TargetInstrInfo *TII,
91789178
const TargetRegisterInfo *TRI) {
9179-
auto DestSrc = TII->isCopyInstr(MI);
9179+
auto DestSrc = TII->isCopyInstr(MI, false);
91809180
if (!DestSrc)
91819181
return std::nullopt;
91829182

0 commit comments

Comments
 (0)