In discussions with @bnjbvr, it came up that generating `OneWayCondBr`s with explicit, hardcoded PC-offsets as part of lowered instruction sequences is actually unsafe, because the register allocator *might* insert a spill or reload into the middle of our sequence. We were careful about this in some cases but somehow missed that it was a general restriction. Conceptually, all inter-instruction references should be via labels at the VCode level; explicit offsets are only ever known at emission time, and resolved by the `MachBuffer`. To allow for conditional trap checks without modifying the CFG (as seen by regalloc) during lowering, this PR instead adds a `TrapIf` pseudo-instruction that conditionally skips a single embedded trap instruction. It lowers to the same `condbr label ; trap ; label: ...` sequence, but without the hardcoded branch-target offset in the lowering code.
29 lines
309 B
Plaintext
29 lines
309 B
Plaintext
test compile
|
|
target aarch64
|
|
|
|
function %f() {
|
|
block0:
|
|
trap user0
|
|
}
|
|
|
|
; check: udf
|
|
|
|
function %g(i64) {
|
|
block0(v0: i64):
|
|
v1 = iconst.i64 42
|
|
v2 = ifcmp v0, v1
|
|
trapif eq v2, user0
|
|
return
|
|
}
|
|
|
|
; check: subs xzr, x0, #42
|
|
; nextln: b.ne 8 ; udf
|
|
|
|
function %h() {
|
|
block0:
|
|
debugtrap
|
|
return
|
|
}
|
|
|
|
; check: brk #0
|