[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