When coloring registers for a branch instruction, also make sure that the values passed as EBB arguments are in the registers expected by the EBB. The first time a branch to an EBB is processed, assign the EBB arguments to the registers where the branch arguments already reside so no regmoves are needed.
94 lines
2.1 KiB
Plaintext
94 lines
2.1 KiB
Plaintext
test regalloc
|
|
isa riscv
|
|
|
|
; Test the coalescer.
|
|
; regex: V=v\d+
|
|
; regex: WS=\s+
|
|
|
|
; This function is already CSSA, so no copies should be inserted.
|
|
function %cssa(i32) -> i32 {
|
|
ebb0(v0: i32):
|
|
; not: copy
|
|
; v0 is used by the branch and passed as an arg - that's no conflict.
|
|
brnz v0, ebb1(v0)
|
|
; v0 is live across the branch above. That's no conflict.
|
|
v1 = iadd_imm v0, 7
|
|
jump ebb1(v1)
|
|
|
|
ebb1(v10: i32):
|
|
v11 = iadd_imm v10, 7
|
|
return v11
|
|
}
|
|
|
|
function %trivial(i32) -> i32 {
|
|
ebb0(v0: i32):
|
|
; check: $(cp1=$V) = copy $v0
|
|
; nextln: brnz $v0, $ebb1($cp1)
|
|
brnz v0, ebb1(v0)
|
|
; not: copy
|
|
v1 = iadd_imm v0, 7
|
|
jump ebb1(v1)
|
|
|
|
ebb1(v10: i32):
|
|
; Use v0 in the destination EBB causes a conflict.
|
|
v11 = iadd v10, v0
|
|
return v11
|
|
}
|
|
|
|
; A value is used as an SSA argument twice in the same branch.
|
|
function %dualuse(i32) -> i32 {
|
|
ebb0(v0: i32):
|
|
; check: $(cp1=$V) = copy $v0
|
|
; nextln: brnz $v0, $ebb1($v0, $cp1)
|
|
brnz v0, ebb1(v0, v0)
|
|
; not: copy
|
|
v1 = iadd_imm v0, 7
|
|
v2 = iadd_imm v1, 56
|
|
jump ebb1(v1, v2)
|
|
|
|
ebb1(v10: i32, v11: i32):
|
|
v12 = iadd v10, v11
|
|
return v12
|
|
}
|
|
|
|
; Interference away from the branch
|
|
; The interference can be broken with a copy at either branch.
|
|
function %interference(i32) -> i32 {
|
|
ebb0(v0: i32):
|
|
; not: copy
|
|
brnz v0, ebb1(v0)
|
|
v1 = iadd_imm v0, 7
|
|
; v1 and v0 interfere here:
|
|
trapnz v0
|
|
; check: $(cp1=$V) = copy $v1
|
|
; not: copy
|
|
; check: jump $ebb1($cp1)
|
|
jump ebb1(v1)
|
|
|
|
ebb1(v10: i32):
|
|
; not: copy
|
|
v11 = iadd_imm v10, 7
|
|
return v11
|
|
}
|
|
|
|
; A loop where one induction variable is used as a backedge argument.
|
|
function %fibonacci(i32) -> i32 {
|
|
ebb0(v0: i32):
|
|
; not: copy
|
|
v1 = iconst.i32 1
|
|
v2 = iconst.i32 2
|
|
jump ebb1(v1, v2)
|
|
|
|
ebb1(v10: i32, v11: i32):
|
|
; v11 needs to be isolated because it interferes with v10.
|
|
; check: $ebb1($v10: i32, $(nv11a=$V): i32)
|
|
; check: $v11 = copy $nv11a
|
|
v12 = iadd v10, v11
|
|
v13 = icmp ult v12, v0
|
|
; check: $(nv11b=$V) = copy $v11
|
|
; not: copy
|
|
; check: brnz $v13, $ebb1($nv11b, $v12)
|
|
brnz v13, ebb1(v11, v12)
|
|
return v12
|
|
}
|