[llvm] [BPF] improve error handling for unsupported sdiv, srem (PR #75088)

Yingchi Long via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 11 11:38:47 PST 2023


https://github.com/inclyc created https://github.com/llvm/llvm-project/pull/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

>From 1cc86c2d49741d51993d9d0797726f04bdda01ae 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] [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
---
 llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp | 14 --------------
 llvm/lib/Target/BPF/BPFISelLowering.cpp | 20 ++++++++++++++++++--
 llvm/lib/Target/BPF/BPFISelLowering.h   |  3 +++
 llvm/test/CodeGen/BPF/sdiv_error.ll     |  4 ++--
 4 files changed, 23 insertions(+), 18 deletions(-)

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..976ae5cc52216a 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);
@@ -297,6 +299,15 @@ void BPFTargetLowering::ReplaceNodeResults(
   fail(DL, DAG, Msg);
 }
 
+SDValue BPFTargetLowering::reportUnsupported(SDValue Op, SelectionDAG &DAG,
+                                             const Twine &Msg) const {
+  const DebugLoc &DL = Op->getDebugLoc();
+  DiagnosticInfoUnsupported Diag(DAG.getMachineFunction().getFunction(), Msg,
+                                 DL);
+  DAG.getContext()->diagnose(Diag);
+  return DAG.getUNDEF(Op->getValueType(0));
+}
+
 SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
   switch (Op.getOpcode()) {
   default:
@@ -307,6 +318,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 reportUnsupported(
+        Op, DAG,
+        "unsupported signed division, please convert to unsigned div/mod.");
   case ISD::DYNAMIC_STACKALLOC:
     report_fatal_error("unsupported dynamic stack allocation");
   }
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h
index 3be1c04bca3d65..8c95fc067a4209 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.h
+++ b/llvm/lib/Target/BPF/BPFISelLowering.h
@@ -39,6 +39,9 @@ class BPFTargetLowering : public TargetLowering {
   // Provide custom lowering hooks for some operations.
   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
 
+  SDValue reportUnsupported(SDValue Op, SelectionDAG &DAG,
+                            const Twine &Msg) const;
+
   // This method returns the name of a target specific DAG node.
   const char *getTargetNodeName(unsigned Opcode) const override;
 
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 {



More information about the llvm-commits mailing list