diff --git a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp --- a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp +++ b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp @@ -254,7 +254,7 @@ const LoadSDNode *LD = cast(Node); uint64_t size = LD->getMemOperand()->getSize(); - if (!size || size > 8 || (size & (size - 1))) + if (!size || size > 8 || (size & (size - 1)) || !LD->isSimple()) return; SDNode *LDAddrNode = LD->getOperand(1).getNode(); @@ -342,7 +342,7 @@ unsigned char *ByteSeq) { const GlobalVariable *V = dyn_cast(Node->getGlobal()); - if (!V || !V->hasInitializer()) + if (!V || !V->hasInitializer() || !V->isConstant()) return false; const Constant *Init = V->getInitializer(); diff --git a/llvm/test/CodeGen/BPF/rodata_6.ll b/llvm/test/CodeGen/BPF/rodata_6.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/rodata_6.ll @@ -0,0 +1,25 @@ +; RUN: llc -march=bpf < %s | FileCheck %s +; +; Source code: +; struct t1 { int a; }; +; struct t1 data = { .a = 3 }; +; int foo(void) { +; return data.a + 20; +; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm test.c + +%struct.t1 = type { i32 } + +@data = dso_local local_unnamed_addr global %struct.t1 { i32 3 }, align 4 + +; Function Attrs: norecurse nounwind readonly +define dso_local i32 @foo() local_unnamed_addr { +entry: + %0 = load i32, i32* getelementptr inbounds (%struct.t1, %struct.t1* @data, i64 0, i32 0), align 4 + %add = add nsw i32 %0, 20 +; CHECK: [[REG1:r[0-9]+]] = data ll +; CHECK: r0 = *(u32 *)([[REG1]] + 0) +; CHECK: r0 += 20 + ret i32 %add +} diff --git a/llvm/test/CodeGen/BPF/rodata_7.ll b/llvm/test/CodeGen/BPF/rodata_7.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/rodata_7.ll @@ -0,0 +1,25 @@ +; RUN: llc -march=bpf < %s | FileCheck %s +; +; Source code: +; struct t1 { int a; }; +; volatile const struct t1 data = { .a = 3 }; +; int foo(void) { +; return data.a + 20; +; } +; Compilation flag: +; clang -target bpf -O2 -S -emit-llvm test.c + +%struct.t1 = type { i32 } + +@data = dso_local constant %struct.t1 { i32 3 }, align 4 + +; Function Attrs: nofree norecurse nounwind +define dso_local i32 @foo() local_unnamed_addr { +entry: + %0 = load volatile i32, i32* getelementptr inbounds (%struct.t1, %struct.t1* @data, i64 0, i32 0), align 4 + %add = add nsw i32 %0, 20 +; CHECK: [[REG1:r[0-9]+]] = data ll +; CHECK: r0 = *(u32 *)([[REG1]] + 0) +; CHECK: r0 += 20 + ret i32 %add +}