[llvm] [BPF] improve error handling by custom lowering & fail() (PR #75088)

Yingchi Long via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 12 21:35:11 PST 2023


https://github.com/inclyc updated https://github.com/llvm/llvm-project/pull/75088

>From 63661ffa74e941054d002a7922954250dfcc2447 Mon Sep 17 00:00:00 2001
From: Yingchi Long <i at lyc.dev>
Date: Tue, 12 Dec 2023 03:27:49 +0800
Subject: [PATCH 1/2] [BPF] improve error handling for unsupported sdiv, srem

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: #57171
---
 llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp | 14 -------------
 llvm/lib/Target/BPF/BPFISelLowering.cpp | 26 ++++++++++++++++++++++---
 llvm/lib/Target/BPF/BPFISelLowering.h   |  2 ++
 llvm/test/CodeGen/BPF/dynamic-stack.ll  |  8 ++++++++
 llvm/test/CodeGen/BPF/sdiv_error.ll     |  4 ++--
 5 files changed, 35 insertions(+), 19 deletions(-)
 create mode 100644 llvm/test/CodeGen/BPF/dynamic-stack.ll

diff --git a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp
index b0cfca3b7ab66a..909c7c005735b6 100644
--- a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp
+++ b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp
@@ -192,20 +192,6 @@ void BPFDAGToDAGISel::Select(SDNode *Node) {
   switch (Opcode) {
   default:
     break;
-  case ISD::SDIV: {
-    if (!Subtarget->hasSdivSmod()) {
-      DebugLoc Empty;
-      const DebugLoc &DL = Node->getDebugLoc();
-      if (DL != Empty)
-        errs() << "Error at line " << DL.getLine() << ": ";
-      else
-        errs() << "Error: ";
-      errs() << "Unsupport signed division for DAG: ";
-      Node->print(errs(), CurDAG);
-      errs() << "Please convert to unsigned div/mod.\n";
-    }
-    break;
-  }
   case ISD::INTRINSIC_W_CHAIN: {
     unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
     switch (IntNo) {
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp
index f3368b8979d6f5..2fe86e75ddae8f 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.cpp
+++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp
@@ -99,8 +99,10 @@ BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM,
 
     setOperationAction(ISD::SDIVREM, VT, Expand);
     setOperationAction(ISD::UDIVREM, VT, Expand);
-    if (!STI.hasSdivSmod())
-      setOperationAction(ISD::SREM, VT, Expand);
+    if (!STI.hasSdivSmod()) {
+      setOperationAction(ISD::SDIV, VT, Custom);
+      setOperationAction(ISD::SREM, VT, Custom);
+    }
     setOperationAction(ISD::MULHU, VT, Expand);
     setOperationAction(ISD::MULHS, VT, Expand);
     setOperationAction(ISD::UMUL_LOHI, VT, Expand);
@@ -307,8 +309,11 @@ SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
     return LowerGlobalAddress(Op, DAG);
   case ISD::SELECT_CC:
     return LowerSELECT_CC(Op, DAG);
+  case ISD::SDIV:
+  case ISD::SREM:
+    return LowerSDIVSREM(Op, DAG);
   case ISD::DYNAMIC_STACKALLOC:
-    report_fatal_error("unsupported dynamic stack allocation");
+    return LowerDYNAMIC_STACKALLOC(Op, DAG);
   }
 }
 
@@ -617,6 +622,21 @@ static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC) {
   }
 }
 
+SDValue BPFTargetLowering::LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  fail(DL, DAG,
+       "unsupported signed division, please convert to unsigned div/mod.");
+  return DAG.getUNDEF(Op->getValueType(0));
+}
+
+SDValue BPFTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
+                                                   SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  fail(DL, DAG, "unsupported dynamic stack allocation");
+  auto Ops = {DAG.getConstant(0, SDLoc(), Op.getValueType()), Op.getOperand(0)};
+  return DAG.getMergeValues(Ops, SDLoc());
+}
+
 SDValue BPFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
   SDValue Chain = Op.getOperand(0);
   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h
index 3be1c04bca3d65..819711b650c15f 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.h
+++ b/llvm/lib/Target/BPF/BPFISelLowering.h
@@ -73,6 +73,8 @@ class BPFTargetLowering : public TargetLowering {
   bool HasJmpExt;
   bool HasMovsx;
 
+  SDValue LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const;
+  SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/test/CodeGen/BPF/dynamic-stack.ll b/llvm/test/CodeGen/BPF/dynamic-stack.ll
new file mode 100644
index 00000000000000..046523ded8001c
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/dynamic-stack.ll
@@ -0,0 +1,8 @@
+; RUN: not llc < %s -mtriple=bpfel 2>&1 | FileCheck %s
+
+define i64 @vla(i64 %num) {
+; CHECK: unsupported dynamic stack allocation
+    %vla = alloca i32, i64 %num
+    %ret = ptrtoint ptr %vla to i64
+    ret i64 %ret
+}
diff --git a/llvm/test/CodeGen/BPF/sdiv_error.ll b/llvm/test/CodeGen/BPF/sdiv_error.ll
index fc79a1d44c16ba..d256d054bbceb2 100644
--- a/llvm/test/CodeGen/BPF/sdiv_error.ll
+++ b/llvm/test/CodeGen/BPF/sdiv_error.ll
@@ -1,6 +1,6 @@
-; RUN: not --crash llc -march=bpf < %s 2> %t1
+; RUN: not llc -march=bpf < %s 2> %t1
 ; RUN: FileCheck %s < %t1
-; CHECK: Unsupport signed division
+; CHECK: unsupported signed division
 
 ; Function Attrs: norecurse nounwind readnone
 define i32 @test(i32 %len) #0 {

>From a5c660756c58d23e7d5dce3b2091d301c37fc364 Mon Sep 17 00:00:00 2001
From: Yingchi Long <i at lyc.dev>
Date: Wed, 13 Dec 2023 13:33:55 +0800
Subject: [PATCH 2/2] [BPF] add sdiv_error test

---
 llvm/test/CodeGen/BPF/sdiv_error.ll | 4 ++--
 llvm/test/CodeGen/BPF/srem_error.ll | 9 +++++++++
 2 files changed, 11 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/BPF/srem_error.ll

diff --git a/llvm/test/CodeGen/BPF/sdiv_error.ll b/llvm/test/CodeGen/BPF/sdiv_error.ll
index d256d054bbceb2..b2b5b749ee648e 100644
--- a/llvm/test/CodeGen/BPF/sdiv_error.ll
+++ b/llvm/test/CodeGen/BPF/sdiv_error.ll
@@ -1,9 +1,9 @@
-; RUN: not llc -march=bpf < %s 2> %t1
+; RUN: not llc -mtriple=bpf < %s 2> %t1
 ; RUN: FileCheck %s < %t1
 ; CHECK: unsupported signed division
 
 ; Function Attrs: norecurse nounwind readnone
 define i32 @test(i32 %len) #0 {
-  %1 = srem i32 %len, 15
+  %1 = sdiv i32 %len, 15
   ret i32 %1
 }
diff --git a/llvm/test/CodeGen/BPF/srem_error.ll b/llvm/test/CodeGen/BPF/srem_error.ll
new file mode 100644
index 00000000000000..2e6105add992db
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/srem_error.ll
@@ -0,0 +1,9 @@
+; RUN: not llc -mtriple=bpf < %s 2> %t1
+; RUN: FileCheck %s < %t1
+; CHECK: unsupported signed division
+
+; Function Attrs: norecurse nounwind readnone
+define i32 @test(i32 %len) #0 {
+  %1 = srem i32 %len, 15
+  ret i32 %1
+}



More information about the llvm-commits mailing list