// If all bits of a user are demanded, then we know that nothing below that
// in the def-use chain needs to be changed.
auto *J = dyn_cast<Instruction>(JU);
- if (J && !DB.getDemandedBits(J).isAllOnesValue())
+ if (J && J->getType()->isSized() &&
+ !DB.getDemandedBits(J).isAllOnesValue())
WorkList.push_back(J);
+
+ // Note that we need to check for unsized types above before asking for
+ // demanded bits. Normally, the only way to reach an instruction with an
+ // unsized type is via an instruction that has side effects (or otherwise
+ // will demand its input bits). However, if we have a readnone function
+ // that returns an unsized type (e.g., void), we must avoid asking for the
+ // demanded bits of the function call's return value. A void-returning
+ // readnone function is always dead (and so we can stop walking the use/def
+ // chain here), but the check is necessary to avoid asserting.
}
// DFS through subsequent users while tracking visits to avoid cycles.
// If all bits of a user are demanded, then we know that nothing below
// that in the def-use chain needs to be changed.
auto *K = dyn_cast<Instruction>(KU);
- if (K && !Visited.count(K) && !DB.getDemandedBits(K).isAllOnesValue())
+ if (K && !Visited.count(K) && K->getType()->isSized() &&
+ !DB.getDemandedBits(K).isAllOnesValue())
WorkList.push_back(K);
}
}
--- /dev/null
+; RUN: opt -S -bdce < %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @PR34211(i16* %p) {
+; CHECK-LABEL: @PR34211
+ %not_demanded_but_not_dead = load volatile i16, i16* %p
+ call void @no_side_effects_so_dead(i16 %not_demanded_but_not_dead)
+ ret void
+
+; CHECK: %not_demanded_but_not_dead = load volatile i16, i16* %p
+; CHECK-NEXT: ret void
+}
+
+declare void @no_side_effects_so_dead(i16) #0
+
+attributes #0 = { nounwind readnone }
+