[llvm] [IR] Require that global value initializers are sized (PR #137358)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 25 09:37:43 PDT 2025


https://github.com/nikic created https://github.com/llvm/llvm-project/pull/137358

While external globals can be unsized, I don't think an unsized initializer makes sense.

It seems like the backend currently ends up treating this as a zero-size global. If people want that behavior, they should declare it as such.

>From d6895cdeb0264e7f989b907e52c0dfcf98b4ea09 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 25 Apr 2025 18:25:48 +0200
Subject: [PATCH] [IR] Require that global value initializers are sized

While external globals can be unsized, I don't think an
unsized initializer makes sense.

It seems like the backend currently ends up treating this as a
zero-size global. If people want that behavior, they should
declare it as such.
---
 llvm/docs/LangRef.rst                               | 2 +-
 llvm/lib/IR/Verifier.cpp                            | 2 ++
 llvm/test/Assembler/2005-05-05-OpaqueUndefValues.ll | 6 +++++-
 llvm/test/Transforms/InstSimplify/gv-alloca-cmp.ll  | 2 +-
 llvm/test/Verifier/global-initializer-sized.ll      | 6 ++++++
 llvm/test/Verifier/scalable-global-vars.ll          | 6 +++---
 6 files changed, 18 insertions(+), 6 deletions(-)
 create mode 100644 llvm/test/Verifier/global-initializer-sized.ll

diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 5bd1d29487139..f8620bf08151d 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -700,7 +700,7 @@ Global Variables
 Global variables define regions of memory allocated at compilation time
 instead of run-time.
 
-Global variable definitions must be initialized.
+Global variable definitions must be initialized with a sized value.
 
 Global variables in other translation units can also be declared, in which
 case they don't have an initializer.
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 84054ddd0298c..968ae464b2e70 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -835,6 +835,8 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
           "Global variable initializer type does not match global "
           "variable type!",
           &GV);
+    Check(GV.getInitializer()->getType()->isSized(),
+          "Global variable initializer must be sized", &GV);
     // If the global has common linkage, it must have a zero initializer and
     // cannot be constant.
     if (GV.hasCommonLinkage()) {
diff --git a/llvm/test/Assembler/2005-05-05-OpaqueUndefValues.ll b/llvm/test/Assembler/2005-05-05-OpaqueUndefValues.ll
index 01456f10c9dc1..e2fdb53058e74 100644
--- a/llvm/test/Assembler/2005-05-05-OpaqueUndefValues.ll
+++ b/llvm/test/Assembler/2005-05-05-OpaqueUndefValues.ll
@@ -2,4 +2,8 @@
 ; RUN: verify-uselistorder %s
 
 %t = type opaque
- at x = global %t undef
+
+define void @test() {
+  %sel = select i1 true, %t undef, %t poison
+  ret void
+}
diff --git a/llvm/test/Transforms/InstSimplify/gv-alloca-cmp.ll b/llvm/test/Transforms/InstSimplify/gv-alloca-cmp.ll
index 4f2544052b215..f30c6379e47e1 100644
--- a/llvm/test/Transforms/InstSimplify/gv-alloca-cmp.ll
+++ b/llvm/test/Transforms/InstSimplify/gv-alloca-cmp.ll
@@ -46,7 +46,7 @@ define i1 @cmp_gv_weak_alloca() {
 }
 
 %opaque = type opaque
- at gv_unsized = weak global %opaque zeroinitializer, align 16
+ at gv_unsized = external global %opaque, align 16
 
 define i1 @cmp_gv_unsized_alloca() {
 ; CHECK-LABEL: define i1 @cmp_gv_unsized_alloca() {
diff --git a/llvm/test/Verifier/global-initializer-sized.ll b/llvm/test/Verifier/global-initializer-sized.ll
new file mode 100644
index 0000000000000..90c2f95f4611a
--- /dev/null
+++ b/llvm/test/Verifier/global-initializer-sized.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+
+%t = type opaque
+ at g = global %t undef
+
+; CHECK: Global variable initializer must be sized 
diff --git a/llvm/test/Verifier/scalable-global-vars.ll b/llvm/test/Verifier/scalable-global-vars.ll
index fb9a3067acba9..9df644d5e10f0 100644
--- a/llvm/test/Verifier/scalable-global-vars.ll
+++ b/llvm/test/Verifier/scalable-global-vars.ll
@@ -13,7 +13,7 @@
 
 ; CHECK-NEXT: Globals cannot contain scalable types
 ; CHECK-NEXT: ptr @ScalableVecStructGlobal
- at ScalableVecStructGlobal = global { i32,  <vscale x 4 x i32> } zeroinitializer
+ at ScalableVecStructGlobal = external global { i32,  <vscale x 4 x i32> }
 
 ; CHECK-NEXT: Globals cannot contain scalable types
 ; CHECK-NEXT: ptr @StructTestGlobal
@@ -23,9 +23,9 @@
 ; CHECK-NEXT: Globals cannot contain scalable types
 ; CHECK-NEXT: ptr @StructArrayTestGlobal
 %struct.array.test = type { [2 x <vscale x 1 x double>] }
- at StructArrayTestGlobal = global %struct.array.test zeroinitializer
+ at StructArrayTestGlobal = external global %struct.array.test
 
 ; CHECK-NEXT: Globals cannot contain scalable types
 ; CHECK-NEXT: ptr @StructTargetTestGlobal
 %struct.target.test = type { target("aarch64.svcount"), target("aarch64.svcount") }
- at StructTargetTestGlobal = global %struct.target.test zeroinitializer
+ at StructTargetTestGlobal = external global %struct.target.test



More information about the llvm-commits mailing list