forked from OSchip/llvm-project
[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:
parent
76aab66d34
commit
1e46eb74be
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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:%.*]]
|
||||
|
|
Loading…
Reference in New Issue