test regalloc isa intel ; 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 }