[llvm] d94e847 - [GlobalOpt] Extend CleanupPointerRootUsers to handle CE users.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 2 01:13:04 PST 2023


Author: Florian Hahn
Date: 2023-03-02T10:12:24+01:00
New Revision: d94e8479fcd7cd57fa9c6f3f3aa24d2ad3e11d89

URL: https://github.com/llvm/llvm-project/commit/d94e8479fcd7cd57fa9c6f3f3aa24d2ad3e11d89
DIFF: https://github.com/llvm/llvm-project/commit/d94e8479fcd7cd57fa9c6f3f3aa24d2ad3e11d89.diff

LOG: [GlobalOpt] Extend CleanupPointerRootUsers to handle CE users.

Extend CleanupPointerRootUsers to iterate over a worklist, add users of
constant expressions to the worklist to enable additional cleanups.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D144468

Added: 
    llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll

Modified: 
    llvm/lib/Transforms/IPO/GlobalOpt.cpp
    llvm/test/ThinLTO/X86/import-constant.ll
    llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-gep-constexpr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index bbe9f878973f..25dc748991c3 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -206,8 +206,10 @@ CleanupPointerRootUsers(GlobalVariable *GV,
   // chain of computation and the store to the global in Dead[n].second.
   SmallVector<std::pair<Instruction *, Instruction *>, 32> Dead;
 
+  SmallVector<User *> Worklist(GV->users());
   // Constants can't be pointers to dynamically allocated memory.
-  for (User *U : llvm::make_early_inc_range(GV->users())) {
+  while (!Worklist.empty()) {
+    User *U = Worklist.pop_back_val();
     if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
       Value *V = SI->getValueOperand();
       if (isa<Constant>(V)) {
@@ -238,7 +240,8 @@ CleanupPointerRootUsers(GlobalVariable *GV,
       if (CE->use_empty()) {
         CE->destroyConstant();
         Changed = true;
-      }
+      } else if (isa<GEPOperator>(CE))
+        append_range(Worklist, CE->users());
     } else if (Constant *C = dyn_cast<Constant>(U)) {
       if (isSafeToDestroyConstant(C)) {
         C->destroyConstant();

diff  --git a/llvm/test/ThinLTO/X86/import-constant.ll b/llvm/test/ThinLTO/X86/import-constant.ll
index ae77192c9a52..79d0ef536733 100644
--- a/llvm/test/ThinLTO/X86/import-constant.ll
+++ b/llvm/test/ThinLTO/X86/import-constant.ll
@@ -32,11 +32,11 @@
 ; IMPORT-NEXT: @_ZL3Obj.llvm.{{.*}} = available_externally hidden constant %struct.S { i32 4, i32 8, ptr @val }
 ; IMPORT-NEXT: @outer = internal local_unnamed_addr global %struct.Q zeroinitializer
 
-; OPT: @outer = internal unnamed_addr global %struct.Q zeroinitializer
+; @outer is a write-only variable that's stored to once, so the store and the global can be removed.
+; OPT-NOT: @outer
 
 ; OPT:      define dso_local i32 @main()
 ; OPT-NEXT: entry:
-; OPT-NEXT:   store ptr null, ptr getelementptr inbounds (%struct.Q, ptr @outer, i64 1, i32 0)
 ; OPT-NEXT:   ret i32 12
 
 ; NOREFS:      @_ZL3Obj.llvm.{{.*}} = external hidden constant %struct.S

diff  --git a/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-gep-constexpr.ll b/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-gep-constexpr.ll
index fdcadc937b1f..f9d988f96e31 100644
--- a/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-gep-constexpr.ll
+++ b/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-gep-constexpr.ll
@@ -16,14 +16,6 @@ declare i32 @fn3()
 define void @stores_single_use_gep_constexpr() {
 ; CHECK-LABEL: @stores_single_use_gep_constexpr(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    store ptr @fn1, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR:%.*]], ptr @global.20ptr, i64 0, i32 1), align 8
-; CHECK-NEXT:    store ptr @fn2, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 2), align 8
-; CHECK-NEXT:    store ptr @fn3, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 3), align 8
-; CHECK-NEXT:    store ptr @fn0, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 4), align 8
-; CHECK-NEXT:    store ptr @fn1, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 5), align 8
-; CHECK-NEXT:    store ptr @fn2, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 6), align 8
-; CHECK-NEXT:    store ptr @fn3, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 7), align 8
-; CHECK-NEXT:    store ptr @fn0, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 8), align 8
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -42,8 +34,6 @@ entry:
 define void @stores_multi_use_gep_constexpr() {
 ; CHECK-LABEL: @stores_multi_use_gep_constexpr(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    store i32 0, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR:%.*]], ptr @global.20ptr, i64 0, i32 16), align 8
-; CHECK-NEXT:    store i32 0, ptr getelementptr inbounds ([[STRUCT_GLOBAL_20PTR]], ptr @global.20ptr, i64 0, i32 16), align 8
 ; CHECK-NEXT:    ret void
 ;
 entry:

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
new file mode 100644
index 000000000000..477b617c003e
--- /dev/null
+++ b/llvm/test/Transforms/GlobalOpt/cleanup-pointer-root-users-ptrtoint-add-constexpr.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=globalopt -S %s | FileCheck %s
+
+%struct.global.20ptr = type { ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }
+
+ at global.20ptr = internal unnamed_addr global %struct.global.20ptr zeroinitializer
+
+declare i32 @fn0()
+
+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:
+  store ptr @fn0, ptr getelementptr inbounds (%struct.global.20ptr, ptr @global.20ptr, i64 0, i32 0), align 8
+  store ptr @fn1, ptr getelementptr inbounds (%struct.global.20ptr, ptr @global.20ptr, i64 0, i32 1), align 8
+  ret void
+}
+
+define void @stores_ptrtoint_constexpr() {
+; CHECK-LABEL: @stores_ptrtoint_constexpr(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    store i32 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @global.20ptr to i64), i64 200) to ptr), align 8
+; CHECK-NEXT:    ret void
+;
+entry:
+  store i32 0, ptr inttoptr (i64 add (i64 ptrtoint (ptr @global.20ptr to i64), i64 200) to ptr), align 8
+  ret void
+}


        


More information about the llvm-commits mailing list