Fix coloring bug with combined constraints and global values.

The Intel instruction "v1 = ushr v2, v2" will implicitly fix the output
register for v2 to %rcx because the output is tied to the first input
operand and the second input operand is fixed to %rcx.

Make sure we handle this transitive constraint when checking for
interference with the globally live registers.

Fixes #218
This commit is contained in:
Jakob Stoklund Olesen
2018-01-17 15:17:34 -08:00
parent 0a6500c99a
commit dcad3fa339
3 changed files with 61 additions and 6 deletions

View File

@@ -27,3 +27,26 @@ ebb0(v0: i64, v1: i64, v2: i64, v3: i64):
ebb1:
return v4
}
; Found by the Binaryen fuzzer in PR218.
;
; This is a similar situation involving combined constraints on the ushr instruction:
;
; - The %rcx register is already in use by a globally live value.
; - The ushr x, x result is also a globally live value.
;
; Since the ushr x, x result is forced to be placed in %rcx, we must set the replace_global_defines
; flag so it can be reassigned to a different global register.
function %pr218(i64 [%rdi], i64 [%rsi], i64 [%rdx], i64 [%rcx]) -> i64 [%rax] {
ebb0(v0: i64, v1: i64, v2: i64, v3: i64):
; check: regmove $v3, %rcx ->
v4 = ushr v0, v0
; check: $v4 = copy
jump ebb1
ebb1:
; v3 is globally live in %rcx.
; v4 is also globally live. Needs to be assigned something else for the trip across the CFG edge.
v5 = iadd v3, v4
return v5
}