Skip to content

Commit ddf85b9

Browse files
authored
[BPF] improve error handling by custom lowering & fail() (#75088)
Currently on mcpu=v3 we do not support sdiv, srem instructions. And the backend crashes with stacktrace & coredump, which is misleading for end users, as this is not a "bug" Add llvm bug reporting for sdiv/srem on ISel legalize-op phase. For clang frontend we can get detailed location & bug report. $ build/bin/clang -g -target bpf -c local/sdiv.c local/sdiv.c:1:35: error: unsupported signed division, please convert to unsigned div/mod. 1 | int sdiv(int a, int b) { return a / b; } | ^ 1 error generated. Fixes: #70433 Fixes: #48647 This also improves error handling for dynamic stack allocation: local/vla.c:2:3: error: unsupported dynamic stack allocation 2 | int b[n]; | ^ 1 error generated. Fixes: llvm/llvm-project#57171
1 parent 2fb060e commit ddf85b9

File tree

6 files changed

+45
-22
lines changed

6 files changed

+45
-22
lines changed

llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -192,20 +192,6 @@ void BPFDAGToDAGISel::Select(SDNode *Node) {
192192
switch (Opcode) {
193193
default:
194194
break;
195-
case ISD::SDIV: {
196-
if (!Subtarget->hasSdivSmod()) {
197-
DebugLoc Empty;
198-
const DebugLoc &DL = Node->getDebugLoc();
199-
if (DL != Empty)
200-
errs() << "Error at line " << DL.getLine() << ": ";
201-
else
202-
errs() << "Error: ";
203-
errs() << "Unsupport signed division for DAG: ";
204-
Node->print(errs(), CurDAG);
205-
errs() << "Please convert to unsigned div/mod.\n";
206-
}
207-
break;
208-
}
209195
case ISD::INTRINSIC_W_CHAIN: {
210196
unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
211197
switch (IntNo) {

llvm/lib/Target/BPF/BPFISelLowering.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,10 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM,
9999

100100
setOperationAction(ISD::SDIVREM, VT, Expand);
101101
setOperationAction(ISD::UDIVREM, VT, Expand);
102-
if (!STI.hasSdivSmod())
103-
setOperationAction(ISD::SREM, VT, Expand);
102+
if (!STI.hasSdivSmod()) {
103+
setOperationAction(ISD::SDIV, VT, Custom);
104+
setOperationAction(ISD::SREM, VT, Custom);
105+
}
104106
setOperationAction(ISD::MULHU, VT, Expand);
105107
setOperationAction(ISD::MULHS, VT, Expand);
106108
setOperationAction(ISD::UMUL_LOHI, VT, Expand);
@@ -307,8 +309,11 @@ SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
307309
return LowerGlobalAddress(Op, DAG);
308310
case ISD::SELECT_CC:
309311
return LowerSELECT_CC(Op, DAG);
312+
case ISD::SDIV:
313+
case ISD::SREM:
314+
return LowerSDIVSREM(Op, DAG);
310315
case ISD::DYNAMIC_STACKALLOC:
311-
report_fatal_error("unsupported dynamic stack allocation");
316+
return LowerDYNAMIC_STACKALLOC(Op, DAG);
312317
}
313318
}
314319

@@ -617,6 +622,21 @@ static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC) {
617622
}
618623
}
619624

625+
SDValue BPFTargetLowering::LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const {
626+
SDLoc DL(Op);
627+
fail(DL, DAG,
628+
"unsupported signed division, please convert to unsigned div/mod.");
629+
return DAG.getUNDEF(Op->getValueType(0));
630+
}
631+
632+
SDValue BPFTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
633+
SelectionDAG &DAG) const {
634+
SDLoc DL(Op);
635+
fail(DL, DAG, "unsupported dynamic stack allocation");
636+
auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
637+
return DAG.getMergeValues(Ops, SDLoc());
638+
}
639+
620640
SDValue BPFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
621641
SDValue Chain = Op.getOperand(0);
622642
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();

llvm/lib/Target/BPF/BPFISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class BPFTargetLowering : public TargetLowering {
7373
bool HasJmpExt;
7474
bool HasMovsx;
7575

76+
SDValue LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const;
77+
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
7678
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
7779
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
7880
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; RUN: not llc < %s -mtriple=bpfel 2>&1 | FileCheck %s
2+
3+
define i64 @vla(i64 %num) {
4+
; CHECK: unsupported dynamic stack allocation
5+
%vla = alloca i32, i64 %num
6+
%ret = ptrtoint ptr %vla to i64
7+
ret i64 %ret
8+
}

llvm/test/CodeGen/BPF/sdiv_error.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
; RUN: not --crash llc -march=bpf < %s 2> %t1
1+
; RUN: not llc -mtriple=bpf < %s 2> %t1
22
; RUN: FileCheck %s < %t1
3-
; CHECK: Unsupport signed division
3+
; CHECK: unsupported signed division
44

5-
; Function Attrs: norecurse nounwind readnone
6-
define i32 @test(i32 %len) #0 {
7-
%1 = srem i32 %len, 15
5+
define i32 @test(i32 %len) {
6+
%1 = sdiv i32 %len, 15
87
ret i32 %1
98
}

llvm/test/CodeGen/BPF/srem_error.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; RUN: not llc -mtriple=bpf < %s 2> %t1
2+
; RUN: FileCheck %s < %t1
3+
; CHECK: unsupported signed division
4+
5+
define i32 @test(i32 %len) {
6+
%1 = srem i32 %len, 15
7+
ret i32 %1
8+
}

0 commit comments

Comments
 (0)