Skip to content

Commit 8066997

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 0b7a18b commit 8066997

File tree

2 files changed

+81
-14
lines changed

2 files changed

+81
-14
lines changed

llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12596,16 +12596,37 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1259612596
}
1259712597

1259812598
ChangeStatus updateImpl(Attributor &A) override {
12599+
assert(A.getInfoCache().getFlatAddressSpace().has_value());
12600+
unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
1259912601
uint32_t OldAddressSpace = AssumedAddressSpace;
12600-
auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
12601-
DepClassTy::REQUIRED);
12602-
auto Pred = [&](Value &Obj) {
12602+
12603+
auto CheckAddressSpace = [&](Value &Obj) {
1260312604
if (isa<UndefValue>(&Obj))
1260412605
return true;
12606+
// If an argument in flat address space only has addrspace cast uses, and
12607+
// those casts are same, then we take the dst addrspace.
12608+
if (auto *Arg = dyn_cast<Argument>(&Obj)) {
12609+
if (Arg->getType()->getPointerAddressSpace() == FlatAS) {
12610+
unsigned CastAddrSpace = FlatAS;
12611+
for (auto *U : Arg->users()) {
12612+
auto *ASCI = dyn_cast<AddrSpaceCastInst>(U);
12613+
if (!ASCI)
12614+
return takeAddressSpace(Obj.getType()->getPointerAddressSpace());
12615+
if (CastAddrSpace != FlatAS &&
12616+
CastAddrSpace != ASCI->getDestAddressSpace())
12617+
return false;
12618+
CastAddrSpace = ASCI->getDestAddressSpace();
12619+
}
12620+
if (CastAddrSpace != FlatAS)
12621+
return takeAddressSpace(CastAddrSpace);
12622+
}
12623+
}
1260512624
return takeAddressSpace(Obj.getType()->getPointerAddressSpace());
1260612625
};
1260712626

12608-
if (!AUO->forallUnderlyingObjects(Pred))
12627+
auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
12628+
DepClassTy::REQUIRED);
12629+
if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
1260912630
return indicatePessimisticFixpoint();
1261012631

1261112632
return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
@@ -12614,17 +12635,21 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1261412635

1261512636
/// See AbstractAttribute::manifest(...).
1261612637
ChangeStatus manifest(Attributor &A) override {
12617-
if (getAddressSpace() == InvalidAddressSpace ||
12618-
getAddressSpace() == getAssociatedType()->getPointerAddressSpace())
12638+
unsigned NewAS = getAddressSpace();
12639+
12640+
if (NewAS == InvalidAddressSpace ||
12641+
NewAS == getAssociatedType()->getPointerAddressSpace())
1261912642
return ChangeStatus::UNCHANGED;
1262012643

12644+
unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
12645+
1262112646
Value *AssociatedValue = &getAssociatedValue();
12622-
Value *OriginalValue = peelAddrspacecast(AssociatedValue);
12647+
Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
1262312648

1262412649
PointerType *NewPtrTy =
12625-
PointerType::get(getAssociatedType()->getContext(), getAddressSpace());
12650+
PointerType::get(getAssociatedType()->getContext(), NewAS);
1262612651
bool UseOriginalValue =
12627-
OriginalValue->getType()->getPointerAddressSpace() == getAddressSpace();
12652+
OriginalValue->getType()->getPointerAddressSpace() == NewAS;
1262812653

1262912654
bool Changed = false;
1263012655

@@ -12684,12 +12709,19 @@ struct AAAddressSpaceImpl : public AAAddressSpace {
1268412709
return AssumedAddressSpace == AS;
1268512710
}
1268612711

12687-
static Value *peelAddrspacecast(Value *V) {
12688-
if (auto *I = dyn_cast<AddrSpaceCastInst>(V))
12689-
return peelAddrspacecast(I->getPointerOperand());
12712+
static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
12713+
if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
12714+
assert(I->getSrcAddressSpace() != FlatAS &&
12715+
"there should not be flat AS -> non-flat AS");
12716+
return I->getPointerOperand();
12717+
}
1269012718
if (auto *C = dyn_cast<ConstantExpr>(V))
12691-
if (C->getOpcode() == Instruction::AddrSpaceCast)
12692-
return peelAddrspacecast(C->getOperand(0));
12719+
if (C->getOpcode() == Instruction::AddrSpaceCast) {
12720+
assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
12721+
FlatAS &&
12722+
"there should not be flat AS -> non-flat AS X");
12723+
return C->getOperand(0);
12724+
}
1269312725
return V;
1269412726
}
1269512727
};

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)