Skip to content

Commit d16be3f

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 674a1a5 commit d16be3f

File tree

2 files changed

+76
-13
lines changed

2 files changed

+76
-13
lines changed

llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12589,15 +12589,37 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1258912589

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

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

1260312625
return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
@@ -12606,17 +12628,18 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1260612628

1260712629
/// See AbstractAttribute::manifest(...).
1260812630
ChangeStatus manifest(Attributor &A) override {
12609-
if (getAddressSpace() == InvalidAddressSpace ||
12610-
getAddressSpace() == getAssociatedType()->getPointerAddressSpace())
12631+
unsigned NewAS = getAddressSpace();
12632+
12633+
if (NewAS == InvalidAddressSpace ||
12634+
NewAS == getAssociatedType()->getPointerAddressSpace())
1261112635
return ChangeStatus::UNCHANGED;
1261212636

1261312637
Value *AssociatedValue = &getAssociatedValue();
1261412638
Value *OriginalValue = peelAddrspacecast(AssociatedValue);
12615-
1261612639
PointerType *NewPtrTy =
12617-
PointerType::get(getAssociatedType()->getContext(), getAddressSpace());
12640+
PointerType::get(getAssociatedType()->getContext(), NewAS);
1261812641
bool UseOriginalValue =
12619-
OriginalValue->getType()->getPointerAddressSpace() == getAddressSpace();
12642+
OriginalValue->getType()->getPointerAddressSpace() == NewAS;
1262012643

1262112644
bool Changed = false;
1262212645

@@ -12677,11 +12700,16 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1267712700
}
1267812701

1267912702
static Value *peelAddrspacecast(Value *V) {
12680-
if (auto *I = dyn_cast<AddrSpaceCastInst>(V))
12681-
return peelAddrspacecast(I->getPointerOperand());
12703+
if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
12704+
assert(I->getSrcAddressSpace() && "there should not be AS 0 -> AS X");
12705+
return I->getPointerOperand();
12706+
}
1268212707
if (auto *C = dyn_cast<ConstantExpr>(V))
12683-
if (C->getOpcode() == Instruction::AddrSpaceCast)
12684-
return peelAddrspacecast(C->getOperand(0));
12708+
if (C->getOpcode() == Instruction::AddrSpaceCast) {
12709+
assert(C->getOperand(0)->getType()->getPointerAddressSpace() &&
12710+
"there should not be AS 0 -> AS X");
12711+
return C->getOperand(0);
12712+
}
1268512713
return V;
1268612714
}
1268712715
};

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,38 @@ 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: [[P_CAST_0:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(1)
250+
; CHECK-NEXT: store i32 [[VAL]], ptr addrspace(1) [[P_CAST_0]], align 4
251+
; CHECK-NEXT: ret void
252+
;
253+
%p.cast.0 = addrspacecast ptr %p to ptr addrspace(1)
254+
%p.cast.1 = addrspacecast ptr addrspace(1) %p.cast.0 to ptr
255+
store i32 %val, ptr %p.cast.1
256+
ret void
257+
}
258+
259+
define internal void @use_argument_after_promotion(ptr %p, i32 %val) {
260+
; CHECK-LABEL: define internal void @use_argument_after_promotion(
261+
; CHECK-SAME: ptr [[P:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {
262+
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(1)
263+
; CHECK-NEXT: store i32 [[VAL]], ptr addrspace(1) [[TMP1]], align 4
264+
; CHECK-NEXT: ret void
265+
;
266+
store i32 %val, ptr %p
267+
ret void
268+
}
269+
270+
define void @kernel_argument_promotion_pattern_inter_procedure(ptr %p, i32 %val) {
271+
; CHECK-LABEL: define void @kernel_argument_promotion_pattern_inter_procedure(
272+
; CHECK-SAME: ptr [[P:%.*]], i32 [[VAL:%.*]]) #[[ATTR0]] {
273+
; CHECK-NEXT: call void @use_argument_after_promotion(ptr [[P]], i32 [[VAL]])
274+
; CHECK-NEXT: ret void
275+
;
276+
%p.cast.0 = addrspacecast ptr %p to ptr addrspace(1)
277+
%p.cast.1 = addrspacecast ptr addrspace(1) %p.cast.0 to ptr
278+
call void @use_argument_after_promotion(ptr %p.cast.1, i32 %val)
279+
ret void
280+
}

0 commit comments

Comments
 (0)