Regalloc solver: check that a variable doesn't exist to test if it can be added (fixes #1123);

This situation could be triggered that can_add_var would return true
while a variable was already added for the given register.

For instance, when we have a reassignment (because of a fixed register
input requirement) and a fixed input conflict on the same fixed
register, this register will not be available in the regs_in set after
inputs_done (because of the fixed input conflict diversion) but will
have its own variable.
This commit is contained in:
Benjamin Bouvier
2019-10-09 13:51:07 +02:00
committed by Dan Gohman
parent beca77c2f8
commit a3f55cdf1f
4 changed files with 412 additions and 1 deletions

View File

@@ -626,7 +626,7 @@ impl Solver {
/// constraints if the value has already been added as a variable or fixed assignment.
fn add_live_var(&mut self, value: Value, rc: RegClass, from: RegUnit, live_through: bool) {
// Check for existing entries for this value.
if self.regs_in.is_avail(rc, from) {
if !self.can_add_var(rc, from) {
// There could be an existing variable entry.
if let Some(v) = self.vars.iter_mut().find(|v| v.value == value) {
// We have an existing variable entry for `value`. Combine the constraints.
@@ -969,6 +969,7 @@ impl Solver {
/// Check if `value` can be added as a variable to help find a solution.
pub fn can_add_var(&mut self, constraint: RegClass, from: RegUnit) -> bool {
!self.regs_in.is_avail(constraint, from)
&& !self.vars.iter().any(|var| var.from == Some(from))
}
}