Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[IR] Require that global value initializers are sized #137358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 2, 2025

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Apr 25, 2025

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.

@llvmbot
Copy link
Member

llvmbot commented Apr 25, 2025

@llvm/pr-subscribers-llvm-ir

Author: Nikita Popov (nikic)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/137358.diff

6 Files Affected:

  • (modified) llvm/docs/LangRef.rst (+1-1)
  • (modified) llvm/lib/IR/Verifier.cpp (+2)
  • (modified) llvm/test/Assembler/2005-05-05-OpaqueUndefValues.ll (+5-1)
  • (modified) llvm/test/Transforms/InstSimplify/gv-alloca-cmp.ll (+1-1)
  • (added) llvm/test/Verifier/global-initializer-sized.ll (+6)
  • (modified) llvm/test/Verifier/scalable-global-vars.ll (+3-3)
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
-@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
-@gv_unsized = weak global %opaque zeroinitializer, align 16
+@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
+@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
-@ScalableVecStructGlobal = global { i32,  <vscale x 4 x i32> } zeroinitializer
+@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>] }
-@StructArrayTestGlobal = global %struct.array.test zeroinitializer
+@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") }
-@StructTargetTestGlobal = global %struct.target.test zeroinitializer
+@StructTargetTestGlobal = external global %struct.target.test

@llvmbot
Copy link
Member

llvmbot commented Apr 25, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/137358.diff

6 Files Affected:

  • (modified) llvm/docs/LangRef.rst (+1-1)
  • (modified) llvm/lib/IR/Verifier.cpp (+2)
  • (modified) llvm/test/Assembler/2005-05-05-OpaqueUndefValues.ll (+5-1)
  • (modified) llvm/test/Transforms/InstSimplify/gv-alloca-cmp.ll (+1-1)
  • (added) llvm/test/Verifier/global-initializer-sized.ll (+6)
  • (modified) llvm/test/Verifier/scalable-global-vars.ll (+3-3)
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
-@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
-@gv_unsized = weak global %opaque zeroinitializer, align 16
+@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
+@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
-@ScalableVecStructGlobal = global { i32,  <vscale x 4 x i32> } zeroinitializer
+@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>] }
-@StructArrayTestGlobal = global %struct.array.test zeroinitializer
+@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") }
-@StructTargetTestGlobal = global %struct.target.test zeroinitializer
+@StructTargetTestGlobal = external global %struct.target.test

Copy link

github-actions bot commented Apr 25, 2025

✅ With the latest revision this PR passed the undef deprecator.

@x = global %t undef

define void @test() {
%sel = select i1 true, %t undef, %t poison
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also forbid "select"/"undef"/"poison"/"zeroinitialzer", I think? I don't see any reason to allow writing values with opaque types in any context; it's about as meaningful as a global variable with an opaque type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in #137625.

Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks

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.
@nikic nikic force-pushed the verifier-global-sized branch from d6895cd to 552847e Compare April 30, 2025 13:20
@nikic nikic merged commit a8ec6e8 into llvm:main May 2, 2025
12 checks passed
@nikic nikic deleted the verifier-global-sized branch May 2, 2025 07:52
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
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.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
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.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
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.
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants