| ; 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 | |
| } |