Index: cmake/modules/HandleLLVMOptions.cmake =================================================================== --- cmake/modules/HandleLLVMOptions.cmake +++ cmake/modules/HandleLLVMOptions.cmake @@ -563,7 +563,7 @@ endif() elseif (LLVM_USE_SANITIZER STREQUAL "Undefined") append_common_sanitizer_flags() - append("-fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all" + append("-fsanitize=undefined -fno-sanitize=vptr,function,null -fno-sanitize-recover=all" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) append("-fsanitize-blacklist=${CMAKE_SOURCE_DIR}/utils/sanitizers/ubsan_blacklist.txt" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) Index: lib/Target/BPF/BPFISelLowering.cpp =================================================================== --- lib/Target/BPF/BPFISelLowering.cpp +++ lib/Target/BPF/BPFISelLowering.cpp @@ -33,7 +33,7 @@ #define DEBUG_TYPE "bpf-lower" -static void fail(const SDLoc &DL, SelectionDAG &DAG, const Twine &Msg) { +static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *Msg) { MachineFunction &MF = DAG.getMachineFunction(); DAG.getContext()->diagnose( DiagnosticInfoUnsupported(*MF.getFunction(), Msg, DL.getDebugLoc())); @@ -306,23 +306,11 @@ // If the callee is a GlobalAddress node (quite common, every direct call is) // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. // Likewise ExternalSymbol -> TargetExternalSymbol. - if (GlobalAddressSDNode *G = dyn_cast(Callee)) { - auto GV = G->getGlobal(); - Twine Msg("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.")); - fail(CLI.DL, DAG, Msg); + if (GlobalAddressSDNode *G = dyn_cast(Callee)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT, G->getOffset(), 0); - } else if (ExternalSymbolSDNode *E = dyn_cast(Callee)) { + else if (ExternalSymbolSDNode *E = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0); - fail(CLI.DL, DAG, Twine("A call to built-in function '" - + StringRef(E->getSymbol()) - + "' is not supported.")); - } // Returns a chain & a flag for retval copy to use. SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); Index: lib/Target/BPF/BPFInstrInfo.td =================================================================== --- lib/Target/BPF/BPFInstrInfo.td +++ lib/Target/BPF/BPFInstrInfo.td @@ -470,7 +470,6 @@ // Calls def : Pat<(BPFcall tglobaladdr:$dst), (JAL tglobaladdr:$dst)>; -def : Pat<(BPFcall texternalsym:$dst), (JAL texternalsym:$dst)>; def : Pat<(BPFcall imm:$dst), (JAL imm:$dst)>; // Loads Index: lib/Target/BPF/BPFMCInstLower.h =================================================================== --- lib/Target/BPF/BPFMCInstLower.h +++ lib/Target/BPF/BPFMCInstLower.h @@ -37,7 +37,6 @@ MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const; MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const; - MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const; }; } Index: lib/Target/BPF/BPFMCInstLower.cpp =================================================================== --- lib/Target/BPF/BPFMCInstLower.cpp +++ lib/Target/BPF/BPFMCInstLower.cpp @@ -29,11 +29,6 @@ return Printer.getSymbol(MO.getGlobal()); } -MCSymbol * -BPFMCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const { - return Printer.GetExternalSymbolSymbol(MO.getSymbolName()); -} - MCOperand BPFMCInstLower::LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { @@ -71,9 +66,6 @@ break; case MachineOperand::MO_RegisterMask: continue; - case MachineOperand::MO_ExternalSymbol: - MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); - break; case MachineOperand::MO_GlobalAddress: MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); break; Index: test/CodeGen/BPF/cc_args.ll =================================================================== --- test/CodeGen/BPF/cc_args.ll +++ test/CodeGen/BPF/cc_args.ll @@ -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: Index: test/CodeGen/BPF/cc_args_be.ll =================================================================== --- test/CodeGen/BPF/cc_args_be.ll +++ test/CodeGen/BPF/cc_args_be.ll @@ -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 { Index: test/CodeGen/BPF/cc_ret.ll =================================================================== --- test/CodeGen/BPF/cc_ret.ll +++ test/CodeGen/BPF/cc_ret.ll @@ -1,4 +1,4 @@ -; RUN: not llc < %s -march=bpfel | FileCheck %s +; RUN: llc < %s -march=bpfel | FileCheck %s define void @test() #0 { entry: Index: test/CodeGen/BPF/fi_ri.ll =================================================================== --- test/CodeGen/BPF/fi_ri.ll +++ test/CodeGen/BPF/fi_ri.ll @@ -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] } Index: test/CodeGen/BPF/intrinsics.ll =================================================================== --- test/CodeGen/BPF/intrinsics.ll +++ test/CodeGen/BPF/intrinsics.ll @@ -52,12 +52,14 @@ define i32 @ld_pseudo() #0 { entry: %call = tail call i64 @llvm.bpf.pseudo(i64 2, i64 3) - tail call void inttoptr (i64 4 to void (i64, i32)*)(i64 %call, i32 4) #2 + tail call void @bar(i64 %call, i32 4) #2 ret i32 0 ; CHECK-LABEL: ld_pseudo: ; CHECK: ld_pseudo r1, 2, 3 # encoding: [0x18,0x21,0x00,0x00,0x03,0x00 } +declare void @bar(i64, i32) #1 + declare i64 @llvm.bpf.pseudo(i64, i64) #2 define i32 @bswap(i64 %a, i64 %b, i64 %c) #0 { Index: test/CodeGen/BPF/objdump_intrinsics.ll =================================================================== --- test/CodeGen/BPF/objdump_intrinsics.ll +++ test/CodeGen/BPF/objdump_intrinsics.ll @@ -52,12 +52,14 @@ define i32 @ld_pseudo() #0 { entry: %call = tail call i64 @llvm.bpf.pseudo(i64 2, i64 3) - tail call void inttoptr (i64 4 to void (i64, i32)*)(i64 %call, i32 4) #2 + tail call void @bar(i64 %call, i32 4) #2 ret i32 0 ; CHECK-LABEL: ld_pseudo: ; CHECK: ld_pseudo r1, 2, 3 } +declare void @bar(i64, i32) #1 + declare i64 @llvm.bpf.pseudo(i64, i64) #2 define i32 @bswap(i64 %a, i64 %b, i64 %c) #0 { Index: test/CodeGen/BPF/objdump_trivial.ll =================================================================== --- test/CodeGen/BPF/objdump_trivial.ll +++ test/CodeGen/BPF/objdump_trivial.ll @@ -1,18 +1,19 @@ ; RUN: llc -march=bpfel -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s ; CHECK: if r2 s> r1 goto -; CHECK: call 1 -; CHECK: exit -; CHECK: call 2 +; CHECK: call ; CHECK: exit +declare void @a() +declare void @b() + define void @foo(i32 %a) { %b = icmp sgt i32 %a, -1 br i1 %b, label %x, label %y x: -call void inttoptr (i64 1 to void ()*)() +call void @a() ret void y: -call void inttoptr (i64 2 to void ()*)() +call void @b() ret void } Index: test/CodeGen/BPF/sanity.ll =================================================================== --- test/CodeGen/BPF/sanity.ll +++ test/CodeGen/BPF/sanity.ll @@ -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 Index: test/CodeGen/BPF/undef.ll =================================================================== --- test/CodeGen/BPF/undef.ll +++ test/CodeGen/BPF/undef.ll @@ -1,4 +1,4 @@ -; RUN: not llc < %s -march=bpf | FileCheck %s +; RUN: llc < %s -march=bpf | FileCheck %s %struct.bpf_map_def = type { i32, i32, i32, i32 } %struct.__sk_buff = type opaque Index: test/CodeGen/BPF/warn-call.ll =================================================================== --- test/CodeGen/BPF/warn-call.ll +++ /dev/null @@ -1,69 +0,0 @@ -; RUN: not llc -march=bpfel < %s 2>&1 >/dev/null | FileCheck %s - -; 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 - tail call void @llvm.dbg.value(metadata i64 %2, i64 0, metadata !16, metadata !17), !dbg !20 - tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 %2, i32 1, i1 false), !dbg !21 - %4 = tail call i8* @foo(i8* %0, i8* %1, i64 %2) #5, !dbg !22 - %5 = tail call fastcc i8* @bar(i8* %0), !dbg !23 - ret i8* %5, !dbg !24 -} - -; Function Attrs: argmemonly nounwind -declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #1 - -declare i8* @foo(i8*, i8*, i64) local_unnamed_addr #2 - -; Function Attrs: noinline nounwind readnone -define internal fastcc i8* @bar(i8* readnone returned) unnamed_addr #3 !dbg !25 { - tail call void @llvm.dbg.value(metadata i8* null, i64 0, metadata !28, metadata !17), !dbg !30 - tail call void @llvm.dbg.value(metadata i64 0, i64 0, metadata !29, metadata !17), !dbg !31 - ret i8* %0, !dbg !32 -} - -; Function Attrs: nounwind readnone -declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #4 - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!3, !4} -!llvm.ident = !{!5} - -!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 5.0.0 (trunk 292174) (llvm/trunk 292179)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) -!1 = !DIFile(filename: "warn_call.c", directory: "/w/llvm/bld") -!2 = !{} -!3 = !{i32 2, !"Dwarf Version", i32 4} -!4 = !{i32 2, !"Debug Info Version", i32 3} -!5 = !{!"clang version 5.0.0 (trunk 292174) (llvm/trunk 292179)"} -!6 = distinct !DISubprogram(name: "warn", scope: !1, file: !1, line: 4, type: !7, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !13) -!7 = !DISubroutineType(types: !8) -!8 = !{!9, !9, !10, !12} -!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64) -!11 = !DIDerivedType(tag: DW_TAG_const_type, baseType: null) -!12 = !DIBasicType(name: "long unsigned int", size: 64, encoding: DW_ATE_unsigned) -!13 = !{!14, !15, !16} -!14 = !DILocalVariable(name: "dst", arg: 1, scope: !6, file: !1, line: 4, type: !9) -!15 = !DILocalVariable(name: "src", arg: 2, scope: !6, file: !1, line: 4, type: !10) -!16 = !DILocalVariable(name: "len", arg: 3, scope: !6, file: !1, line: 4, type: !12) -!17 = !DIExpression() -!18 = !DILocation(line: 4, column: 18, scope: !6) -!19 = !DILocation(line: 4, column: 35, scope: !6) -!20 = !DILocation(line: 4, column: 54, scope: !6) -!21 = !DILocation(line: 6, column: 2, scope: !6) -!22 = !DILocation(line: 7, column: 2, scope: !6) -!23 = !DILocation(line: 8, column: 9, scope: !6) -!24 = !DILocation(line: 8, column: 2, scope: !6) -!25 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 2, type: !7, isLocal: true, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !26) -!26 = !{!27, !28, !29} -!27 = !DILocalVariable(name: "dst", arg: 1, scope: !25, file: !1, line: 2, type: !9) -!28 = !DILocalVariable(name: "src", arg: 2, scope: !25, file: !1, line: 2, type: !10) -!29 = !DILocalVariable(name: "len", arg: 3, scope: !25, file: !1, line: 2, type: !12) -!30 = !DILocation(line: 2, column: 67, scope: !25) -!31 = !DILocation(line: 2, column: 86, scope: !25) -!32 = !DILocation(line: 2, column: 93, scope: !25)