[Attributor][FIX] Avoid dangling value pointers during code modification

When we replace instructions with unreachable we delete instructions. We
now avoid dangling pointers to those deleted instructions in the
`ToBeChangedToUnreachableInsts` set. Other modification collections
might need to be updated in the future as well.
This commit is contained in:
Johannes Doerfert 2020-01-07 15:10:30 -06:00
parent 76aab66d34
commit 1e46eb74be
4 changed files with 33 additions and 3 deletions

View File

@ -171,6 +171,25 @@ template <> struct simplify_type<const WeakVH> {
static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; }
};
// Specialize DenseMapInfo to allow WeakVH to participate in DenseMap.
template <> struct DenseMapInfo<WeakVH> {
static inline WeakVH getEmptyKey() {
return WeakVH(DenseMapInfo<Value *>::getEmptyKey());
}
static inline WeakVH getTombstoneKey() {
return WeakVH(DenseMapInfo<Value *>::getTombstoneKey());
}
static unsigned getHashValue(const WeakVH &Val) {
return DenseMapInfo<Value *>::getHashValue(Val);
}
static bool isEqual(const WeakVH &LHS, const WeakVH &RHS) {
return DenseMapInfo<Value *>::isEqual(LHS, RHS);
}
};
/// Value handle that is nullable, but tries to track the Value.
///
/// This is a value handle that tries hard to point to a Value, even across

View File

@ -1174,7 +1174,7 @@ private:
DenseMap<Use *, Value *> ToBeChangedUses;
/// Instructions we replace with `unreachable` insts after manifest is done.
SmallPtrSet<Instruction *, 8> ToBeChangedToUnreachableInsts;
SmallDenseSet<WeakVH, 16> ToBeChangedToUnreachableInsts;
/// Functions, blocks, and instructions we delete after manifest is done.
///

View File

@ -5668,8 +5668,9 @@ ChangeStatus Attributor::run(Module &M) {
}
}
}
for (Instruction *I : ToBeChangedToUnreachableInsts)
changeToUnreachable(I, /* UseLLVMTrap */ false);
for (auto &V : ToBeChangedToUnreachableInsts)
if (Instruction *I = dyn_cast_or_null<Instruction>(V))
changeToUnreachable(I, /* UseLLVMTrap */ false);
for (Instruction *I : TerminatorsToFold)
ConstantFoldTerminator(I->getParent());

View File

@ -16,6 +16,16 @@ define void @load_wholly_unreachable() {
ret void
}
define void @loads_wholly_unreachable() {
; ATTRIBUTOR-LABEL: @loads_wholly_unreachable(
; ATTRIBUTOR-NEXT: unreachable
;
%a = load i32, i32* null
%b = load i32, i32* null
ret void
}
define void @load_single_bb_unreachable(i1 %cond) {
; ATTRIBUTOR-LABEL: @load_single_bb_unreachable(
; ATTRIBUTOR-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[E:%.*]]