[PATCH] D111897: BPF: remove intrindics @llvm.stacksave() and @llvm.stackrestore()

Yonghong Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 15 09:46:13 PDT 2021


yonghong-song created this revision.
yonghong-song added reviewers: ast, pchaigno.
Herald added subscribers: hiraditya, mgorny.
yonghong-song requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Paul Chaignon reported a bpf verifier failure ([1]) due to using
non-ABI register R11 <https://reviews.llvm.org/source/libunwind/>. For the test case, llvm11 is okay while
llvm12 and later generates verifier unfriendly code.

The failure is related to variable length array size.
The following mimics the variable length array definition
in the test case:

  struct t { char a[20]; };
  void foo(void *);
  int test() {
     const int a = 8;
     char tmp[AA + sizeof(struct t) + a];
     foo(tmp);
     ...
  }

Paul helped bisect that the following llvm commit is
responsible:

552c6c232872 <https://reviews.llvm.org/rG552c6c2328723a248c2b4d2765f75d49129dff20> ("PR44406: Follow behavior of array bound constant

  folding in more recent versions of GCC.")

Basically, before the above commit, clang frontend did constant
folding for array size "AA + sizeof(struct t) + a" to be 68, 
so used alloca for stack allocation. After the above commit,
clang frontend didn't do constant folding for array size
any more, which results in a VLA and llvm.stacksave/llvm.stackrestore
is generated.

BPF architecture API does not support stack pointer (sp) register.
The LLVM internally used R11 <https://reviews.llvm.org/source/libunwind/> to indicate sp register but it should
not be in the final code. Otherwise, kernel verifier will reject it.

The early patch ([2]) tried to fix the issue in clang frontend.
But the upstream discussion considered frontend fix is really a
hack and the backend should properly undo llvm.stacksave/llvm.stackrestore.
This patch implemented a bpf IR phase to remove these intrinsics
unconditionally. If eventually the alloca can be resolved with
constant size, r11 will not be generated. If alloca cannot be
resolved with constant size, SelectionDag will complain, the same
as without this patch.

[1] https://lore.kernel.org/bpf/20210809151202.GB1012999@Mem/
 [2] https://reviews.llvm.org/D107882


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111897

Files:
  llvm/lib/Target/BPF/BPF.h
  llvm/lib/Target/BPF/BPFIRPeephole.cpp
  llvm/lib/Target/BPF/BPFTargetMachine.cpp
  llvm/lib/Target/BPF/CMakeLists.txt
  llvm/test/CodeGen/BPF/vla.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D111897.380042.patch
Type: text/x-patch
Size: 11030 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211015/3d848861/attachment.bin>


More information about the llvm-commits mailing list