https://github.com/shiltian updated https://github.com/llvm/llvm-project/pull/108258
>From 4f56200b16374ae69b717847872d53a80f505869 Mon Sep 17 00:00:00 2001 From: Shilei Tian <i...@tianshilei.me> Date: Wed, 11 Sep 2024 12:23:32 -0400 Subject: [PATCH] [Attributor] Take the address space from addrspacecast directly If the value to be analyzed is directly from addrspacecast, we take the source address space directly. This is to improve the case where in `AMDGPUPromoteKernelArgumentsPass`, the kernel argument is promoted by insertting an addrspacecast directly from a generic pointer. However, during the analysis, the underlying object will be the generic pointer, instead of the addrspacecast, thus the inferred address space is the generic one, which is not ideal. --- .../Transforms/IPO/AttributorAttributes.cpp | 60 ++++++++++++++----- llvm/test/CodeGen/AMDGPU/aa-as-infer.ll | 33 ++++++++++ 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index b2888f556d7d0d..22f983af85af3e 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -12587,16 +12587,37 @@ struct AAAddressSpaceImpl : public AAAddressSpace { } ChangeStatus updateImpl(Attributor &A) override { + assert(A.getInfoCache().getDL().getFlatAddressSpace().has_value()); + unsigned FlatAS = A.getInfoCache().getDL().getFlatAddressSpace().value(); uint32_t OldAddressSpace = AssumedAddressSpace; - auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this, - DepClassTy::REQUIRED); - auto Pred = [&](Value &Obj) { + + auto CheckAddressSpace = [&](Value &Obj) { if (isa<UndefValue>(&Obj)) return true; + // If an argument in flat address space only has addrspace cast uses, and + // those casts are same, then we take the dst addrspace. + if (auto *Arg = dyn_cast<Argument>(&Obj)) { + if (Arg->getType()->getPointerAddressSpace() == FlatAS) { + unsigned CastAddrSpace = FlatAS; + for (auto *U : Arg->users()) { + auto *ASCI = dyn_cast<AddrSpaceCastInst>(U); + if (!ASCI) + return takeAddressSpace(Obj.getType()->getPointerAddressSpace()); + if (CastAddrSpace != FlatAS && + CastAddrSpace != ASCI->getDestAddressSpace()) + return false; + CastAddrSpace = ASCI->getDestAddressSpace(); + } + if (CastAddrSpace != FlatAS) + return takeAddressSpace(CastAddrSpace); + } + } return takeAddressSpace(Obj.getType()->getPointerAddressSpace()); }; - if (!AUO->forallUnderlyingObjects(Pred)) + auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this, + DepClassTy::REQUIRED); + if (!AUO->forallUnderlyingObjects(CheckAddressSpace)) return indicatePessimisticFixpoint(); return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED @@ -12605,17 +12626,21 @@ struct AAAddressSpaceImpl : public AAAddressSpace { /// See AbstractAttribute::manifest(...). ChangeStatus manifest(Attributor &A) override { - if (getAddressSpace() == InvalidAddressSpace || - getAddressSpace() == getAssociatedType()->getPointerAddressSpace()) + unsigned NewAS = getAddressSpace(); + + if (NewAS == InvalidAddressSpace || + NewAS == getAssociatedType()->getPointerAddressSpace()) return ChangeStatus::UNCHANGED; + unsigned FlatAS = A.getInfoCache().getDL().getFlatAddressSpace().value(); + Value *AssociatedValue = &getAssociatedValue(); - Value *OriginalValue = peelAddrspacecast(AssociatedValue); + Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS); PointerType *NewPtrTy = - PointerType::get(getAssociatedType()->getContext(), getAddressSpace()); + PointerType::get(getAssociatedType()->getContext(), NewAS); bool UseOriginalValue = - OriginalValue->getType()->getPointerAddressSpace() == getAddressSpace(); + OriginalValue->getType()->getPointerAddressSpace() == NewAS; bool Changed = false; @@ -12675,12 +12700,19 @@ struct AAAddressSpaceImpl : public AAAddressSpace { return AssumedAddressSpace == AS; } - static Value *peelAddrspacecast(Value *V) { - if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) - return peelAddrspacecast(I->getPointerOperand()); + static Value *peelAddrspacecast(Value *V, unsigned FlatAS) { + if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) { + assert(I->getSrcAddressSpace() != FlatAS && + "there should not be flat AS -> non-flat AS"); + return I->getPointerOperand(); + } if (auto *C = dyn_cast<ConstantExpr>(V)) - if (C->getOpcode() == Instruction::AddrSpaceCast) - return peelAddrspacecast(C->getOperand(0)); + if (C->getOpcode() == Instruction::AddrSpaceCast) { + assert(C->getOperand(0)->getType()->getPointerAddressSpace() != + FlatAS && + "there should not be flat AS -> non-flat AS X"); + return C->getOperand(0); + } return V; } }; diff --git a/llvm/test/CodeGen/AMDGPU/aa-as-infer.ll b/llvm/test/CodeGen/AMDGPU/aa-as-infer.ll index fdc5debb18915c..cc2c80060231c9 100644 --- a/llvm/test/CodeGen/AMDGPU/aa-as-infer.ll +++ b/llvm/test/CodeGen/AMDGPU/aa-as-infer.ll @@ -243,3 +243,36 @@ define void @foo(ptr addrspace(3) %val) { ret void } +define void @kernel_argument_promotion_pattern_intra_procedure(ptr %p, i32 %val) { +; CHECK-LABEL: define void @kernel_argument_promotion_pattern_intra_procedure( +; CHECK-SAME: ptr [[P:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: store i32 [[VAL]], ptr [[P]], align 4 +; CHECK-NEXT: ret void +; + %p.cast.0 = addrspacecast ptr %p to ptr addrspace(1) + %p.cast.1 = addrspacecast ptr addrspace(1) %p.cast.0 to ptr + store i32 %val, ptr %p.cast.1 + ret void +} + +define internal void @use_argument_after_promotion(ptr %p, i32 %val) { +; CHECK-LABEL: define internal void @use_argument_after_promotion( +; CHECK-SAME: ptr [[P:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: store i32 [[VAL]], ptr [[P]], align 4 +; CHECK-NEXT: ret void +; + store i32 %val, ptr %p + ret void +} + +define void @kernel_argument_promotion_pattern_inter_procedure(ptr %p, i32 %val) { +; CHECK-LABEL: define void @kernel_argument_promotion_pattern_inter_procedure( +; CHECK-SAME: ptr [[P:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: call void @use_argument_after_promotion(ptr [[P]], i32 [[VAL]]) +; CHECK-NEXT: ret void +; + %p.cast.0 = addrspacecast ptr %p to ptr addrspace(1) + %p.cast.1 = addrspacecast ptr addrspace(1) %p.cast.0 to ptr + call void @use_argument_after_promotion(ptr %p.cast.1, i32 %val) + ret void +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits