Skip to content

Commit 081015e

Browse files
committed
[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.
1 parent cfce39f commit 081015e

File tree

2 files changed

+81
-14
lines changed

2 files changed

+81
-14
lines changed

llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12587,16 +12587,38 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1258712587
}
1258812588

1258912589
ChangeStatus updateImpl(Attributor &A) override {
12590+
unsigned FlatAS = A.getInfoCache().getDL().getFlatAddressSpace();
12591+
assert(FlatAS != DataLayout::AS_INVALID);
1259012592
uint32_t OldAddressSpace = AssumedAddressSpace;
12591-
auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
12592-
DepClassTy::REQUIRED);
12593-
auto Pred = [&](Value &Obj) {
12593+
12594+
auto CheckAddressSpace = [&](Value &Obj) {
1259412595
if (isa<UndefValue>(&Obj))
1259512596
return true;
12597+
// If an argument in flat address space only has addrspace cast uses, and
12598+
// those casts are same, then we take the dst addrspace.
12599+
if (auto *Arg = dyn_cast<Argument>(&Obj)) {
12600+
if (FlatAS != DataLayout::AS_INVALID &&
12601+
Arg->getType()->getPointerAddressSpace() == FlatAS) {
12602+
unsigned CastAddrSpace = FlatAS;
12603+
for (auto *U : Arg->users()) {
12604+
auto *ASCI = dyn_cast<AddrSpaceCastInst>(U);
12605+
if (!ASCI)
12606+
return takeAddressSpace(Obj.getType()->getPointerAddressSpace());
12607+
if (CastAddrSpace != FlatAS &&
12608+
CastAddrSpace != ASCI->getDestAddressSpace())
12609+
return false;
12610+
CastAddrSpace = ASCI->getDestAddressSpace();
12611+
}
12612+
if (CastAddrSpace != FlatAS)
12613+
return takeAddressSpace(CastAddrSpace);
12614+
}
12615+
}
1259612616
return takeAddressSpace(Obj.getType()->getPointerAddressSpace());
1259712617
};
1259812618

12599-
if (!AUO->forallUnderlyingObjects(Pred))
12619+
auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
12620+
DepClassTy::REQUIRED);
12621+
if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
1260012622
return indicatePessimisticFixpoint();
1260112623

1260212624
return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
@@ -12605,17 +12627,22 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1260512627

1260612628
/// See AbstractAttribute::manifest(...).
1260712629
ChangeStatus manifest(Attributor &A) override {
12608-
if (getAddressSpace() == DataLayout::AS_INVALID ||
12609-
getAddressSpace() == getAssociatedType()->getPointerAddressSpace())
12630+
unsigned NewAS = getAddressSpace();
12631+
12632+
if (NewAS == DataLayout::AS_INVALID ||
12633+
NewAS == getAssociatedType()->getPointerAddressSpace())
1261012634
return ChangeStatus::UNCHANGED;
1261112635

12636+
unsigned FlatAS = A.getInfoCache().getDL().getFlatAddressSpace();
12637+
assert(FlatAS != DataLayout::AS_INVALID);
12638+
1261212639
Value *AssociatedValue = &getAssociatedValue();
12613-
Value *OriginalValue = peelAddrspacecast(AssociatedValue);
12640+
Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
1261412641

1261512642
PointerType *NewPtrTy =
12616-
PointerType::get(getAssociatedType()->getContext(), getAddressSpace());
12643+
PointerType::get(getAssociatedType()->getContext(), NewAS);
1261712644
bool UseOriginalValue =
12618-
OriginalValue->getType()->getPointerAddressSpace() == getAddressSpace();
12645+
OriginalValue->getType()->getPointerAddressSpace() == NewAS;
1261912646

1262012647
bool Changed = false;
1262112648

@@ -12675,12 +12702,19 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1267512702
return AssumedAddressSpace == AS;
1267612703
}
1267712704

12678-
static Value *peelAddrspacecast(Value *V) {
12679-
if (auto *I = dyn_cast<AddrSpaceCastInst>(V))
12680-
return peelAddrspacecast(I->getPointerOperand());
12705+
static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
12706+
if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
12707+
assert(I->getSrcAddressSpace() != FlatAS &&
12708+
"there should not be flat AS -> non-flat AS");
12709+
return I->getPointerOperand();
12710+
}
1268112711
if (auto *C = dyn_cast<ConstantExpr>(V))
12682-
if (C->getOpcode() == Instruction::AddrSpaceCast)
12683-
return peelAddrspacecast(C->getOperand(0));
12712+
if (C->getOpcode() == Instruction::AddrSpaceCast) {
12713+
assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
12714+
FlatAS &&
12715+
"there should not be flat AS -> non-flat AS X");
12716+
return C->getOperand(0);
12717+
}
1268412718
return V;
1268512719
}
1268612720
};

llvm/test/CodeGen/AMDGPU/aa-as-infer.ll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,36 @@ define void @foo(ptr addrspace(3) %val) {
243243
ret void
244244
}
245245

246+
define void @kernel_argument_promotion_pattern_intra_procedure(ptr %p, i32 %val) {
247+
; CHECK-LABEL: define void @kernel_argument_promotion_pattern_intra_procedure(
248+
; CHECK-SAME: ptr [[P:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {
249+
; CHECK-NEXT: store i32 [[VAL]], ptr [[P]], align 4
250+
; CHECK-NEXT: ret void
251+
;
252+
%p.cast.0 = addrspacecast ptr %p to ptr addrspace(1)
253+
%p.cast.1 = addrspacecast ptr addrspace(1) %p.cast.0 to ptr
254+
store i32 %val, ptr %p.cast.1
255+
ret void
256+
}
257+
258+
define internal void @use_argument_after_promotion(ptr %p, i32 %val) {
259+
; CHECK-LABEL: define internal void @use_argument_after_promotion(
260+
; CHECK-SAME: ptr [[P:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {
261+
; CHECK-NEXT: store i32 [[VAL]], ptr [[P]], align 4
262+
; CHECK-NEXT: ret void
263+
;
264+
store i32 %val, ptr %p
265+
ret void
266+
}
267+
268+
define void @kernel_argument_promotion_pattern_inter_procedure(ptr %p, i32 %val) {
269+
; CHECK-LABEL: define void @kernel_argument_promotion_pattern_inter_procedure(
270+
; CHECK-SAME: ptr [[P:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {
271+
; CHECK-NEXT: call void @use_argument_after_promotion(ptr [[P]], i32 [[VAL]])
272+
; CHECK-NEXT: ret void
273+
;
274+
%p.cast.0 = addrspacecast ptr %p to ptr addrspace(1)
275+
%p.cast.1 = addrspacecast ptr addrspace(1) %p.cast.0 to ptr
276+
call void @use_argument_after_promotion(ptr %p.cast.1, i32 %val)
277+
ret void
278+
}

0 commit comments

Comments
 (0)