diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs index af8a901c6e..1a25e22867 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs @@ -46,6 +46,10 @@ impl AliasSet { matches!(self, AliasSet::Unknown) } + pub(super) fn is_empty(&self) -> bool { + matches!(self, AliasSet::Empty) + } + /// Return the single known alias if there is exactly one. /// Otherwise, return None. pub(super) fn single_alias(&self) -> Option { @@ -94,12 +98,21 @@ impl AliasSet { /// This is an optimization to avoid having to look up an entry ready to be modified in the [Block](crate::ssa::opt::mem2reg::block::Block), /// because doing so would involve calling `Arc::make_mut` which clones the entry, ready for modification. pub(super) fn should_unify(&self, other: &Self) -> bool { - if let (Some(self_aliases), Some(other_aliases)) = (&self.aliases, &other.aliases) { - // `unify` would extend `self_aliases` with `other_aliases`, so if `other_aliases` is a subset, then nothing would happen. - !other_aliases.is_subset(self_aliases) - } else { - // `unify` would set `aliases` to `None`, so if it's not `Some`, then nothing would happen. - self.aliases.is_some() + match self { + AliasSet::Unknown => false, + AliasSet::Empty => !other.is_empty(), + AliasSet::Known(id) => match other { + AliasSet::Unknown => !self.is_unknown(), + AliasSet::Empty => false, + AliasSet::Known(other_id) => id != other_id, + AliasSet::KnownMultiple(_) => true, + }, + AliasSet::KnownMultiple(values) => match other { + AliasSet::Unknown => !self.is_unknown(), + AliasSet::Empty => false, + AliasSet::Known(other_id) => values.contains(other_id), + AliasSet::KnownMultiple(other_values) => !other_values.is_subset(values), + }, } }