[llvm] r318614 - [bpf] allow direct and indirect calls

Alexei Starovoitov via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 18 17:35:00 PST 2017


Author: ast
Date: Sat Nov 18 17:35:00 2017
New Revision: 318614

URL: http://llvm.org/viewvc/llvm-project?rev=318614&view=rev
Log:
[bpf] allow direct and indirect calls

kernel verifier is becoming smarter and soon will support
direct and indirect function calls.
Remove obsolete error from BPF backend.
Make call to use PCRel_4 fixup.
'bpf to bpf' calls are distinguished from 'bpf to kernel' calls
by insn->src_reg == BPF_PSEUDO_CALL == 1 which is used as relocation
indicator similar to ld_imm64->src_reg == BPF_PSEUDO_MAP_FD == 1
The actual 'call' instruction remains the same for both
'bpf to kernel' and 'bpf to bpf' calls.

Signed-off-by: Alexei Starovoitov <ast at kernel.org>

Modified:
    llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp
    llvm/trunk/lib/Target/BPF/BPFInstrInfo.td
    llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
    llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp
    llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp
    llvm/trunk/test/CodeGen/BPF/cc_args.ll
    llvm/trunk/test/CodeGen/BPF/cc_args_be.ll
    llvm/trunk/test/CodeGen/BPF/cc_ret.ll
    llvm/trunk/test/CodeGen/BPF/fi_ri.ll
    llvm/trunk/test/CodeGen/BPF/sanity.ll
    llvm/trunk/test/CodeGen/BPF/undef.ll
    llvm/trunk/test/CodeGen/BPF/warn-call.ll

Modified: llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp Sat Nov 18 17:35:00 2017
@@ -330,13 +330,6 @@ SDValue BPFTargetLowering::LowerCall(Tar
   // Likewise ExternalSymbol -> TargetExternalSymbol.
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
     auto GV = G->getGlobal();
-    fail(CLI.DL, DAG,
-         "A call to global function '" + StringRef(GV->getName())
-         + "' is not supported. "
-         + (GV->isDeclaration() ?
-           "Only calls to predefined BPF helpers are allowed." :
-           "Please use __attribute__((always_inline) to make sure"
-           " this function is inlined."));
     Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT,
                                         G->getOffset(), 0);
   } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {

Modified: llvm/trunk/lib/Target/BPF/BPFInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFInstrInfo.td?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/BPFInstrInfo.td (original)
+++ llvm/trunk/lib/Target/BPF/BPFInstrInfo.td Sat Nov 18 17:35:00 2017
@@ -400,6 +400,18 @@ class CALL<string OpcodeStr>
   let BPFClass = BPF_JMP;
 }
 
+class CALLX<string OpcodeStr>
+    : TYPE_ALU_JMP<BPF_CALL.Value, BPF_X.Value,
+                   (outs),
+                   (ins calltarget:$BrDst),
+                   !strconcat(OpcodeStr, " $BrDst"),
+                   []> {
+  bits<32> BrDst;
+
+  let Inst{31-0} = BrDst;
+  let BPFClass = BPF_JMP;
+}
+
 // Jump always
 let isBranch = 1, isTerminator = 1, hasDelaySlot=0, isBarrier = 1 in {
   def JMP : BRANCH<BPF_JA, "goto", [(br bb:$BrDst)]>;
@@ -410,6 +422,7 @@ let isCall=1, hasDelaySlot=0, Uses = [R1
     // Potentially clobbered registers
     Defs = [R0, R1, R2, R3, R4, R5] in {
   def JAL  : CALL<"call">;
+  def JALX  : CALLX<"callx">;
 }
 
 class NOP_I<string OpcodeStr>
@@ -476,6 +489,7 @@ def : Pat<(i64 (and (i64 GPR:$src), 0xff
 def : Pat<(BPFcall tglobaladdr:$dst), (JAL tglobaladdr:$dst)>;
 def : Pat<(BPFcall texternalsym:$dst), (JAL texternalsym:$dst)>;
 def : Pat<(BPFcall imm:$dst), (JAL imm:$dst)>;
+def : Pat<(BPFcall GPR:$dst), (JALX GPR:$dst)>;
 
 // Loads
 def : Pat<(extloadi8  ADDRri:$src), (i64 (LDB ADDRri:$src))>;

Modified: llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp Sat Nov 18 17:35:00 2017
@@ -76,6 +76,15 @@ void BPFAsmBackend::applyFixup(const MCA
       unsigned Idx = IsLittleEndian ? i : Size - i - 1;
       Data[Fixup.getOffset() + Idx] = uint8_t(Value >> (i * 8));
     }
+  } else if (Fixup.getKind() == FK_PCRel_4) {
+    Value = (uint32_t)((Value - 8) / 8);
+    if (IsLittleEndian) {
+      Data[Fixup.getOffset() + 1] = 0x10;
+      support::endian::write32le(&Data[Fixup.getOffset() + 4], Value);
+    } else {
+      Data[Fixup.getOffset() + 1] = 0x1;
+      support::endian::write32be(&Data[Fixup.getOffset() + 4], Value);
+    }
   } else {
     assert(Fixup.getKind() == FK_PCRel_2);
     Value = (uint16_t)((Value - 8) / 8);

Modified: llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp Sat Nov 18 17:35:00 2017
@@ -44,6 +44,7 @@ unsigned BPFELFObjectWriter::getRelocTyp
     llvm_unreachable("invalid fixup kind!");
   case FK_SecRel_8:
     return ELF::R_BPF_64_64;
+  case FK_PCRel_4:
   case FK_SecRel_4:
     return ELF::R_BPF_64_32;
   case FK_Data_8:

Modified: llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp Sat Nov 18 17:35:00 2017
@@ -100,7 +100,7 @@ unsigned BPFMCCodeEmitter::getMachineOpV
 
   if (MI.getOpcode() == BPF::JAL)
     // func call name
-    Fixups.push_back(MCFixup::create(0, Expr, FK_SecRel_4));
+    Fixups.push_back(MCFixup::create(0, Expr, FK_PCRel_4));
   else if (MI.getOpcode() == BPF::LD_imm64)
     Fixups.push_back(MCFixup::create(0, Expr, FK_SecRel_8));
   else

Modified: llvm/trunk/test/CodeGen/BPF/cc_args.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/cc_args.ll?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/cc_args.ll (original)
+++ llvm/trunk/test/CodeGen/BPF/cc_args.ll Sat Nov 18 17:35:00 2017
@@ -1,4 +1,4 @@
-; RUN: not llc < %s -march=bpfel -show-mc-encoding | FileCheck %s
+; RUN: llc < %s -march=bpfel -show-mc-encoding | FileCheck %s
 
 define void @test() #0 {
 entry:

Modified: llvm/trunk/test/CodeGen/BPF/cc_args_be.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/cc_args_be.ll?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/cc_args_be.ll (original)
+++ llvm/trunk/test/CodeGen/BPF/cc_args_be.ll Sat Nov 18 17:35:00 2017
@@ -1,4 +1,4 @@
-; RUN: not llc < %s -march=bpfeb -show-mc-encoding | FileCheck %s
+; RUN: llc < %s -march=bpfeb -show-mc-encoding | FileCheck %s
 ; test big endian
 
 define void @test() #0 {

Modified: llvm/trunk/test/CodeGen/BPF/cc_ret.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/cc_ret.ll?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/cc_ret.ll (original)
+++ llvm/trunk/test/CodeGen/BPF/cc_ret.ll Sat Nov 18 17:35:00 2017
@@ -1,4 +1,4 @@
-; RUN: not llc < %s -march=bpfel | FileCheck %s
+; RUN: llc < %s -march=bpfel | FileCheck %s
 
 define void @test() #0 {
 entry:

Modified: llvm/trunk/test/CodeGen/BPF/fi_ri.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/fi_ri.ll?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/fi_ri.ll (original)
+++ llvm/trunk/test/CodeGen/BPF/fi_ri.ll Sat Nov 18 17:35:00 2017
@@ -1,4 +1,4 @@
-; RUN: not llc < %s -march=bpf | FileCheck %s
+; RUN: llc < %s -march=bpf | FileCheck %s
 
 %struct.key_t = type { i32, [16 x i8] }
 

Modified: llvm/trunk/test/CodeGen/BPF/sanity.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/sanity.ll?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/sanity.ll (original)
+++ llvm/trunk/test/CodeGen/BPF/sanity.ll Sat Nov 18 17:35:00 2017
@@ -1,4 +1,4 @@
-; RUN: not llc < %s -march=bpfel | FileCheck %s
+; RUN: llc < %s -march=bpfel | FileCheck %s
 
 @foo_printf.fmt = private unnamed_addr constant [9 x i8] c"hello  \0A\00", align 1
 

Modified: llvm/trunk/test/CodeGen/BPF/undef.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/undef.ll?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/undef.ll (original)
+++ llvm/trunk/test/CodeGen/BPF/undef.ll Sat Nov 18 17:35:00 2017
@@ -1,5 +1,5 @@
-; RUN: not llc < %s -march=bpfel | FileCheck -check-prefixes=CHECK,EL %s
-; RUN: not llc < %s -march=bpfeb | FileCheck -check-prefixes=CHECK,EB %s
+; RUN: llc < %s -march=bpfel | FileCheck -check-prefixes=CHECK,EL %s
+; RUN: llc < %s -march=bpfeb | FileCheck -check-prefixes=CHECK,EB %s
 
 %struct.bpf_map_def = type { i32, i32, i32, i32 }
 %struct.__sk_buff = type opaque

Modified: llvm/trunk/test/CodeGen/BPF/warn-call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/warn-call.ll?rev=318614&r1=318613&r2=318614&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/warn-call.ll (original)
+++ llvm/trunk/test/CodeGen/BPF/warn-call.ll Sat Nov 18 17:35:00 2017
@@ -2,9 +2,6 @@
 
 ; CHECK: error: warn_call.c
 ; CHECK: built-in function 'memcpy'
-; CHECK: error: warn_call.c
-; CHECK: global function 'foo'
-; CHECK: global function 'bar'
 define i8* @warn(i8* returned, i8*, i64) local_unnamed_addr #0 !dbg !6 {
   tail call void @llvm.dbg.value(metadata i8* %0, i64 0, metadata !14, metadata !17), !dbg !18
   tail call void @llvm.dbg.value(metadata i8* %1, i64 0, metadata !15, metadata !17), !dbg !19




More information about the llvm-commits mailing list