peepmatic: Fix a failed assertion due to extra iterations after fixed point
After replacing an instruction with an alias to an earlier value, trying to further optimize that value is unnecessary, since we've already processed it, and also was triggering an assertion.
This commit is contained in:
@@ -611,8 +611,26 @@ pub fn do_preopt<'func, 'isa>(
|
|||||||
|
|
||||||
while let Some(block) = pos.next_block() {
|
while let Some(block) = pos.next_block() {
|
||||||
while let Some(inst) = pos.next_inst() {
|
while let Some(inst) = pos.next_inst() {
|
||||||
preopt.apply_all(&mut pos, ValueOrInst::Inst(inst));
|
// After we apply one optimization, that might make another
|
||||||
let inst = pos.current_inst().unwrap();
|
// optimization applicable. Keep running the peephole optimizer
|
||||||
|
// until either:
|
||||||
|
//
|
||||||
|
// * No optimization applied, and therefore it doesn't make sense to
|
||||||
|
// try again, because no optimization will apply again.
|
||||||
|
//
|
||||||
|
// * Or when we replaced an instruction with an alias to an existing
|
||||||
|
// value, because we already ran the peephole optimizer over the
|
||||||
|
// aliased value's instruction in an early part of the traversal
|
||||||
|
// over the function.
|
||||||
|
while let Some(ValueOrInst::Inst(new_inst)) =
|
||||||
|
preopt.apply_one(&mut pos, ValueOrInst::Inst(inst))
|
||||||
|
{
|
||||||
|
// We transplanted a new instruction into the current
|
||||||
|
// instruction, so the "new" instruction is actually the same
|
||||||
|
// one, just with different data.
|
||||||
|
debug_assert_eq!(new_inst, inst);
|
||||||
|
}
|
||||||
|
debug_assert_eq!(pos.current_inst(), Some(inst));
|
||||||
|
|
||||||
// Try to transform divide-by-constant into simpler operations.
|
// Try to transform divide-by-constant into simpler operations.
|
||||||
if let Some(divrem_info) = get_div_info(inst, &pos.func.dfg) {
|
if let Some(divrem_info) = get_div_info(inst, &pos.func.dfg) {
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
test simple_preopt
|
||||||
|
target x86_64
|
||||||
|
|
||||||
|
;; This file used to trigger assertions where we would keep trying to
|
||||||
|
;; unnecessarily apply optimizations after replacing an instruction with an
|
||||||
|
;; alias of another value that we had already optimized.
|
||||||
|
|
||||||
|
function %foo() {
|
||||||
|
block0:
|
||||||
|
v0 = iconst.i32 3
|
||||||
|
v1 = srem_imm v0, 2
|
||||||
|
v2 = sdiv_imm v1, 1
|
||||||
|
trap unreachable
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user