[llvm] [BPF] improve error handling by custom lowering & fail() (PR #75088)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 12 08:30:03 PST 2023
eddyz87 wrote:
Hi @inclyc, thank you for working on this.
I think these chages are fine.
The the default `Expand` action for sdiv/srem does not help us, because they rely on `ISD::SDIVREM` / `ISD::UDIVREM` that we don't support either.
<details>
<summary><code>Expand</code> implementation code</summary>
```c++
bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
...
case ISD::UREM:
case ISD::SREM:
if (TLI.expandREM(Node, Tmp1, DAG))
Results.push_back(Tmp1);
break;
case ISD::UDIV:
case ISD::SDIV: {
bool isSigned = Node->getOpcode() == ISD::SDIV;
unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM;
EVT VT = Node->getValueType(0);
if (TLI.isOperationLegalOrCustom(DivRemOpc, VT)) {
SDVTList VTs = DAG.getVTList(VT, VT);
Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Node->getOperand(0),
Node->getOperand(1));
Results.push_back(Tmp1);
}
break;
}
...
}
bool TargetLowering::expandREM(SDNode *Node, SDValue &Result,
SelectionDAG &DAG) const {
EVT VT = Node->getValueType(0);
SDLoc dl(Node);
bool isSigned = Node->getOpcode() == ISD::SREM;
unsigned DivOpc = isSigned ? ISD::SDIV : ISD::UDIV;
unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM;
SDValue Dividend = Node->getOperand(0);
SDValue Divisor = Node->getOperand(1);
if (isOperationLegalOrCustom(DivRemOpc, VT)) {
SDVTList VTs = DAG.getVTList(VT, VT);
Result = DAG.getNode(DivRemOpc, dl, VTs, Dividend, Divisor).getValue(1);
return true;
}
if (isOperationLegalOrCustom(DivOpc, VT)) {
// X % Y -> X-X/Y*Y
SDValue Divide = DAG.getNode(DivOpc, dl, VT, Dividend, Divisor);
SDValue Mul = DAG.getNode(ISD::MUL, dl, VT, Divide, Divisor);
Result = DAG.getNode(ISD::SUB, dl, VT, Dividend, Mul);
return true;
}
return false;
}
```
</details>
As a nitpick, there is no test for error reported on `srem`.
https://github.com/llvm/llvm-project/pull/75088
More information about the llvm-commits
mailing list