diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 3f0f6c127b456..f986f5406b2b3 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -955,6 +955,15 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { "Global @" + GV.getName() + " has illegal target extension type", GVType); + // Check that the the address space can hold all bits of the type, recognized + // by an access in the address space being able to reach all bytes of the + // type. + Check(!GVType->isSized() || + isUIntN(DL.getAddressSizeInBits(GV.getAddressSpace()), + GV.getGlobalSize(DL)), + "Global variable is too large to fit into the address space", &GV, + GVType); + if (!GV.hasInitializer()) { visitGlobalValue(GV); return; diff --git a/llvm/test/CodeGen/LoongArch/merge-base-offset-tlsle.ll b/llvm/test/CodeGen/LoongArch/merge-base-offset-tlsle.ll index 97d33379913e5..fd1468308ec62 100644 --- a/llvm/test/CodeGen/LoongArch/merge-base-offset-tlsle.ll +++ b/llvm/test/CodeGen/LoongArch/merge-base-offset-tlsle.ll @@ -661,7 +661,7 @@ if.end: ret void } -@g_a64 = dso_local thread_local(localexec) global [614750729487779976 x i64] zeroinitializer, align 8 +@g_a64 = dso_local thread_local(localexec) global [536870911 x i64] zeroinitializer, align 8 define dso_local ptr @tlsle_load_addr_offset_1() nounwind { ; LA32-LABEL: tlsle_load_addr_offset_1: diff --git a/llvm/test/CodeGen/LoongArch/merge-base-offset.ll b/llvm/test/CodeGen/LoongArch/merge-base-offset.ll index ea0fe3d0b0178..31916a4d36864 100644 --- a/llvm/test/CodeGen/LoongArch/merge-base-offset.ll +++ b/llvm/test/CodeGen/LoongArch/merge-base-offset.ll @@ -959,7 +959,7 @@ label: ret ptr %0 } -@g_a64 = dso_local global [614750729487779976 x i64] zeroinitializer, align 8 +@g_a64 = dso_local global [536870911 x i64] zeroinitializer, align 8 define dso_local ptr @load_addr_offset_1() nounwind { ; LA32-LABEL: load_addr_offset_1: diff --git a/llvm/test/Transforms/GlobalOpt/large-element-size.ll b/llvm/test/Transforms/GlobalOpt/large-element-size.ll index 914112af313a5..14a3cd035d26f 100644 --- a/llvm/test/Transforms/GlobalOpt/large-element-size.ll +++ b/llvm/test/Transforms/GlobalOpt/large-element-size.ll @@ -6,7 +6,7 @@ target datalayout = "p:32:32" %struct.t.1 = type { %struct.u.0, %struct.u.0, %struct.u.0, %struct.u.0, i32, i32, i32, i32 } %struct.u.0 = type { i32, i32, i32, i8 } -@s = external global [700 x [24000 x %struct.s.2]], align 1 +@s = external global [700 x [2400 x %struct.s.2]], align 1 @p = global ptr getelementptr (i8, ptr @s, i64 2247483647), align 1 ; CHECK: @p = local_unnamed_addr global ptr getelementptr (i8, ptr @s, i32 -2047483649), align 1 diff --git a/llvm/test/Verifier/global-var-too-big.ll b/llvm/test/Verifier/global-var-too-big.ll new file mode 100644 index 0000000000000..fecb021145ae1 --- /dev/null +++ b/llvm/test/Verifier/global-var-too-big.ll @@ -0,0 +1,21 @@ +; RUN: not opt -S -passes=verify < %s 2>&1 | FileCheck %s + +target datalayout = "e-m:e-p1:16:16-p2:32:32-p3:64:64-i8:8-i32:32-i64:64" + +; Too large for 16-bit address space. +@G1 = internal addrspace(1) global [65536 x i8] zeroinitializer, align 4 + +; Too large for 32-bit address space. +@G2 = internal addrspace(2) global [2147483648 x i16] zeroinitializer, align 4 + +; Fit within the address spaces +@G3 = internal addrspace(1) global [65535 x i8] zeroinitializer, align 4 +@G4 = internal addrspace(2) global [2147483647 x i16] zeroinitializer, align 4 + +; CHECK: Global variable is too large to fit into the address space +; CHECK-NEXT: ptr addrspace(1) @G1 +; CHECK-NEXT: [65536 x i8] +; CHECK: Global variable is too large to fit into the address space +; CHECK-NEXT: ptr addrspace(2) @G2 +; CHECK-NEXT: [2147483648 x i16] +; CHECK-NOT: Global variable is too large to fit into the address space