Skip to content

Implicit Exec Mask Operand Missing From MCInstrDesc of Some Opcodes in AMDGPU backend #89830

Closed
@matinraayai

Description

@matinraayai

The following Opcodes do not have AMDGPU::EXEC mask as an implicit operand in their MC Instr Desc:
GLOBAL_STORE_DWORD_vi
BUFFER_LOAD_DWORD_OFFEN_vi
GLOBAL_STORE_DWORD_SADDR_vi
The issue appears when constructing a llvm::MachineInstr from a valid llvm::MCInst, in the same manner as llvm-exegesis here:

MachineInstrBuilder Builder = BuildMI(MBB, DL, MCID);
for (unsigned OpIndex = 0, E = Inst.getNumOperands(); OpIndex < E;
++OpIndex) {
const MCOperand &Op = Inst.getOperand(OpIndex);
if (Op.isReg()) {
const bool IsDef = OpIndex < MCID.getNumDefs();
unsigned Flags = 0;
const MCOperandInfo &OpInfo = MCID.operands().begin()[OpIndex];
if (IsDef && !OpInfo.isOptionalDef())
Flags |= RegState::Define;
Builder.addReg(Op.getReg(), Flags);
} else if (Op.isImm()) {
Builder.addImm(Op.getImm());
} else if (!Op.isValid()) {
llvm_unreachable("Operand is not set");
} else {
llvm_unreachable("Not yet implemented");
}
}
}

For the MIR to be correct, simply adding the explicit operands should be enough, as the implicit operands are automatically added according to the MCInstrDesc when calling the llvm::BuildMI here:
MachineInstrBuilder Builder = BuildMI(MBB, DL, MCID);

This method will call the llvm::MachineInstr constructor with NoImplicit flag set to false:

MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &TID,
DebugLoc DL, bool NoImp)
: MCID(&TID), NumOperands(0), Flags(0), AsmPrinterFlags(0),
DbgLoc(std::move(DL)), DebugInstrNum(0) {
assert(DbgLoc.hasTrivialDestructor() && "Expected trivial destructor");
// Reserve space for the expected number of operands.
if (unsigned NumOps = MCID->getNumOperands() + MCID->implicit_defs().size() +
MCID->implicit_uses().size()) {
CapOperands = OperandCapacity::get(NumOps);
Operands = MF.allocateOperandArray(CapOperands);
}
if (!NoImp)
addImplicitDefUseOperands(MF);
}

However, when printing the constructed MIR, the implicit exec is nowhere to be seen:

GLOBAL_STORE_DWORD_vi $vgpr0_vgpr1, $vgpr2, 0, 0
BUFFER_LOAD_DWORD_OFFEN_vi $vgpr3, $sgpr0_sgpr1_sgpr2_sgpr3, 0, 60, 0, 0
BUFFER_STORE_DWORD_OFFEN_vi $vgpr1, $vgpr3, $sgpr0_sgpr1_sgpr2_sgpr3, 0, 84, 0, 0

This causes issues when these instructions get verified before running CodeGen passes.

CC: @arsenm @kzhuravl

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions