diff --git a/lang/README.md b/lang/README.md index 8c52a920..86d489c4 100644 --- a/lang/README.md +++ b/lang/README.md @@ -1144,3 +1144,15 @@ main := fn(): uint { return f } ``` + +#### aliasing_overoptimization +```hb +Foo := struct {ptr: ^uint, rnd: uint} + +main := fn(): uint { + mem := &2 + stru := Foo.(mem, 0); + *stru.ptr = 0 + return *mem +} +``` diff --git a/lang/src/son.rs b/lang/src/son.rs index 8095497a..374cdac8 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -3885,5 +3885,6 @@ mod tests { loop_stores; dead_code_in_loop; infinite_loop_after_peephole; + aliasing_overoptimization; } } diff --git a/lang/src/son/hbvm.rs b/lang/src/son/hbvm.rs index 74df48cf..1bff9fe5 100644 --- a/lang/src/son/hbvm.rs +++ b/lang/src/son/hbvm.rs @@ -675,7 +675,7 @@ impl<'a> Function<'a> { "{:?}", self.nodes[nid] ); - debug_assert_eq!(self.nodes[nid].lock_rc, 0, "{:?}", self.nodes[nid]); + debug_assert_eq!(self.nodes[nid].lock_rc, 0, "{nid} {:?}", self.nodes[nid]); debug_assert!(self.nodes[nid].kind != Kind::Phi || self.nodes[nid].ty != ty::Id::VOID); regalloc2::VReg::new(nid as _, regalloc2::RegClass::Int) } @@ -953,15 +953,18 @@ impl<'a> Function<'a> { } Kind::Stck | Kind::Arg if node.outputs.iter().all(|&n| { - matches!(self.nodes[n].kind, Kind::Stre | Kind::Load - if self.nodes[n].ty.loc(self.tys) == Loc::Reg) - || matches!(self.nodes[n].kind, Kind::BinOp { op: TokenKind::Add } - if self.nodes.is_const(self.nodes[n].inputs[2]) - && self.nodes[n] - .outputs - .iter() - .all(|&n| matches!(self.nodes[n].kind, Kind::Stre | Kind::Load - if self.nodes[n].ty.loc(self.tys) == Loc::Reg))) + matches!(self.nodes[n].kind, Kind::Load + if self.nodes[n].ty.loc(self.tys) == Loc::Reg) + || matches!(self.nodes[n].kind, Kind::Stre + if self.nodes[n].ty.loc(self.tys) == Loc::Reg + && self.nodes[n].inputs[1] != nid) + || matches!(self.nodes[n].kind, Kind::BinOp { op: TokenKind::Add } + if self.nodes.is_const(self.nodes[n].inputs[2]) + && self.nodes[n] + .outputs + .iter() + .all(|&n| matches!(self.nodes[n].kind, Kind::Stre | Kind::Load + if self.nodes[n].ty.loc(self.tys) == Loc::Reg))) }) => self.nodes.lock(nid), Kind::Stck if self.tys.size_of(node.ty) == 0 => self.nodes.lock(nid), Kind::Stck => { diff --git a/lang/tests/son_tests_aliasing_overoptimization.txt b/lang/tests/son_tests_aliasing_overoptimization.txt new file mode 100644 index 00000000..e69de29b