[PATCH] D157806: [BPF] Fix in/out argument constraints for CORE_MEM instructions
Eduard Zingerman via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 13 15:29:56 PDT 2023
eddyz87 added a comment.
In D157806#4583421 <https://reviews.llvm.org/D157806#4583421>, @yonghong-song wrote:
> ... Another solution is similar to D157805 <https://reviews.llvm.org/D157805> where we can clear 'killed' for the 'out' parameter, right?
The error is reported by the following code in the `MachineVerifier.cpp`:
void
MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
const MachineInstr *MI = MO->getParent();
const MCInstrDesc &MCID = MI->getDesc();
unsigned NumDefs = MCID.getNumDefs();
if (MCID.getOpcode() == TargetOpcode::PATCHPOINT)
NumDefs = (MONum == 0 && MO->isReg()) ? NumDefs : 0;
// The first MCID.NumDefs operands must be explicit register defines
if (MONum < NumDefs) {
const MCOperandInfo &MCOI = MCID.operands()[MONum];
if (!MO->isReg())
report("Explicit definition must be a register", MO, MONum);
else if (!MO->isDef() && !MCOI.isOptionalDef())
report("Explicit definition marked as use", MO, MONum); <---- error is reported here
else if (MO->isImplicit())
report("Explicit definition marked as implicit", MO, MONum);
} else if (...) {
...
}
...
}
As far as I understand this code:
- `MCID` is a static information about instruction, generated from the `td` file;
- `MCID.getNumDefs()` is the number of values specified in the `outs` part of the pattern (e.g. for `CORE_MEM` outs defined as `(outs GPR:$dst)`, hence `getNumDefs()` returns `1`);
- to satisfy the above check on the machine operand level the following change is needed:
@@ -146,8 +147,11 @@ void BPFMISimplifyPatchable::checkADDrr(MachineRegisterInfo *MRI,
continue;
}
+ MachineOperand &FirstMO = DefInst->getOperand(0);
+ FirstMO.setIsKill(false); // Can't setIsDef(true) if kill is set
+ FirstMO.setIsDef(true);
BuildMI(*DefInst->getParent(), *DefInst, DefInst->getDebugLoc(), TII->get(COREOp))
- .add(DefInst->getOperand(0)).addImm(Opcode).add(*BaseOp)
+ .add(FirstMO).addImm(Opcode).add(*BaseOp)
.addGlobalAddress(GVal);
DefInst->eraseFromParent();
}
But this is not conservative for stores (as store does not define it's first operand) and also leads to incorrect SSA form, which is reported by the MachineVerifier:
bb.0.entry:
liveins: $r1
DBG_VALUE $r1, $noreg, !"t", !DIExpression(), debug-location !18; t.c:0 line no:5
%0:gpr = COPY $r1
DBG_VALUE %0:gpr, $noreg, !"t", !DIExpression(), debug-location !18; t.c:0 line no:5
%1:gpr = LD_imm64 @"llvm.t:0:0$0:0"
%3:gpr = ADD_rr %0:gpr(tied-def 0), killed %1:gpr
%4:gpr = MOV_ri 42
%4:gpr = CORE_MEM 411, %0:gpr, @"llvm.t:0:0$0:0", debug-location !19; t.c:6:8
RET debug-location !25; t.c:7:1
# End machine code for function test.
*** Bad machine code: Multiple virtual register defs in SSA form ***
- function: test
- basic block: %bb.0 entry (0x621000068290)
- instruction: %4:gpr = MOV_ri 42
- operand 0: %4:gpr
*** Bad machine code: Multiple virtual register defs in SSA form ***
- function: test
- basic block: %bb.0 entry (0x621000068290)
- instruction: %4:gpr = CORE_MEM 411, %0:gpr, @"llvm.t:0:0$0:0", debug-location !19; t.c:6:8
- operand 0: %4:gpr
Which complains about two definitions for `%4`.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D157806/new/
https://reviews.llvm.org/D157806
More information about the llvm-commits
mailing list