Files
clang-p2996/llvm/test/CodeGen/BPF/store_imm.ll
Eduard Zingerman 8f28e8069c [BPF] support for BPF_ST instruction in codegen
Generate store immediate instruction when CPUv4 is enabled.
For example:

    $ cat test.c
    struct foo {
      unsigned char  b;
      unsigned short h;
      unsigned int   w;
      unsigned long  d;
    };
    void bar(volatile struct foo *p) {
      p->b = 1;
      p->h = 2;
      p->w = 3;
      p->d = 4;
    }

    $ clang -O2 --target=bpf -mcpu=v4 test.c -c -o - | llvm-objdump -d -
    ...
    0000000000000000 <bar>:
           0:	72 01 00 00 01 00 00 00	*(u8 *)(r1 + 0x0) = 0x1
           1:	6a 01 02 00 02 00 00 00	*(u16 *)(r1 + 0x2) = 0x2
           2:	62 01 04 00 03 00 00 00	*(u32 *)(r1 + 0x4) = 0x3
           3:	7a 01 08 00 04 00 00 00	*(u64 *)(r1 + 0x8) = 0x4
           4:	95 00 00 00 00 00 00 00	exit

Take special care to:
- apply `BPFMISimplifyPatchable::checkADDrr` rewrite for BPF_ST
- validate immediate value when BPF_ST write is 64-bit:
  BPF interprets `(BPF_ST | BPF_MEM | BPF_DW)` writes as writes with
  sign extension. Thus it is fine to generate such write when
  immediate is -1, but it is incorrect to generate such write when
  immediate is +0xffff_ffff.

This commit was previously reverted in e66affa17e.
The reason for revert was an unrelated bug in BPF backend,
triggered by test case added in this commit if LLVM is built
with LLVM_ENABLE_EXPENSIVE_CHECKS.
The bug was fixed in D157806.

Differential Revision: https://reviews.llvm.org/D140804
2023-08-16 17:51:28 +03:00

105 lines
4.1 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -march=bpfel -mcpu=v4 -show-mc-encoding | FileCheck %s
target triple = "bpf"
define void @byte(ptr %p0) {
; CHECK-LABEL: byte:
; CHECK: # %bb.0:
; CHECK-NEXT: *(u8 *)(r1 + 0) = 1 # encoding: [0x72,0x01,0x00,0x00,0x01,0x00,0x00,0x00]
; CHECK-NEXT: *(u8 *)(r1 + 1) = 255 # encoding: [0x72,0x01,0x01,0x00,0xff,0x00,0x00,0x00]
%p1 = getelementptr i8, ptr %p0, i32 1
store volatile i8 1, ptr %p0, align 1
store volatile i8 -1, ptr %p1, align 1
unreachable
}
define void @half(ptr, ptr %p0) {
; CHECK-LABEL: half:
; CHECK: # %bb.0:
; CHECK-NEXT: *(u16 *)(r2 + 0) = 1 # encoding: [0x6a,0x02,0x00,0x00,0x01,0x00,0x00,0x00]
; CHECK-NEXT: *(u16 *)(r2 + 2) = 65535 # encoding: [0x6a,0x02,0x02,0x00,0xff,0xff,0x00,0x00]
%p1 = getelementptr i8, ptr %p0, i32 2
store volatile i16 1, ptr %p0, align 2
store volatile i16 -1, ptr %p1, align 2
unreachable
}
define void @word(ptr, ptr, ptr %p0) {
; CHECK-LABEL: word:
; CHECK: # %bb.0:
; CHECK-NEXT: *(u32 *)(r3 + 0) = 1 # encoding: [0x62,0x03,0x00,0x00,0x01,0x00,0x00,0x00]
; CHECK-NEXT: *(u32 *)(r3 + 4) = -1 # encoding: [0x62,0x03,0x04,0x00,0xff,0xff,0xff,0xff]
; CHECK-NEXT: *(u32 *)(r3 + 8) = -2000000000 # encoding: [0x62,0x03,0x08,0x00,0x00,0x6c,0xca,0x88]
; CHECK-NEXT: *(u32 *)(r3 + 12) = -1 # encoding: [0x62,0x03,0x0c,0x00,0xff,0xff,0xff,0xff]
; CHECK-NEXT: *(u32 *)(r3 + 12) = 0 # encoding: [0x62,0x03,0x0c,0x00,0x00,0x00,0x00,0x00]
%p1 = getelementptr i8, ptr %p0, i32 4
%p2 = getelementptr i8, ptr %p0, i32 8
%p3 = getelementptr i8, ptr %p0, i32 12
store volatile i32 1, ptr %p0, align 4
store volatile i32 -1, ptr %p1, align 4
store volatile i32 -2000000000, ptr %p2, align 4
store volatile i32 4294967295, ptr %p3, align 4
store volatile i32 4294967296, ptr %p3, align 4
unreachable
}
define void @dword(ptr, ptr, ptr, ptr %p0) {
; CHECK-LABEL: dword:
; CHECK: # %bb.0:
; CHECK-NEXT: *(u64 *)(r4 + 0) = 1 # encoding: [0x7a,0x04,0x00,0x00,0x01,0x00,0x00,0x00]
; CHECK-NEXT: *(u64 *)(r4 + 8) = -1 # encoding: [0x7a,0x04,0x08,0x00,0xff,0xff,0xff,0xff]
; CHECK-NEXT: *(u64 *)(r4 + 16) = 2000000000 # encoding: [0x7a,0x04,0x10,0x00,0x00,0x94,0x35,0x77]
; CHECK-NEXT: *(u64 *)(r4 + 16) = -2000000000 # encoding: [0x7a,0x04,0x10,0x00,0x00,0x6c,0xca,0x88]
; CHECK-NEXT: r1 = 4294967295 ll # encoding: [0x18,0x01,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
; CHECK-NEXT: *(u64 *)(r4 + 24) = r1 # encoding: [0x7b,0x14,0x18,0x00,0x00,0x00,0x00,0x00]
%p1 = getelementptr i8, ptr %p0, i32 8
%p2 = getelementptr i8, ptr %p0, i32 16
%p3 = getelementptr i8, ptr %p0, i32 24
store volatile i64 1, ptr %p0, align 8
store volatile i64 -1, ptr %p1, align 8
store volatile i64 2000000000, ptr %p2, align 8
store volatile i64 -2000000000, ptr %p2, align 8
store volatile i64 4294967295, ptr %p3, align 8
unreachable
}
define void @unaligned(ptr %p0) {
; CHECK-LABEL: unaligned:
; CHECK: # %bb.0:
; CHECK-NEXT: *(u8 *)(r1 + 1) = 255 # encoding: [0x72,0x01,0x01,0x00,0xff,0x00,0x00,0x00]
; CHECK-NEXT: *(u8 *)(r1 + 0) = 254 # encoding: [0x72,0x01,0x00,0x00,0xfe,0x00,0x00,0x00]
; CHECK-NEXT: *(u16 *)(r1 + 10) = 65535 # encoding: [0x6a,0x01,0x0a,0x00,0xff,0xff,0x00,0x00]
; CHECK-NEXT: *(u16 *)(r1 + 8) = 65534 # encoding: [0x6a,0x01,0x08,0x00,0xfe,0xff,0x00,0x00]
; CHECK-NEXT: *(u32 *)(r1 + 20) = -1 # encoding: [0x62,0x01,0x14,0x00,0xff,0xff,0xff,0xff]
; CHECK-NEXT: *(u32 *)(r1 + 16) = -2 # encoding: [0x62,0x01,0x10,0x00,0xfe,0xff,0xff,0xff]
%p1 = getelementptr i8, ptr %p0, i32 8
%p2 = getelementptr i8, ptr %p0, i32 16
store volatile i16 -2, ptr %p0, align 1
store volatile i32 -2, ptr %p1, align 2
store volatile i64 -2, ptr %p2, align 4
unreachable
}
define void @inline_asm(ptr %p0) {
; CHECK-LABEL: inline_asm:
; CHECK: # %bb.0:
; CHECK-NEXT: #APP
; CHECK-NEXT: *(u32 *)(r0 + 42) = 7 # encoding: [0x62,0x00,0x2a,0x00,0x07,0x00,0x00,0x00]
; CHECK-EMPTY:
; CHECK-NEXT: #NO_APP
call void asm "*(u32 *)(r0 + 42) = 7;", "~{r0},~{mem}"()
unreachable
}