| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 |
| |
| ; RUN: llc -mtriple=bpfel -mattr=+allows-misaligned-mem-access -verify-machineinstrs %s -o - \ |
| ; RUN: | FileCheck --check-prefixes=ALL,MISALIGN %s |
| ; RUN: llc -mtriple=bpfeb -mattr=+allows-misaligned-mem-access -verify-machineinstrs %s -o - \ |
| ; RUN: | FileCheck --check-prefixes=ALL,MISALIGN %s |
| |
| ; RUN: llc -mtriple=bpfel -verify-machineinstrs %s -o - \ |
| ; RUN: | FileCheck --check-prefixes=ALL,ALIGN %s |
| ; RUN: llc -mtriple=bpfeb -verify-machineinstrs %s -o - \ |
| ; RUN: | FileCheck --check-prefixes=ALL,ALIGN %s |
| ; NOTE: |
| ; This test verifies that the new +bpf-allow-misaligned-mem-access |
| ; feature allows the BPF backend to emit direct unaligned load/store |
| ; instructions instead of byte-by-byte emulation sequences. |
| |
| ; --------------------------------------------------------------------- |
| ; i8 load |
| ; --------------------------------------------------------------------- |
| define i8 @test_load_i8(ptr %p) { |
| ; ALL-LABEL: test_load_i8: |
| ; ALL: # %bb.0: |
| ; ALL-NEXT: w{{[0-9]+}} = *(u8 *)(r1 + 0) |
| ; ALL-NEXT: exit |
| %v = load i8, ptr %p, align 1 |
| ret i8 %v |
| } |
| |
| ; --------------------------------------------------------------------- |
| ; i8 store |
| ; --------------------------------------------------------------------- |
| define void @test_store_i8(ptr %p, i8 %v) { |
| ; ALL-LABEL: test_store_i8: |
| ; ALL: # %bb.0: |
| ; ALL-NEXT: *(u8 *)(r1 + 0) = w{{[0-9]+}} |
| ; ALL-NEXT: exit |
| store i8 %v, ptr %p, align 1 |
| ret void |
| } |
| |
| ; --------------------------------------------------------------------- |
| ; i16 load |
| ; --------------------------------------------------------------------- |
| define i16 @test_load_i16(ptr %p) { |
| ; MISALIGN-LABEL: test_load_i16: |
| ; MISALIGN: # %bb.0: |
| ; MISALIGN: w{{[0-9]+}} = *(u16 *)(r1 + 0) |
| ; MISALIGN: exit |
| ; |
| ; ALIGN-LABEL: test_load_i16: |
| ; ALIGN: # %bb.0: |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 0) |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 1) |
| ; ALIGN-DAG: w{{[0-9]+}} <<= 8 |
| ; ALIGN-DAG: w{{[0-9]+}} |= w{{[0-9]+}} |
| ; ALIGN: exit |
| %v = load i16, ptr %p, align 1 |
| ret i16 %v |
| } |
| |
| ; --------------------------------------------------------------------- |
| ; i16 store |
| ; --------------------------------------------------------------------- |
| define void @test_store_i16(ptr %p, i16 %v) { |
| ; MISALIGN-LABEL: test_store_i16: |
| ; MISALIGN: # %bb.0: |
| ; MISALIGN: *(u16 *)(r1 + 0) = w{{[0-9]+}} |
| ; MISALIGN: exit |
| ; |
| ; ALIGN-LABEL: test_store_i16: |
| ; ALIGN: # %bb.0: |
| ; ALIGN-DAG: *(u8 *)(r1 + 0) = w{{[0-9]+}} |
| ; ALIGN-DAG: w{{[0-9]+}} >>= 8 |
| ; ALIGN-DAG: *(u8 *)(r1 + 1) = w{{[0-9]+}} |
| ; ALIGN: exit |
| store i16 %v, ptr %p, align 1 |
| ret void |
| } |
| |
| ; --------------------------------------------------------------------- |
| ; i32 load |
| ; --------------------------------------------------------------------- |
| |
| define i32 @test_load_i32(ptr %p) { |
| ; MISALIGN-LABEL: test_load_i32: |
| ; MISALIGN: # %bb.0: |
| ; MISALIGN: w{{[0-9]+}} = *(u32 *)(r1 + 0) |
| ; MISALIGN: exit |
| ; |
| ; ALIGN-LABEL: test_load_i32: |
| ; ALIGN: # %bb.0: |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 0) |
| ; ALIGN-DAG: w{{[0-9]+}} <<= 8 |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 1) |
| ; ALIGN-DAG: w{{[0-9]+}} |= w{{[0-9]+}} |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 2) |
| ; ALIGN-DAG: w{{[0-9]+}} <<= 16 |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 3) |
| ; ALIGN-DAG: w{{[0-9]+}} <<= 24 |
| ; ALIGN: exit |
| %v = load i32, ptr %p, align 1 |
| ret i32 %v |
| } |
| |
| ; --------------------------------------------------------------------- |
| ; i32 store |
| ; --------------------------------------------------------------------- |
| |
| define void @test_store_i32(ptr %p, i32 %v) { |
| ; MISALIGN-LABEL: test_store_i32: |
| ; MISALIGN: # %bb.0: |
| ; MISALIGN: *(u32 *)(r1 + 0) = w{{[0-9]+}} |
| ; MISALIGN: exit |
| ; |
| ; ALIGN-LABEL: test_store_i32: |
| ; ALIGN: # %bb.0: |
| ; ALIGN-DAG: w{{[0-9]+}} = w{{[0-9]+}} |
| ; ALIGN-DAG: w{{[0-9]+}} >>= 24 |
| ; ALIGN-DAG: *(u8 *)(r1 + 0) = w{{[0-9]+}} |
| ; ALIGN-DAG: w{{[0-9]+}} = w{{[0-9]+}} |
| ; ALIGN-DAG: w{{[0-9]+}} >>= 16 |
| ; ALIGN-DAG: *(u8 *)(r1 + 1) = w{{[0-9]+}} |
| ; ALIGN-DAG: *(u8 *)(r1 + 2) = w{{[0-9]+}} |
| ; ALIGN-DAG: w{{[0-9]+}} >>= 8 |
| ; ALIGN-DAG: *(u8 *)(r1 + 3) = w{{[0-9]+}} |
| ; ALIGN: exit |
| store i32 %v, ptr %p, align 1 |
| ret void |
| } |
| |
| ; --------------------------------------------------------------------- |
| ; i64 load |
| ; --------------------------------------------------------------------- |
| |
| define i64 @test_load_i64(ptr %p) { |
| ; MISALIGN-LABEL: test_load_i64: |
| ; MISALIGN: # %bb.0: |
| ; MISALIGN: r0 = *(u64 *)(r1 + 0) |
| ; MISALIGN: exit |
| ; |
| ; ALIGN-LABEL: test_load_i64: |
| ; ALIGN: # %bb.0: |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 0) |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 1) |
| ; ALIGN-DAG: r{{[0-9]+}} <<= 8 |
| ; ALIGN-DAG: r{{[0-9]+}} |= r{{[0-9]+}} |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 2) |
| ; ALIGN-DAG: r{{[0-9]+}} <<= 16 |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 3) |
| ; ALIGN-DAG: r{{[0-9]+}} <<= 24 |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 4) |
| ; ALIGN-DAG: w{{[0-9]+}} <<= 8 |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 5) |
| ; ALIGN-DAG: w{{[0-9]+}} |= w{{[0-9]+}} |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 6) |
| ; ALIGN-DAG: w{{[0-9]+}} <<= 16 |
| ; ALIGN-DAG: w{{[0-9]+}} = *(u8 *)(r1 + 7) |
| ; ALIGN-DAG: w{{[0-9]+}} <<= 24 |
| ; ALIGN-DAG: r{{[0-9]+}} <<= 32 |
| ; ALIGN: exit |
| %v = load i64, ptr %p, align 1 |
| ret i64 %v |
| } |
| |
| ; --------------------------------------------------------------------- |
| ; i64 store |
| ; --------------------------------------------------------------------- |
| |
| define void @test_store_i64(ptr %p, i64 %v) { |
| ; MISALIGN-LABEL: test_store_i64: |
| ; MISALIGN: # %bb.0: |
| ; MISALIGN: *(u64 *)(r1 + 0) = r2 |
| ; MISALIGN: exit |
| ; |
| ; ALIGN-LABEL: test_store_i64: |
| ; ALIGN: # %bb.0: |
| ; ALIGN-DAG: *(u8 *)(r1 + 0) = w{{[0-9]+}} |
| ; ALIGN-DAG: r{{[0-9]+}} = r{{[0-9]+}} |
| ; ALIGN-DAG: r{{[0-9]+}} >>= 56 |
| ; ALIGN-DAG: *(u8 *)(r1 + 1) = w{{[0-9]+}} |
| ; ALIGN-DAG: r{{[0-9]+}} >>= 48 |
| ; ALIGN-DAG: *(u8 *)(r1 + 2) = w{{[0-9]+}} |
| ; ALIGN-DAG: r{{[0-9]+}} >>= 40 |
| ; ALIGN-DAG: *(u8 *)(r1 + 3) = w{{[0-9]+}} |
| ; ALIGN-DAG: r{{[0-9]+}} >>= 32 |
| ; ALIGN-DAG: *(u8 *)(r1 + 4) = w{{[0-9]+}} |
| ; ALIGN-DAG: r{{[0-9]+}} >>= 24 |
| ; ALIGN-DAG: *(u8 *)(r1 + 5) = w{{[0-9]+}} |
| ; ALIGN-DAG: r{{[0-9]+}} >>= 16 |
| ; ALIGN-DAG: *(u8 *)(r1 + 6) = w{{[0-9]+}} |
| ; ALIGN-DAG: r{{[0-9]+}} >>= 8 |
| ; ALIGN-DAG: *(u8 *)(r1 + 7) = w{{[0-9]+}} |
| ; ALIGN: exit |
| store i64 %v, ptr %p, align 1 |
| ret void |
| } |