[GlobalOpt] Fix dead const handling in pointer root user cleanup (PR61674)
authorNikita Popov <npopov@redhat.com>
Fri, 24 Mar 2023 13:17:26 +0000 (14:17 +0100)
committerNikita Popov <npopov@redhat.com>
Fri, 24 Mar 2023 13:19:43 +0000 (14:19 +0100)
Rather than cleanup up dead constant expressions as we go along,
do this once at the end. This aligns it with the
CleanupConstantGlobalUsers() implementation and avoids
any invalidation issues.

Fixes https://github.com/llvm/llvm-project/issues/61674.

llvm/lib/Transforms/IPO/GlobalOpt.cpp
llvm/test/Transforms/GlobalOpt/pr61674.ll [new file with mode: 0644]

index 1d56611..fec8d70 100644 (file)
@@ -237,19 +237,8 @@ CleanupPointerRootUsers(GlobalVariable *GV,
           Dead.push_back(std::make_pair(I, MTI));
       }
     } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
-      if (CE->use_empty()) {
-        CE->destroyConstant();
-        Changed = true;
-      } else if (isa<GEPOperator>(CE))
+      if (isa<GEPOperator>(CE))
         append_range(Worklist, CE->users());
-    } else if (Constant *C = dyn_cast<Constant>(U)) {
-      if (isSafeToDestroyConstant(C)) {
-        C->destroyConstant();
-        // This could have invalidated UI, start over from scratch.
-        Dead.clear();
-        CleanupPointerRootUsers(GV, GetTLI);
-        return true;
-      }
     }
   }
 
@@ -271,6 +260,7 @@ CleanupPointerRootUsers(GlobalVariable *GV,
     }
   }
 
+  GV->removeDeadConstantUsers();
   return Changed;
 }
 
diff --git a/llvm/test/Transforms/GlobalOpt/pr61674.ll b/llvm/test/Transforms/GlobalOpt/pr61674.ll
new file mode 100644 (file)
index 0000000..1ca8634
--- /dev/null
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -S -passes=globalopt < %s | FileCheck %s
+
+; Test handling of dead constant expressions in CleanupPointerRootUsers().
+
+@g = internal global [2 x [1 x [6 x ptr]]] zeroinitializer
+
+define void @test() {
+; CHECK-LABEL: define void @test() local_unnamed_addr {
+; CHECK-NEXT:    ret void
+;
+  store ptr null, ptr getelementptr inbounds ([2 x [1 x [6 x ptr]]], ptr @g, i32 0, i32 1), align 1
+  ret void
+
+dead:
+  zext i1 icmp ne (ptr getelementptr inbounds ([2 x [1 x [6 x ptr]]], ptr @g, i32 0, i32 1), ptr getelementptr inbounds ([6 x ptr], ptr getelementptr inbounds ([2 x [1 x [6 x ptr]]], ptr @g, i32 0, i32 1), i32 0, i32 5)) to i16
+  ret void
+}
+
+; uselistorder directives
+uselistorder ptr getelementptr inbounds ([2 x [1 x [6 x ptr]]], ptr @g, i32 0, i32 1), { 1, 2, 0 }