[llvm] r300269 - [bpf] Fix memory offset check for loads and stores

Alexei Starovoitov via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 13 15:24:13 PDT 2017


Author: ast
Date: Thu Apr 13 17:24:13 2017
New Revision: 300269

URL: http://llvm.org/viewvc/llvm-project?rev=300269&view=rev
Log:
[bpf] Fix memory offset check for loads and stores

If the offset cannot fit into the instruction, an addition to the
pointer is emitted before the actual access. However, BPF offsets are
16-bit but LLVM considers them to be, for the matter of this check,
to be 32-bit long.

This causes the following program:

int bpf_prog1(void *ign)
{

volatile unsigned long t = 0x8983984739ull;
return *(unsigned long *)((0xffffffff8fff0002ull) + t);

}

To generate the following (wrong) code:

0: 18 01 00 00 39 47 98 83 00 00 00 00 89 00 00 00

r1 = 590618314553ll

2: 7b 1a f8 ff 00 00 00 00 *(u64 *)(r10 - 8) = r1
3: 79 a1 f8 ff 00 00 00 00 r1 = *(u64 *)(r10 - 8)
4: 79 10 02 00 00 00 00 00 r0 = *(u64 *)(r1 + 2)
5: 95 00 00 00 00 00 00 00 exit

Fix it by changing the offset check to 16-bit.

Patch by Nadav Amit <nadav.amit at gmail.com>
Signed-off-by: Alexei Starovoitov <ast at kernel.org>
Differential Revision: https://reviews.llvm.org/D32055

Added:
    llvm/trunk/test/CodeGen/BPF/mem_offset.ll
Modified:
    llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp

Modified: llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp?rev=300269&r1=300268&r2=300269&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp Thu Apr 13 17:24:13 2017
@@ -71,7 +71,7 @@ bool BPFDAGToDAGISel::SelectAddr(SDValue
   // Addresses of the form Addr+const or Addr|const
   if (CurDAG->isBaseWithConstantOffset(Addr)) {
     ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
-    if (isInt<32>(CN->getSExtValue())) {
+    if (isInt<16>(CN->getSExtValue())) {
 
       // If the first operand is a FI, get the TargetFI Node
       if (FrameIndexSDNode *FIN =
@@ -99,7 +99,7 @@ bool BPFDAGToDAGISel::SelectFIAddr(SDVal
 
   // Addresses of the form Addr+const or Addr|const
   ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
-  if (isInt<32>(CN->getSExtValue())) {
+  if (isInt<16>(CN->getSExtValue())) {
 
     // If the first operand is a FI, get the TargetFI Node
     if (FrameIndexSDNode *FIN =

Added: llvm/trunk/test/CodeGen/BPF/mem_offset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/mem_offset.ll?rev=300269&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/mem_offset.ll (added)
+++ llvm/trunk/test/CodeGen/BPF/mem_offset.ll Thu Apr 13 17:24:13 2017
@@ -0,0 +1,17 @@
+; RUN: llc -march=bpfel -show-mc-encoding < %s | FileCheck %s
+
+; Function Attrs: nounwind
+define i32 @bpf_prog1(i8* nocapture readnone) local_unnamed_addr #0 {
+; CHECK: r1 += -1879113726 # encoding: [0x07,0x01,0x00,0x00,0x02,0x00,0xff,0x8f]
+; CHECK: r0 = *(u64 *)(r1 + 0) # encoding: [0x79,0x10,0x00,0x00,0x00,0x00,0x00,0x00]
+  %2 = alloca i64, align 8
+  %3 = bitcast i64* %2 to i8*
+  store volatile i64 590618314553, i64* %2, align 8
+  %4 = load volatile i64, i64* %2, align 8
+  %5 = add i64 %4, -1879113726
+  %6 = inttoptr i64 %5 to i64*
+  %7 = load i64, i64* %6, align 8
+  %8 = trunc i64 %7 to i32
+  ret i32 %8
+}
+




More information about the llvm-commits mailing list