Function: Respect IgnoreLLVMUsed with addrspacecasted functions
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Sat, 3 Dec 2022 00:22:54 +0000 (19:22 -0500)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Fri, 16 Dec 2022 19:24:03 +0000 (14:24 -0500)
Try to respect IgnoreLLVMUsed if the function was addrspacecasted to
match llvm.used's type.

llvm/lib/IR/Function.cpp
llvm/test/Analysis/CallGraph/llvm-used.ll

index aaef089..cd66eeb 100644 (file)
@@ -1905,10 +1905,6 @@ std::optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) {
   return NewDecl;
 }
 
-static bool isPointerCastOperator(const User *U) {
-  return isa<AddrSpaceCastOperator>(U) || isa<BitCastOperator>(U);
-}
-
 /// hasAddressTaken - returns true if there are any uses of this function
 /// other than direct calls or invokes to it. Optionally ignores callback
 /// uses, assume like pointer annotation calls, and references in llvm.used
@@ -1930,7 +1926,8 @@ bool Function::hasAddressTaken(const User **PutOffender,
 
     const auto *Call = dyn_cast<CallBase>(FU);
     if (!Call) {
-      if (IgnoreAssumeLikeCalls && isPointerCastOperator(FU) &&
+      if (IgnoreAssumeLikeCalls &&
+          isa<BitCastOperator, AddrSpaceCastOperator>(FU) &&
           all_of(FU->users(), [](const User *U) {
             if (const auto *I = dyn_cast<IntrinsicInst>(U))
               return I->isAssumeLikeIntrinsic();
@@ -1941,8 +1938,8 @@ bool Function::hasAddressTaken(const User **PutOffender,
 
       if (IgnoreLLVMUsed && !FU->user_empty()) {
         const User *FUU = FU;
-        if (isa<BitCastOperator>(FU) && FU->hasOneUse() &&
-            !FU->user_begin()->user_empty())
+        if (isa<BitCastOperator, AddrSpaceCastOperator>(FU) &&
+            FU->hasOneUse() && !FU->user_begin()->user_empty())
           FUU = *FU->user_begin();
         if (llvm::all_of(FUU->users(), [](const User *U) {
               if (const auto *GV = dyn_cast<GlobalVariable>(U))
index 9f0df15..738a42d 100644 (file)
@@ -8,6 +8,7 @@
 ; CHECK: Call graph node <<null function>><<{{.*}}>>  #uses=0
 ; CHECK-NEXT:  CS<None> calls function 'used1'
 ; CHECK-NEXT:  CS<None> calls function 'used2'
+; CHECK-NEXT:  CS<None> calls function 'used_addrspace1'
 ; CHECK-NEXT:  CS<None> calls function 'unused'
 ; CHECK-EMPTY:
 ; CHECK-NEXT:   Call graph node for function: 'unused'<<{{.*}}>>  #uses=1
 ; CHECK-EMPTY:
 ; CHECK-NEXT:   Call graph node for function: 'used2'<<{{.*}}>>  #uses=1
 ; CHECK-EMPTY:
+; CHECK-NEXT:   Call graph node for function: 'used_addrspace1'<<{{.*}}>>  #uses=1
+; CHECK-EMPTY:
 
-@llvm.used = appending global [1 x ptr] [ptr @used1]
+@llvm.used = appending global [2 x ptr] [ptr @used1, ptr addrspacecast (ptr addrspace(1) @used_addrspace1 to ptr)]
 @llvm.compiler.used = appending global [1 x ptr] [ptr @used2]
 @array = appending global [1 x ptr] [ptr @unused]
 
@@ -31,6 +34,11 @@ entry:
   ret void
 }
 
+define internal void @used_addrspace1() addrspace(1) {
+entry:
+  ret void
+}
+
 define internal void @unused() {
 entry:
   ret void