test regalloc target x86_64 haswell ; Test combinations of constraints. ; ; The x86 ushr instruction requires its second operand to be passed in %rcx and its output is ; tied to the first input operand. ; ; If we pass the same value to both operands, both constraints must be satisfied. ; Found by the Binaryen fuzzer in PR221. ; ; Conditions triggering the problem: ; ; - The same value used for a tied operand and a fixed operand. ; - The common value is already in %rcx. ; - The tied output value is live outside the EBB. ; ; Under these conditions, Solver::add_tied_input() would create a variable for the tied input ; without considering the fixed constraint. function %pr221(i64 [%rdi], i64 [%rsi], i64 [%rdx], i64 [%rcx]) -> i64 [%rax] { ebb0(v0: i64, v1: i64, v2: i64, v3: i64): v4 = ushr v3, v3 jump ebb1 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 }