[llvm] [Attributor] Avoid AS-cast for function pointers (PR #65825)

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 8 18:02:35 PDT 2023


https://github.com/jdoerfert created https://github.com/llvm/llvm-project/pull/65825:

Based on the post-commit discussion of
https://github.com/llvm/llvm-project/commit/37642714edfc382be90ab8ec091e0261465c1b47
we now avoid the AS cast if it is not a no-op.

>From 92ac67b33e11a385f538ade1e129b9b11c4d06e4 Mon Sep 17 00:00:00 2001
From: Johannes Doerfert <johannes at jdoerfert.de>
Date: Fri, 8 Sep 2023 12:59:35 -0700
Subject: [PATCH] [Attributor] Avoid AS-cast for function pointers

Based on the post-commit discussion of
https://github.com/llvm/llvm-project/commit/37642714edfc382be90ab8ec091e0261465c1b47
---
 .../Transforms/IPO/AttributorAttributes.cpp   | 26 +++++++-
 llvm/test/Transforms/Attributor/callgraph.ll  | 63 ++++++++++---------
 2 files changed, 55 insertions(+), 34 deletions(-)

diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 03b5dc3899ac8f8..1447f47bf8a0db7 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -12304,11 +12304,31 @@ struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
                         UsedAssumedInformation))
       return ChangeStatus::UNCHANGED;
 
+    const auto *TTI =
+        A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
+            *CB->getFunction());
+    const DataLayout &DL = A.getDataLayout();
+    LLVMContext &Ctx = CB->getContext();
+
     ChangeStatus Changed = ChangeStatus::UNCHANGED;
     Value *FP = CB->getCalledOperand();
-    if (FP->getType()->getPointerAddressSpace())
-      FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getType(), 0),
-                                 FP->getName() + ".as0", CB);
+    unsigned ProgramAS = A.getDataLayout().getProgramAddressSpace();
+    unsigned PtrAS = FP->getType()->getPointerAddressSpace();
+    // TODO: All we really want is a bitcast, see:
+    // https://github.com/llvm/llvm-project/commit/37642714edfc382be90ab8ec091e0261465c1b47#r126273142
+    if (PtrAS != ProgramAS) {
+      if (TTI->isNoopAddrSpaceCast(PtrAS, ProgramAS)) {
+        FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getType(), 0),
+                                   FP->getName() + ".as0", CB);
+      } else {
+        FP = new IntToPtrInst(
+            new PtrToIntInst(FP,
+                             Type::getIntNTy(Ctx, DL.getPointerTypeSizeInBits(
+                                                      FP->getType())),
+                             "", CB),
+            PointerType::get(Ctx, ProgramAS), "", CB);
+      }
+    }
 
     bool CBIsVoid = CB->getType()->isVoidTy();
     Instruction *IP = CB;
diff --git a/llvm/test/Transforms/Attributor/callgraph.ll b/llvm/test/Transforms/Attributor/callgraph.ll
index a85c6a02a99e57f..b3db037b6f48a3a 100644
--- a/llvm/test/Transforms/Attributor/callgraph.ll
+++ b/llvm/test/Transforms/Attributor/callgraph.ll
@@ -604,50 +604,51 @@ define void @as_cast(ptr %arg) {
 ;
 ; CWRLD-LABEL: @as_cast(
 ; CWRLD-NEXT:    [[FP:%.*]] = load ptr addrspace(1), ptr [[ARG:%.*]], align 8
-; CWRLD-NEXT:    [[FP_AS0:%.*]] = addrspacecast ptr addrspace(1) [[FP]] to ptr
-; CWRLD-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[FP_AS0]], @func3
-; CWRLD-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
-; CWRLD:       2:
+; CWRLD-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[FP]] to i64
+; CWRLD-NEXT:    [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to ptr
+; CWRLD-NEXT:    [[TMP3:%.*]] = icmp eq ptr [[TMP2]], @func3
+; CWRLD-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
+; CWRLD:       4:
 ; CWRLD-NEXT:    tail call void @func3()
-; CWRLD-NEXT:    br label [[TMP21:%.*]]
-; CWRLD:       3:
-; CWRLD-NEXT:    [[TMP4:%.*]] = icmp eq ptr [[FP_AS0]], @func4
-; CWRLD-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
+; CWRLD-NEXT:    br label [[TMP23:%.*]]
 ; CWRLD:       5:
+; CWRLD-NEXT:    [[TMP6:%.*]] = icmp eq ptr [[TMP2]], @func4
+; CWRLD-NEXT:    br i1 [[TMP6]], label [[TMP7:%.*]], label [[TMP8:%.*]]
+; CWRLD:       7:
 ; CWRLD-NEXT:    tail call void @func4()
-; CWRLD-NEXT:    br label [[TMP21]]
-; CWRLD:       6:
-; CWRLD-NEXT:    [[TMP7:%.*]] = icmp eq ptr [[FP_AS0]], @retI32
-; CWRLD-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]]
+; CWRLD-NEXT:    br label [[TMP23]]
 ; CWRLD:       8:
+; CWRLD-NEXT:    [[TMP9:%.*]] = icmp eq ptr [[TMP2]], @retI32
+; CWRLD-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]]
+; CWRLD:       10:
 ; CWRLD-NEXT:    call void @retI32()
-; CWRLD-NEXT:    br label [[TMP21]]
-; CWRLD:       9:
-; CWRLD-NEXT:    [[TMP10:%.*]] = icmp eq ptr [[FP_AS0]], @takeI32
-; CWRLD-NEXT:    br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12:%.*]]
+; CWRLD-NEXT:    br label [[TMP23]]
 ; CWRLD:       11:
+; CWRLD-NEXT:    [[TMP12:%.*]] = icmp eq ptr [[TMP2]], @takeI32
+; CWRLD-NEXT:    br i1 [[TMP12]], label [[TMP13:%.*]], label [[TMP14:%.*]]
+; CWRLD:       13:
 ; CWRLD-NEXT:    call void @takeI32()
-; CWRLD-NEXT:    br label [[TMP21]]
-; CWRLD:       12:
-; CWRLD-NEXT:    [[TMP13:%.*]] = icmp eq ptr [[FP_AS0]], @retFloatTakeFloat
-; CWRLD-NEXT:    br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]]
+; CWRLD-NEXT:    br label [[TMP23]]
 ; CWRLD:       14:
+; CWRLD-NEXT:    [[TMP15:%.*]] = icmp eq ptr [[TMP2]], @retFloatTakeFloat
+; CWRLD-NEXT:    br i1 [[TMP15]], label [[TMP16:%.*]], label [[TMP17:%.*]]
+; CWRLD:       16:
 ; CWRLD-NEXT:    call void @retFloatTakeFloat()
-; CWRLD-NEXT:    br label [[TMP21]]
-; CWRLD:       15:
-; CWRLD-NEXT:    [[TMP16:%.*]] = icmp eq ptr [[FP_AS0]], @retFloatTakeFloatFloatNoundef
-; CWRLD-NEXT:    br i1 [[TMP16]], label [[TMP17:%.*]], label [[TMP18:%.*]]
+; CWRLD-NEXT:    br label [[TMP23]]
 ; CWRLD:       17:
-; CWRLD-NEXT:    call void @retFloatTakeFloatFloatNoundef()
-; CWRLD-NEXT:    br label [[TMP21]]
-; CWRLD:       18:
-; CWRLD-NEXT:    br i1 true, label [[TMP19:%.*]], label [[TMP20:%.*]]
+; CWRLD-NEXT:    [[TMP18:%.*]] = icmp eq ptr [[TMP2]], @retFloatTakeFloatFloatNoundef
+; CWRLD-NEXT:    br i1 [[TMP18]], label [[TMP19:%.*]], label [[TMP20:%.*]]
 ; CWRLD:       19:
-; CWRLD-NEXT:    tail call void @void()
-; CWRLD-NEXT:    br label [[TMP21]]
+; CWRLD-NEXT:    call void @retFloatTakeFloatFloatNoundef()
+; CWRLD-NEXT:    br label [[TMP23]]
 ; CWRLD:       20:
-; CWRLD-NEXT:    unreachable
+; CWRLD-NEXT:    br i1 true, label [[TMP21:%.*]], label [[TMP22:%.*]]
 ; CWRLD:       21:
+; CWRLD-NEXT:    tail call void @void()
+; CWRLD-NEXT:    br label [[TMP23]]
+; CWRLD:       22:
+; CWRLD-NEXT:    unreachable
+; CWRLD:       23:
 ; CWRLD-NEXT:    ret void
 ;
   %fp = load ptr addrspace(1), ptr %arg, align 8



More information about the llvm-commits mailing list