mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
[InstCombine][GC] Handle gc.relocations of vector type
We introduced gc.relocates of vector-of-pointer types a couple of weeks back. Somehow, I missed updating the InstCombine rule to account for this. If we hit this code path with a vector-of-pointers gc.relocate, we'd crash on a cast<PointerType>. I also took the chance to do a bit of code style cleanup. llvm-svn: 260279
This commit is contained in:
parent
16f8ead77d
commit
0e7cbf4f20
@ -1825,7 +1825,6 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||||||
// facts about the relocate value, while being careful to
|
// facts about the relocate value, while being careful to
|
||||||
// preserve relocation semantics.
|
// preserve relocation semantics.
|
||||||
Value *DerivedPtr = cast<GCRelocateInst>(II)->getDerivedPtr();
|
Value *DerivedPtr = cast<GCRelocateInst>(II)->getDerivedPtr();
|
||||||
auto *GCRelocateType = cast<PointerType>(II->getType());
|
|
||||||
|
|
||||||
// Remove the relocation if unused, note that this check is required
|
// Remove the relocation if unused, note that this check is required
|
||||||
// to prevent the cases below from looping forever.
|
// to prevent the cases below from looping forever.
|
||||||
@ -1836,36 +1835,34 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||||||
// TODO: provide a hook for this in GCStrategy. This is clearly legal for
|
// TODO: provide a hook for this in GCStrategy. This is clearly legal for
|
||||||
// most practical collectors, but there was discussion in the review thread
|
// most practical collectors, but there was discussion in the review thread
|
||||||
// about whether it was legal for all possible collectors.
|
// about whether it was legal for all possible collectors.
|
||||||
if (isa<UndefValue>(DerivedPtr)) {
|
if (isa<UndefValue>(DerivedPtr))
|
||||||
// gc_relocate is uncasted. Use undef of gc_relocate's type to replace it.
|
// Use undef of gc_relocate's type to replace it.
|
||||||
return replaceInstUsesWith(*II, UndefValue::get(GCRelocateType));
|
return replaceInstUsesWith(*II, UndefValue::get(II->getType()));
|
||||||
}
|
|
||||||
|
|
||||||
// The relocation of null will be null for most any collector.
|
if (auto *PT = dyn_cast<PointerType>(II->getType())) {
|
||||||
// TODO: provide a hook for this in GCStrategy. There might be some weird
|
// The relocation of null will be null for most any collector.
|
||||||
// collector this property does not hold for.
|
// TODO: provide a hook for this in GCStrategy. There might be some
|
||||||
if (isa<ConstantPointerNull>(DerivedPtr)) {
|
// weird collector this property does not hold for.
|
||||||
// gc_relocate is uncasted. Use null-pointer of gc_relocate's type to
|
if (isa<ConstantPointerNull>(DerivedPtr))
|
||||||
// replace it.
|
// Use null-pointer of gc_relocate's type to replace it.
|
||||||
return replaceInstUsesWith(*II, ConstantPointerNull::get(GCRelocateType));
|
return replaceInstUsesWith(*II, ConstantPointerNull::get(PT));
|
||||||
}
|
|
||||||
|
// isKnownNonNull -> nonnull attribute
|
||||||
// isKnownNonNull -> nonnull attribute
|
if (isKnownNonNullAt(DerivedPtr, II, DT, TLI))
|
||||||
if (isKnownNonNullAt(DerivedPtr, II, DT, TLI))
|
II->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull);
|
||||||
II->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull);
|
|
||||||
|
// isDereferenceablePointer -> deref attribute
|
||||||
// isDereferenceablePointer -> deref attribute
|
if (isDereferenceablePointer(DerivedPtr, DL))
|
||||||
if (isDereferenceablePointer(DerivedPtr, DL)) {
|
if (Argument *A = dyn_cast<Argument>(DerivedPtr))
|
||||||
if (Argument *A = dyn_cast<Argument>(DerivedPtr)) {
|
II->addDereferenceableAttr(AttributeSet::ReturnIndex,
|
||||||
uint64_t Bytes = A->getDereferenceableBytes();
|
A->getDereferenceableBytes());
|
||||||
II->addDereferenceableAttr(AttributeSet::ReturnIndex, Bytes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: bitcast(relocate(p)) -> relocate(bitcast(p))
|
// TODO: bitcast(relocate(p)) -> relocate(bitcast(p))
|
||||||
// Canonicalize on the type from the uses to the defs
|
// Canonicalize on the type from the uses to the defs
|
||||||
|
|
||||||
// TODO: relocate((gep p, C, C2, ...)) -> gep(relocate(p), C, C2, ...)
|
// TODO: relocate((gep p, C, C2, ...)) -> gep(relocate(p), C, C2, ...)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,3 +50,21 @@ gc:
|
|||||||
no_gc:
|
no_gc:
|
||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; Make sure we don't crash when processing vectors
|
||||||
|
define <2 x i8 addrspace(1)*> @vector(<2 x i8 addrspace(1)*> %obj) gc "statepoint-example" {
|
||||||
|
entry:
|
||||||
|
; CHECK-LABEL: @vector
|
||||||
|
; CHECK: gc.statepoint
|
||||||
|
; CHECK: gc.relocate
|
||||||
|
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0, <2 x i8 addrspace(1)*> %obj)
|
||||||
|
%obj.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 7, i32 7) ; (%obj, %obj)
|
||||||
|
ret <2 x i8 addrspace(1)*> %obj.relocated
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @do_safepoint()
|
||||||
|
|
||||||
|
declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
||||||
|
declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32)
|
||||||
|
declare <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token, i32, i32)
|
||||||
|
Loading…
Reference in New Issue
Block a user