test regalloc target i686 ; regex: V=v\d+ ; regex: REG=%r([abcd]x|[sd]i) ; Tied operands, both are killed at instruction. function %tied_easy() -> i32 { ebb0: v0 = iconst.i32 12 v1 = iconst.i32 13 ; not: copy ; check: isub v2 = isub v0, v1 return v2 } ; Tied operand is live after instruction. function %tied_alive() -> i32 { ebb0: v0 = iconst.i32 12 v1 = iconst.i32 13 ; check: $(v0c=$V) = copy v0 ; check: v2 = isub $v0c, v1 v2 = isub v0, v1 ; check: v3 = iadd v2, v0 v3 = iadd v2, v0 return v3 } ; Fixed register constraint. function %fixed_op() -> i32 { ebb0: ; check: ,%rax] ; sameln: v0 = iconst.i32 12 v0 = iconst.i32 12 v1 = iconst.i32 13 ; The dynamic shift amount must be in %rcx ; check: regmove v0, %rax -> %rcx v2 = ishl v1, v0 return v2 } ; Fixed register constraint twice. function %fixed_op_twice() -> i32 { ebb0: ; check: ,%rax] ; sameln: v0 = iconst.i32 12 v0 = iconst.i32 12 v1 = iconst.i32 13 ; The dynamic shift amount must be in %rcx ; check: regmove v0, %rax -> %rcx v2 = ishl v1, v0 ; check: regmove v0, %rcx -> $REG ; check: regmove v2, $REG -> %rcx v3 = ishl v0, v2 return v3 } ; Tied use of a diverted register. function %fixed_op_twice() -> i32 { ebb0: ; check: ,%rax] ; sameln: v0 = iconst.i32 12 v0 = iconst.i32 12 v1 = iconst.i32 13 ; The dynamic shift amount must be in %rcx ; check: regmove v0, %rax -> %rcx ; check: v2 = ishl v1, v0 v2 = ishl v1, v0 ; Now v0 is globally allocated to %rax, but diverted to %rcx. ; Check that the tied def gets the diverted register. v3 = isub v0, v2 ; not: regmove ; check: ,%rcx] ; sameln: isub ; Move it into place for the return value. ; check: regmove v3, %rcx -> %rax return v3 }