Skip to content

[Attributor] Do not optimize away externally_initialized loads. #128170

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 5 commits into from
Mar 3, 2025

Conversation

Pierre-vh
Copy link
Contributor

Fixes SWDEV-515029

@llvmbot
Copy link
Member

llvmbot commented Feb 21, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Pierre van Houtryve (Pierre-vh)

Changes

Fixes SWDEV-515029


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/IPO/Attributor.cpp (+2-1)
  • (modified) llvm/test/Transforms/Attributor/value-simplify.ll (+19)
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index a1e1a51b201b0..0865e4da1a071 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -260,7 +260,8 @@ AA::getInitialValueForObj(Attributor &A, const AbstractAttribute &QueryingAA,
       return nullptr;
   } else {
     if (!GV->hasLocalLinkage() &&
-        (GV->isInterposable() || !(GV->isConstant() && GV->hasInitializer())))
+        (GV->isInterposable() || GV->isExternallyInitialized() ||
+         !(GV->isConstant() && GV->hasInitializer())))
       return nullptr;
     if (!GV->hasInitializer())
       return UndefValue::get(&Ty);
diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll
index a90fb54fbe74a..59160c0834980 100644
--- a/llvm/test/Transforms/Attributor/value-simplify.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify.ll
@@ -12,6 +12,7 @@ declare ptr @llvm.call.preallocated.arg(token, i32)
 @ConstPtr = constant i32 0, align 4
 @ConstWeakPtr = weak constant i32 0, align 4
 @ConstWeakODRPtr = weak_odr constant i32 0, align 4
+@ExtInitZeroInit = externally_initialized constant i32 zeroinitializer, align 4
 
 ;.
 ; CHECK: @str = private unnamed_addr addrspace(4) constant [1 x i8] zeroinitializer, align 1
@@ -19,6 +20,7 @@ declare ptr @llvm.call.preallocated.arg(token, i32)
 ; CHECK: @ConstPtr = constant i32 0, align 4
 ; CHECK: @ConstWeakPtr = weak constant i32 0, align 4
 ; CHECK: @ConstWeakODRPtr = weak_odr constant i32 0, align 4
+; CHECK: @ExtInitZeroInit = externally_initialized constant i32 0, align 4
 ; CHECK: @S = external global %struct.X
 ; CHECK: @g = internal constant { [2 x ptr] } { [2 x ptr] [ptr @f1, ptr @f2] }
 ; CHECK: @x = external global i32
@@ -1651,6 +1653,23 @@ define i32 @readWeakOdrConst() {
   ret i32 %l
 }
 
+define i32 @readExtInitZeroInit() {
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; TUNIT-LABEL: define {{[^@]+}}@readExtInitZeroInit
+; TUNIT-SAME: () #[[ATTR2]] {
+; TUNIT-NEXT:    [[L:%.*]] = load i32, ptr @ExtInitZeroInit, align 4
+; TUNIT-NEXT:    ret i32 [[L]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CGSCC-LABEL: define {{[^@]+}}@readExtInitZeroInit
+; CGSCC-SAME: () #[[ATTR1]] {
+; CGSCC-NEXT:    [[L:%.*]] = load i32, ptr @ExtInitZeroInit, align 4
+; CGSCC-NEXT:    ret i32 [[L]]
+;
+  %l = load i32, ptr @ExtInitZeroInit
+  ret i32 %l
+}
+
 ;.
 ; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn }
 ; TUNIT: attributes #[[ATTR1]] = { memory(readwrite, argmem: none) }

@Pierre-vh Pierre-vh requested review from arsenm and shiltian February 24, 2025 07:59
return UndefValue::get(&Ty);
if (GV->hasLocalLinkage()) {
// Uninitialized global with local linkage.
if (!GV->hasInitializer())
Copy link
Contributor

Choose a reason for hiding this comment

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

Can that happen? I thought non-external linkage always requires an initializer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, I'm not sure when we should return undef in this case.
Maybe only for external GVs that don't have an initializer, and don't have externally_initialized? Not sure if that even comes up either.
@jdoerfert what should this function do?

Copy link
Contributor

Choose a reason for hiding this comment

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

IIRC we have some global shared variables in OpenMP DeviceRTL that are marked as uninitialized via attribute.

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like the asm parser only allows globals without init if isValidDeclarationLinkage, but I don't see other calls of the function -- we're probably missing verifier enforcement for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nikic Can I land the patch ? It'd fix a crash we've seen in the LTO pipeline.

Copy link
Contributor

Choose a reason for hiding this comment

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

On a second look, we do have a verifier check here:

Check(!GV.isDeclaration() || GV.hasValidDeclarationLinkage(),
"Global is external, but doesn't have external or weak linkage!", &GV);

So I believe you should just drop the !hasInitializer check here. (Or make it an assert.)

@Pierre-vh Pierre-vh requested a review from nikic March 3, 2025 08:29
@Pierre-vh Pierre-vh requested a review from arsenm March 3, 2025 10:40
@Pierre-vh Pierre-vh merged commit 5470dff into llvm:main Mar 3, 2025
11 checks passed
@Pierre-vh Pierre-vh deleted the attributor-extinit branch March 3, 2025 14:10
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Mar 14, 2025
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Mar 14, 2025
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
rocm-ci pushed a commit to ROCm/llvm-project that referenced this pull request Apr 11, 2025
rocm-ci pushed a commit to ROCm/llvm-project that referenced this pull request Apr 11, 2025
jrbyrnes pushed a commit to jrbyrnes/llvm-project that referenced this pull request May 27, 2025
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