Skip to content

Commit

Permalink
Use getPointerAddressSpace instead of cast<PointerType>.getAddressSpa…
Browse files Browse the repository at this point in the history
…ce. (JuliaLang#54113)

The former also handles vectors of pointers, which can occur after
vectorization:

```
#5  0x00007f5bfe94de5e in llvm::cast<llvm::PointerType, llvm::Type> (Val=<optimized out>) at llvm/Support/Casting.h:578
578	  assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!");

(rr) up
#6  GCInvariantVerifier::visitAddrSpaceCastInst (this=this@entry=0x7ffd022fbf56, I=...) at julia/src/llvm-gc-invariant-verifier.cpp:66
66	    unsigned ToAS = cast<PointerType>(I.getDestTy())->getAddressSpace();

(rr) call I.dump()
%23 = addrspacecast <4 x ptr addrspace(10)> %wide.load to <4 x ptr addrspace(11)>, !dbg !43
```

Fixes aborts seen in JuliaLang#53070
  • Loading branch information
maleadt authored Apr 19, 2024
1 parent 3364aa5 commit 074ea2a
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 21 deletions.
6 changes: 3 additions & 3 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static Value *maybe_decay_untracked(jl_codectx_t &ctx, Value *V)
static Value *decay_derived(jl_codectx_t &ctx, Value *V)
{
Type *T = V->getType();
if (cast<PointerType>(T)->getAddressSpace() == AddressSpace::Derived)
if (T->getPointerAddressSpace() == AddressSpace::Derived)
return V;
// Once llvm deletes pointer element types, we won't need it here any more either.
Type *NewT = PointerType::getWithSamePointeeType(cast<PointerType>(T), AddressSpace::Derived);
Expand All @@ -68,7 +68,7 @@ static Value *decay_derived(jl_codectx_t &ctx, Value *V)
static Value *maybe_decay_tracked(jl_codectx_t &ctx, Value *V)
{
Type *T = V->getType();
if (cast<PointerType>(T)->getAddressSpace() != AddressSpace::Tracked)
if (T->getPointerAddressSpace() != AddressSpace::Tracked)
return V;
Type *NewT = PointerType::getWithSamePointeeType(cast<PointerType>(T), AddressSpace::Derived);
return ctx.builder.CreateAddrSpaceCast(V, NewT);
Expand Down Expand Up @@ -295,7 +295,7 @@ void jl_debugcache_t::initialize(Module *m) {

static Value *emit_pointer_from_objref(jl_codectx_t &ctx, Value *V)
{
unsigned AS = cast<PointerType>(V->getType())->getAddressSpace();
unsigned AS = V->getType()->getPointerAddressSpace();
if (AS != AddressSpace::Tracked && AS != AddressSpace::Derived)
return V;
V = decay_derived(ctx, V);
Expand Down
5 changes: 3 additions & 2 deletions src/llvm-alloc-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1067,10 +1067,11 @@ void Optimizer::splitOnStack(CallInst *orig_inst)
store_ty = T_pjlvalue;
}
else {
store_ty = PointerType::getWithSamePointeeType(T_pjlvalue, cast<PointerType>(store_ty)->getAddressSpace());
store_ty = PointerType::getWithSamePointeeType(
T_pjlvalue, store_ty->getPointerAddressSpace());
store_val = builder.CreateBitCast(store_val, store_ty);
}
if (cast<PointerType>(store_ty)->getAddressSpace() != AddressSpace::Tracked)
if (store_ty->getPointerAddressSpace() != AddressSpace::Tracked)
store_val = builder.CreateAddrSpaceCast(store_val, pass.T_prjlvalue);
newstore = builder.CreateStore(store_val, slot.slot);
}
Expand Down
29 changes: 15 additions & 14 deletions src/llvm-gc-invariant-verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ struct GCInvariantVerifier : public InstVisitor<GCInvariantVerifier> {
};

void GCInvariantVerifier::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
unsigned FromAS = cast<PointerType>(I.getSrcTy())->getAddressSpace();
unsigned ToAS = cast<PointerType>(I.getDestTy())->getAddressSpace();
unsigned FromAS = I.getSrcTy()->getPointerAddressSpace();
unsigned ToAS = I.getDestTy()->getPointerAddressSpace();
if (FromAS == 0)
return;
Check(ToAS != AddressSpace::Loaded && FromAS != AddressSpace::Loaded,
Expand All @@ -78,10 +78,10 @@ void GCInvariantVerifier::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
}

void GCInvariantVerifier::checkStoreInst(Type *VTy, unsigned AS, Value &SI) {
if (VTy->isPointerTy()) {
if (VTy->isPtrOrPtrVectorTy()) {
/* We currently don't obey this for arguments. That's ok - they're
externally rooted. */
unsigned AS = cast<PointerType>(VTy)->getAddressSpace();
unsigned AS = VTy->getPointerAddressSpace();
Check(AS != AddressSpace::CalleeRooted &&
AS != AddressSpace::Derived,
"Illegal store of decayed value", &SI);
Expand All @@ -107,15 +107,15 @@ void GCInvariantVerifier::visitAtomicCmpXchgInst(AtomicCmpXchgInst &SI) {

void GCInvariantVerifier::visitLoadInst(LoadInst &LI) {
Type *Ty = LI.getType();
if (Ty->isPointerTy()) {
unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
if (Ty->isPtrOrPtrVectorTy()) {
unsigned AS = Ty->getPointerAddressSpace();
Check(AS != AddressSpace::CalleeRooted &&
AS != AddressSpace::Derived,
"Illegal load of gc relevant value", &LI);
}
Ty = LI.getPointerOperand()->getType();
if (Ty->isPointerTy()) {
unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
if (Ty->isPtrOrPtrVectorTy()) {
unsigned AS = Ty->getPointerAddressSpace();
Check(AS != AddressSpace::CalleeRooted,
"Illegal load of callee rooted value", &LI);
}
Expand All @@ -129,18 +129,18 @@ void GCInvariantVerifier::visitReturnInst(ReturnInst &RI) {
if (!RI.getReturnValue())
return;
Type *RTy = RI.getReturnValue()->getType();
if (!RTy->isPointerTy())
if (!RTy->isPtrOrPtrVectorTy())
return;
unsigned AS = cast<PointerType>(RTy)->getAddressSpace();
unsigned AS = RTy->getPointerAddressSpace();
Check(!isSpecialAS(AS) || AS == AddressSpace::Tracked,
"Only gc tracked values may be directly returned", &RI);
}

void GCInvariantVerifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
Type *Ty = GEP.getType();
if (!Ty->isPointerTy())
if (!Ty->isPtrOrPtrVectorTy())
return;
unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
unsigned AS = Ty->getPointerAddressSpace();
if (!isSpecialAS(AS))
return;
/* We're actually ok with GEPs here, as long as they don't feed into any
Expand Down Expand Up @@ -170,8 +170,9 @@ void GCInvariantVerifier::visitCallInst(CallInst &CI) {
continue;
}
Type *Ty = Arg->getType();
Check(Ty->isPointerTy() && cast<PointerType>(Ty)->getAddressSpace() == AddressSpace::Tracked,
"Invalid derived pointer in jlcall", &CI);
Check(Ty->isPtrOrPtrVectorTy() &&
Ty->getPointerAddressSpace() == AddressSpace::Tracked,
"Invalid derived pointer in jlcall", &CI);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/llvm-propagate-addrspaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ struct PropagateJuliaAddrspacesVisitor : public InstVisitor<PropagateJuliaAddrsp
};

static unsigned getValueAddrSpace(Value *V) {
return cast<PointerType>(V->getType())->getAddressSpace();
return V->getType()->getPointerAddressSpace();
}

static bool isSpecialAS(unsigned AS) {
Expand Down Expand Up @@ -139,7 +139,7 @@ Value *PropagateJuliaAddrspacesVisitor::LiftPointer(Module *M, Value *V, Instruc
break;
} else {
// Ok, we've reached a leaf - check if it is eligible for lifting
if (!CurrentV->getType()->isPointerTy() ||
if (!CurrentV->getType()->isPtrOrPtrVectorTy() ||
isSpecialAS(getValueAddrSpace(CurrentV))) {
// If not, poison all (recursive) users of this value, to prevent
// looking at them again in future iterations.
Expand Down
13 changes: 13 additions & 0 deletions test/llvmpasses/gc-invariant-verifier.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; This file is a part of Julia. License is MIT: https://julialang.org/license

; RUN: opt -enable-new-pm=1 --opaque-pointers=1 --load-pass-plugin=libjulia-codegen%shlibext -passes='function(GCInvariantVerifier)' -S %s | FileCheck %s

; CHECK-LABEL: @vectorized_addrspacecast
define ptr addrspace(10) @vectorized_addrspacecast() {
top:
ret ptr addrspace(10) null

vector.ph:
%0 = addrspacecast <4 x ptr addrspace(10)> zeroinitializer to <4 x ptr addrspace(11)>
unreachable
}

0 comments on commit 074ea2a

Please sign in to comment.