[PATCH] D155894: [BPF] Do not miscompile, allow external calls

Eduard Zingerman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 25 10:18:04 PDT 2023


eddyz87 added a comment.

In D155894#4532046 <https://reviews.llvm.org/D155894#4532046>, @tamird wrote:

> Figured it out - if you pass `--bpf-expand-memcpy-in-order` to llc, you will reproduce the `A call to built-in function 'memset' is not supported.` prints.

I can see the error with this flag, thanks.

Also, here is a simpler example which could be triggered from clang:

  $ cat test.c
  extern void *memset(void *s, int c, unsigned long n);
  extern void efoo(char *p);
  void bar(char *p, unsigned long l) {
    memset(p, 0, l);
    efoo(p);
  }
  
  $ clang -O2 --target=bpf -mcpu=v3 test.c -emit-llvm -S -o test.ll
  $ cat test.ll
  ...
  ; Function Attrs: nounwind
  define dso_local void @bar(ptr noundef %p, i64 noundef %l) local_unnamed_addr #0 {
  entry:
    tail call void @llvm.memset.p0.i64(ptr align 1 %p, i8 0, i64 %l, i1 false)
    tail call void @efoo(ptr noundef %p) #3
    ret void
  }
  
  ; Function Attrs: mustprogress nocallback nofree nounwind willreturn memory(argmem: write)
  declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1
  
  declare dso_local void @efoo(ptr noundef) local_unnamed_addr #2
  
  attributes #0 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="v3" }
  attributes #1 = { mustprogress nocallback nofree nounwind willreturn memory(argmem: write) }
  attributes #2 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="v3" }
  attributes #3 = { nounwind }
  ...
  $ llc -mcpu=v3 test.ll -o - 
  error: <unknown>:0:0: in function bar void (ptr, i64): A call to built-in function 'memset' is not supported.
  
  Callee: t21: i64 = GlobalAddress<ptr @efoo> 0
  	.globl	bar                             # -- Begin function bar
  	.p2align	3
  	.type	bar, at function
  bar:                                    # @bar
  .Lbar$local:
  	.type	.Lbar$local, at function
  # %bb.0:                                # %entry
  	r3 = r2
  	r6 = r1
  	w2 = 0
  	call memset  # <------ Note the leftover call to `memset`
  	r1 = r6
  	call efoo
  	exit
  .Lfunc_end0:
  	.size	bar, .Lfunc_end0-bar
  	.size	.Lbar$local, .Lfunc_end0-bar
                                          # -- End function

The warnings would be reported for builtin extern functions (list is here: llvm/include/llvm/IR/RuntimeLibcalls.def).
But will not be reported for regular extern functions, like `efoo` in the example above.
As far as I understand all BPF code that uses `clang` uses `llvm.memset` patterns that could be statically expanded as a bunch of stores and BPF runtime does not really provide `memset` implementation.
So on one hand it probably would be better to retain this warning for clang, but on the other hand these warnings really belong to linker not compiler.
If libbpf is used as a linker I think it would report an error if code w/o suitable `memset` implementation is loaded.
Is there a way to pass a list of supported builtins as a parameter here?
@yonghong-song, what do you think?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155894/new/

https://reviews.llvm.org/D155894



More information about the llvm-commits mailing list