Make sure return values are assigned an affinity.
When an EBB argument value is used only as a return value, it still needs to be given a register affinity. Otherwise it would appear as a ghost value with no affinity. Do the same to call arguments.
This commit is contained in:
@@ -40,3 +40,26 @@ ebb0(v1: i32, v2: i32):
|
||||
; nextln: return $v2, $v1
|
||||
return v2, v1
|
||||
}
|
||||
|
||||
; Return an EBB argument.
|
||||
function %retebb(i32, i32) -> i32 {
|
||||
ebb0(v1: i32, v2: i32):
|
||||
brnz v1, ebb1(v1)
|
||||
jump ebb1(v2)
|
||||
|
||||
ebb1(v10: i32):
|
||||
return v10
|
||||
}
|
||||
|
||||
; Pass an EBB argument as a function argument.
|
||||
function %callebb(i32, i32) -> i32 {
|
||||
fn0 = function %foo(i32) -> i32
|
||||
|
||||
ebb0(v1: i32, v2: i32):
|
||||
brnz v1, ebb1(v1)
|
||||
jump ebb1(v2)
|
||||
|
||||
ebb1(v10: i32):
|
||||
v11 = call fn0(v10)
|
||||
return v11
|
||||
}
|
||||
|
||||
@@ -376,9 +376,9 @@ impl Liveness {
|
||||
}
|
||||
|
||||
// Iterator of constraints, one per value operand.
|
||||
// TODO: Should we fail here if the instruction doesn't have a valid encoding?
|
||||
let encoding = func.encodings[inst];
|
||||
let mut operand_constraints = enc_info
|
||||
.operand_constraints(func.encodings[inst])
|
||||
.operand_constraints(encoding)
|
||||
.map(|c| c.ins)
|
||||
.unwrap_or(&[])
|
||||
.iter();
|
||||
@@ -392,11 +392,18 @@ impl Liveness {
|
||||
|
||||
// Apply operand constraint, ignoring any variable arguments after the fixed
|
||||
// operands described by `operand_constraints`. Variable arguments are either
|
||||
// EBB arguments or call/return ABI arguments. EBB arguments need to be
|
||||
// resolved by the coloring algorithm, and ABI constraints require specific
|
||||
// registers or stack slots which the affinities don't model anyway.
|
||||
// EBB arguments or call/return ABI arguments.
|
||||
if let Some(constraint) = operand_constraints.next() {
|
||||
lr.affinity.merge(constraint, ®_info);
|
||||
} else if lr.affinity.is_none() && encoding.is_legal() &&
|
||||
!func.dfg[inst].opcode().is_branch() {
|
||||
// This is a real encoded instruction using a value that doesn't yet have a
|
||||
// concrete affinity. Most likely a call argument or a return value. Give
|
||||
// the value a register affinity matching the ABI type.
|
||||
//
|
||||
// EBB arguments on a branch are not required to have an affinity.
|
||||
let rc = isa.regclass_for_abi_type(func.dfg.value_type(arg));
|
||||
lr.affinity = Affinity::Reg(rc.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user