diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td --- a/llvm/lib/Target/BPF/BPFInstrInfo.td +++ b/llvm/lib/Target/BPF/BPFInstrInfo.td @@ -67,6 +67,8 @@ [{return isInt<32>(N->getSExtValue()); }]>; def i32immSExt32 : PatLeaf<(i32 imm), [{return isInt<32>(N->getSExtValue()); }]>; +def i64immZExt32 : PatLeaf<(i64 imm), + [{return isUInt<32>(N->getZExtValue()); }]>; // Addressing modes. def ADDRri : ComplexPattern; @@ -411,7 +413,7 @@ } class STOREi64 - : STORE; + : STORE; let Predicates = [BPFNoALU32] in { def STW : STOREi64; @@ -420,6 +422,37 @@ } def STD : STOREi64; +class STORE_imm + : TYPE_LD_ST { + bits<20> addr; + bits<32> imm; + + let Inst{51-48} = addr{19-16}; // base reg + let Inst{47-32} = addr{15-0}; // offset + let Inst{31-0} = imm; + let BPFClass = BPF_ST; +} + +let Predicates = [BPFNoALU32] in { + def STH_imm : STORE_imm; + def STB_imm : STORE_imm; +} +let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in { + def STW32_imm : STORE_imm; + def STH32_imm : STORE_imm; + def STB32_imm : STORE_imm; +} + +// For BPFNoALU32 this handles u32 size stores +// For BPFHasALU32 DAG combiner creates such patterns when splits unaligned stores +def STW_imm : STORE_imm; +def STD_imm : STORE_imm; + // LOAD instructions class LOAD Pattern> : TYPE_LD_ST - : STORE32; + : STORE32; let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in { def STW32 : STOREi32; diff --git a/llvm/test/CodeGen/BPF/basictest.ll b/llvm/test/CodeGen/BPF/basictest.ll --- a/llvm/test/CodeGen/BPF/basictest.ll +++ b/llvm/test/CodeGen/BPF/basictest.ll @@ -8,8 +8,8 @@ } ; CHECK-LABEL: store_imm: -; CHECK: *(u32 *)(r1 + 0) = r{{[03]}} -; CHECK: *(u32 *)(r2 + 4) = r{{[03]}} +; CHECK: *(u32 *)(r1 + 0) = 0 +; CHECK: *(u32 *)(r2 + 4) = 0 define i32 @store_imm(ptr %a, ptr %b) { entry: store i32 0, ptr %a, align 4 diff --git a/llvm/test/CodeGen/BPF/ex1.ll b/llvm/test/CodeGen/BPF/ex1.ll --- a/llvm/test/CodeGen/BPF/ex1.ll +++ b/llvm/test/CodeGen/BPF/ex1.ll @@ -31,10 +31,9 @@ ; CHECK: call 4 ; CHECK: call 9 ; CHECK: if r0 != 0 -; CHECK: r1 = 622884453 -; CHECK: *(u32 *)(r10 - 16) = r1 ; CHECK: r1 = 7214898703899978611 ll ; CHECK: *(u64 *)(r10 - 24) = r1 +; CHECK: *(u32 *)(r10 - 16) = 622884453 ; CHECK: call 11 ; CHECK: r0 = 0 ; CHECK: exit diff --git a/llvm/test/CodeGen/BPF/fi_ri.ll b/llvm/test/CodeGen/BPF/fi_ri.ll --- a/llvm/test/CodeGen/BPF/fi_ri.ll +++ b/llvm/test/CodeGen/BPF/fi_ri.ll @@ -5,10 +5,9 @@ ; Function Attrs: nounwind uwtable define i32 @test() #0 { %key = alloca %struct.key_t, align 4 -; CHECK: r1 = 0 -; CHECK: *(u32 *)(r10 - 8) = r1 -; CHECK: *(u64 *)(r10 - 16) = r1 -; CHECK: *(u64 *)(r10 - 24) = r1 +; CHECK: *(u32 *)(r10 - 8) = 0 +; CHECK: *(u64 *)(r10 - 16) = 0 +; CHECK: *(u64 *)(r10 - 24) = 0 call void @llvm.memset.p0.i64(ptr align 4 %key, i8 0, i64 20, i1 false) ; CHECK: r1 = r10 ; CHECK: r1 += -20 diff --git a/llvm/test/CodeGen/BPF/i128.ll b/llvm/test/CodeGen/BPF/i128.ll --- a/llvm/test/CodeGen/BPF/i128.ll +++ b/llvm/test/CodeGen/BPF/i128.ll @@ -31,7 +31,7 @@ } ; CHECK-LABEL: test -; CHECK: *(u64 *)(r10 - 48) = r{{[0-9]+}} +; CHECK: *(u64 *)(r10 - 48) = 0 ; CHECK: *(u32 *)(r10 - 48) = r{{[0-9]+}} ; Function Attrs: argmemonly nounwind willreturn diff --git a/llvm/test/CodeGen/BPF/remove_truncate_5.ll b/llvm/test/CodeGen/BPF/remove_truncate_5.ll --- a/llvm/test/CodeGen/BPF/remove_truncate_5.ll +++ b/llvm/test/CodeGen/BPF/remove_truncate_5.ll @@ -23,10 +23,8 @@ %1 = alloca %struct.test_t, align 4 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %1) #3 call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 4 %1, ptr align 4 @test.t, i64 16, i1 false) -; CHECK: r1 = 0 -; CHECK: *(u64 *)(r10 - 8) = r1 -; CHECK: r1 = 5 -; CHECK: *(u64 *)(r10 - 16) = r1 +; CHECK: *(u64 *)(r10 - 8) = 0 +; CHECK: *(u64 *)(r10 - 16) = 5 ; CHECK: r1 = r10 ; CHECK: r1 += -16 call void @foo(ptr nonnull %1) #3 diff --git a/llvm/test/CodeGen/BPF/rodata_1.ll b/llvm/test/CodeGen/BPF/rodata_1.ll --- a/llvm/test/CodeGen/BPF/rodata_1.ll +++ b/llvm/test/CodeGen/BPF/rodata_1.ll @@ -36,12 +36,10 @@ tail call void @llvm.memcpy.p0.p0.i64(ptr @g1, ptr @test.t1, i64 3, i1 false) tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 @g2, ptr align 4 @test.t2, i64 20, i1 false) ; CHECK: r1 = g1 -; CHECK: r2 = 0 -; CHECK: *(u8 *)(r1 + 1) = r2 -; CHECK: r3 = 1 -; CHECK: *(u8 *)(r1 + 2) = r3 +; CHECK: *(u8 *)(r1 + 1) = 0 +; CHECK: *(u8 *)(r1 + 2) = 1 ; CHECK: r1 = g2 -; CHECK: *(u32 *)(r1 + 8) = r3 +; CHECK: *(u32 *)(r1 + 8) = 1 ret i32 0 } ; CHECK: .section .rodata,"a",@progbits diff --git a/llvm/test/CodeGen/BPF/rodata_2.ll b/llvm/test/CodeGen/BPF/rodata_2.ll --- a/llvm/test/CodeGen/BPF/rodata_2.ll +++ b/llvm/test/CodeGen/BPF/rodata_2.ll @@ -33,17 +33,13 @@ entry: tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 @g, ptr align 4 @test.t2, i64 32, i1 false) ; CHECK: r1 = g ll -; CHECK: r2 = 3 -; CHECK: *(u32 *)(r1 + 24) = r2 -; CHECK: r2 = 2 -; CHECK: *(u32 *)(r1 + 20) = r2 -; CHECK: r2 = 1 -; CHECK: *(u32 *)(r1 + 16) = r2 -; CHECK: r2 = 0 -; CHECK: *(u32 *)(r1 + 28) = r2 -; CHECK: *(u32 *)(r1 + 8) = r2 -; CHECK: *(u32 *)(r1 + 4) = r2 -; CHECK: *(u32 *)(r1 + 0) = r2 +; CHECK: *(u32 *)(r1 + 28) = 0 +; CHECK: *(u32 *)(r1 + 24) = 3 +; CHECK: *(u32 *)(r1 + 20) = 2 +; CHECK: *(u32 *)(r1 + 16) = 1 +; CHECK: *(u32 *)(r1 + 8) = 0 +; CHECK: *(u32 *)(r1 + 4) = 0 +; CHECK: *(u32 *)(r1 + 0) = 0 ret i32 0 } ; CHECK: .section .rodata.cst32,"aM",@progbits,32 diff --git a/llvm/test/CodeGen/BPF/rodata_3.ll b/llvm/test/CodeGen/BPF/rodata_3.ll --- a/llvm/test/CodeGen/BPF/rodata_3.ll +++ b/llvm/test/CodeGen/BPF/rodata_3.ll @@ -26,10 +26,8 @@ define i32 @test() local_unnamed_addr #0 { entry: tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 @g, ptr align 4 @test.t1, i64 16, i1 false) -; CHECK-EL: r2 = 1 -; CHECK-EL: *(u32 *)(r1 + 0) = r2 -; CHECK-EB: r2 = 16777216 -; CHECK-EB: *(u32 *)(r1 + 0) = r2 +; CHECK-EL: *(u32 *)(r1 + 0) = 1 +; CHECK-EB: *(u32 *)(r1 + 0) = 16777216 ret i32 0 } ; CHECK-EL: .section .rodata.cst16,"aM",@progbits,16 diff --git a/llvm/test/CodeGen/BPF/rodata_4.ll b/llvm/test/CodeGen/BPF/rodata_4.ll --- a/llvm/test/CodeGen/BPF/rodata_4.ll +++ b/llvm/test/CodeGen/BPF/rodata_4.ll @@ -28,10 +28,8 @@ ; CHECK-LABEL: test: entry: tail call void @llvm.memcpy.p0.p0.i64(ptr align 2 @g, ptr align 2 getelementptr inbounds ([4 x %struct.test_t1], ptr @test.t1, i64 0, i64 1), i64 6, i1 false) -; CHECK: r2 = 600 -; CHECK: *(u16 *)(r1 + 2) = r2 -; CHECK: r2 = 60 -; CHECK: *(u16 *)(r1 + 0) = r2 +; CHECK: *(u16 *)(r1 + 2) = 600 +; CHECK: *(u16 *)(r1 + 0) = 60 ret i32 0 } ; CHECK: .section .rodata,"a",@progbits diff --git a/llvm/test/CodeGen/BPF/rodata_5.ll b/llvm/test/CodeGen/BPF/rodata_5.ll --- a/llvm/test/CodeGen/BPF/rodata_5.ll +++ b/llvm/test/CodeGen/BPF/rodata_5.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -march=bpfel -mattr=+alu32 -verify-machineinstrs | FileCheck %s -; RUN: llc < %s -march=bpfeb -mattr=+alu32 -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -march=bpfel -mattr=+alu32 -verify-machineinstrs | FileCheck %s -check-prefixes=CHECK-EL +; RUN: llc < %s -march=bpfeb -mattr=+alu32 -verify-machineinstrs | FileCheck %s -check-prefixes=CHECK-EB ; ; Source Code: ; struct t { @@ -32,10 +32,12 @@ call void @llvm.lifetime.end.p0(i64 3, ptr nonnull %v1) ret i32 0 } -; CHECK-NOT: w{{[0-9]+}} = *(u16 *) -; CHECK-NOT: w{{[0-9]+}} = *(u8 *) -; CHECK: *(u16 *)(r10 - 4) = w{{[0-9]+}} -; CHECK: *(u8 *)(r10 - 2) = w{{[0-9]+}} + +; CHECK-EL: *(u8 *)(r10 - 2) = 0 +; CHECK-EL: *(u16 *)(r10 - 4) = 512 + +; CHECK-EB: *(u8 *)(r10 - 2) = 0 +; CHECK-EB: *(u16 *)(r10 - 4) = 2 ; Function Attrs: argmemonly nounwind willreturn declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) diff --git a/llvm/test/CodeGen/BPF/sanity.ll b/llvm/test/CodeGen/BPF/sanity.ll --- a/llvm/test/CodeGen/BPF/sanity.ll +++ b/llvm/test/CodeGen/BPF/sanity.ll @@ -143,10 +143,9 @@ define void @foo_printf() #1 { ; CHECK-LABEL: foo_printf: ; CHECK: # %bb.0: -; CHECK-NEXT: r1 = 0 -; CHECK-NEXT: *(u8 *)(r10 - 8) = r1 ; CHECK-NEXT: r1 = 729618802566522216 ll ; CHECK-NEXT: *(u64 *)(r10 - 16) = r1 +; CHECK-NEXT: *(u8 *)(r10 - 8) = 0 ; CHECK-NEXT: r1 = r10 ; CHECK-NEXT: r1 += -16 ; CHECK-NEXT: call printf diff --git a/llvm/test/CodeGen/BPF/selectiondag-bug.ll b/llvm/test/CodeGen/BPF/selectiondag-bug.ll --- a/llvm/test/CodeGen/BPF/selectiondag-bug.ll +++ b/llvm/test/CodeGen/BPF/selectiondag-bug.ll @@ -55,8 +55,7 @@ ; CHECK: call 8 ; CHECK-NOT: r{{[0-9]+}} = 0 ; CHECK: [[REG3:r[0-9]+]] = *(u64 *)(r10 - 24) -; CHECK: [[REG1:r[0-9]+]] = 0 -; CHECK: *(u64 *)(r10 - 24) = [[REG1]] +; CHECK: *(u64 *)(r10 - 24) = 0 %probe_read5 = call i64 inttoptr (i64 9 to ptr)(ptr nonnull %"struct kernfs_node.parent", i32 8, i64 %16) %18 = load i64, ptr %"struct kernfs_node.parent", align 8 diff --git a/llvm/test/CodeGen/BPF/store_imm.ll b/llvm/test/CodeGen/BPF/store_imm.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/store_imm.ll @@ -0,0 +1,105 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -march=bpfel -mcpu=v2 -show-mc-encoding -opaque-pointers | FileCheck %s +; RUN: llc < %s -march=bpfel -mcpu=v3 -show-mc-encoding -opaque-pointers | 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 +} diff --git a/llvm/test/CodeGen/BPF/undef.ll b/llvm/test/CodeGen/BPF/undef.ll --- a/llvm/test/CodeGen/BPF/undef.ll +++ b/llvm/test/CodeGen/BPF/undef.ll @@ -19,21 +19,20 @@ ; EB: r1 = 361984551142686720 ll ; CHECK: *(u64 *)(r10 - 8) = r1 -; CHECK: r1 = 0 -; CHECK-DAG: *(u16 *)(r10 + 24) = r1 -; CHECK-DAG: *(u16 *)(r10 + 22) = r1 -; CHECK-DAG: *(u16 *)(r10 + 20) = r1 -; CHECK-DAG: *(u16 *)(r10 + 18) = r1 -; CHECK-DAG: *(u16 *)(r10 + 16) = r1 -; CHECK-DAG: *(u16 *)(r10 + 14) = r1 -; CHECK-DAG: *(u16 *)(r10 + 12) = r1 -; CHECK-DAG: *(u16 *)(r10 + 10) = r1 -; CHECK-DAG: *(u16 *)(r10 + 8) = r1 -; CHECK-DAG: *(u16 *)(r10 + 6) = r1 -; CHECK-DAG: *(u16 *)(r10 + 4) = r1 -; CHECK-DAG: *(u16 *)(r10 + 2) = r1 -; CHECK-DAG: *(u16 *)(r10 + 0) = r1 -; CHECK-DAG: *(u16 *)(r10 + 26) = r1 +; CHECK-DAG: *(u16 *)(r10 + 26) = 0 +; CHECK-DAG: *(u16 *)(r10 + 24) = 0 +; CHECK-DAG: *(u16 *)(r10 + 22) = 0 +; CHECK-DAG: *(u16 *)(r10 + 20) = 0 +; CHECK-DAG: *(u16 *)(r10 + 18) = 0 +; CHECK-DAG: *(u16 *)(r10 + 16) = 0 +; CHECK-DAG: *(u16 *)(r10 + 14) = 0 +; CHECK-DAG: *(u16 *)(r10 + 12) = 0 +; CHECK-DAG: *(u16 *)(r10 + 10) = 0 +; CHECK-DAG: *(u16 *)(r10 + 8) = 0 +; CHECK-DAG: *(u16 *)(r10 + 6) = 0 +; CHECK-DAG: *(u16 *)(r10 + 4) = 0 +; CHECK-DAG: *(u16 *)(r10 + 2) = 0 +; CHECK-DAG: *(u16 *)(r10 + 0) = 0 ; CHECK: r2 = r10 ; CHECK: r2 += -8