[llvm] [GlobalOpt] Look through non-PointerType constant expressions. (PR #125205)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 31 03:35:03 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Florian Hahn (fhahn)

<details>
<summary>Changes</summary>

Allow looking through constant expressions. Constant expressions cannot read, modify or leak the global themselves.

I might be missing something, but using analyzeGlobalAux should ensure all (instruction) users that may read, modify or leak the global are checked.

This fixes another regression exposed by
https://github.com/llvm/llvm-project/pull/123518.

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


3 Files Affected:

- (modified) llvm/lib/Transforms/Utils/GlobalStatus.cpp (+12-3) 
- (modified) llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll (-2) 
- (modified) llvm/test/Transforms/GlobalOpt/read-with-constexpr-users.ll (+2-3) 


``````````diff
diff --git a/llvm/lib/Transforms/Utils/GlobalStatus.cpp b/llvm/lib/Transforms/Utils/GlobalStatus.cpp
index 0b3016a86e2875..54a72824129b86 100644
--- a/llvm/lib/Transforms/Utils/GlobalStatus.cpp
+++ b/llvm/lib/Transforms/Utils/GlobalStatus.cpp
@@ -78,8 +78,14 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
           return true;
       } else {
         // Ignore dead constant users.
-        if (!isSafeToDestroyConstant(C))
-          return true;
+        if (!isSafeToDestroyConstant(C)) {
+          if (CE) {
+            if (VisitedUsers.insert(CE).second)
+              if (analyzeGlobalAux(CE, GS, VisitedUsers))
+                return true;
+          } else
+            return true;
+        }
       }
     } else if (const Instruction *I = dyn_cast<Instruction>(UR)) {
       if (!GS.HasMultipleAccessingFunctions) {
@@ -166,9 +172,12 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
         if (MTI->getArgOperand(1) == V)
           GS.IsLoaded = true;
       } else if (const MemSetInst *MSI = dyn_cast<MemSetInst>(I)) {
-        assert(MSI->getArgOperand(0) == V && "Memset only takes one pointer!");
+        if (MSI->getArgOperand(0) != V || MSI->getArgOperand(1) == V)
+          return true;
         if (MSI->isVolatile())
           return true;
+        assert(MSI->getArgOperand(0) == V &&
+               "First argument must be the pointer!");
         GS.StoredType = GlobalStatus::Stored;
       } else if (const auto *CB = dyn_cast<CallBase>(I)) {
         if (CB->getIntrinsicID() == Intrinsic::threadlocal_address) {
diff --git a/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll b/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll
index 1e87d9266cb380..52bdc4343851ab 100644
--- a/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll
+++ b/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll
@@ -12,8 +12,6 @@ declare i32 @fn1()
 define void @stores_single_use_gep_constexpr() {
 ; CHECK-LABEL: @stores_single_use_gep_constexpr(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    store ptr @fn0, ptr @global.20ptr, align 8
-; CHECK-NEXT:    store ptr @fn1, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR:%.*]], ptr @global.20ptr, i64 0, i32 1), align 8
 ; CHECK-NEXT:    ret void
 ;
 entry:
diff --git a/llvm/test/Transforms/GlobalOpt/read-with-constexpr-users.ll b/llvm/test/Transforms/GlobalOpt/read-with-constexpr-users.ll
index 9df31887102f23..1e39cac9722ca5 100644
--- a/llvm/test/Transforms/GlobalOpt/read-with-constexpr-users.ll
+++ b/llvm/test/Transforms/GlobalOpt/read-with-constexpr-users.ll
@@ -5,15 +5,14 @@
 @H = internal global [2 x i64 ] zeroinitializer
 
 ;.
-; CHECK: @G = internal global [2 x i64] zeroinitializer
+; CHECK: @G = internal constant [2 x i64] zeroinitializer
 ; CHECK: @H = internal global [2 x i64] zeroinitializer
 ;.
 define i64 @G_used_by_gep_inttoptr_exprs() {
 ; CHECK-LABEL: define i64 @G_used_by_gep_inttoptr_exprs() local_unnamed_addr {
-; CHECK-NEXT:    [[L:%.*]] = load i64, ptr @G, align 8
 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @G, i64 16) to i64), i64 8) to ptr), i64 1
 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[GEP]], @G
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C]], i64 [[L]], i64 9
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[C]], i64 0, i64 9
 ; CHECK-NEXT:    ret i64 [[SEL]]
 ;
   %l = load i64, ptr @G, align 8

``````````

</details>


https://github.com/llvm/llvm-project/pull/125205


More information about the llvm-commits mailing list