57 lines
2.3 KiB
YAML
57 lines
2.3 KiB
YAML
# Regression test for the W65816StackSlotCleanup flag-preservation wrap
|
|
# (caeb78e follow-up: course_floor_piece hang / "reads uninitialized memory").
|
|
#
|
|
# RUN (see scripts/smokeTest.sh):
|
|
# llc -march=w65816 -run-pass=w65816-stack-slot-cleanup flagWrapLoopGuard.mir
|
|
#
|
|
# This is the exact miscompiling shape: a loop-guard test `CMPi16imm $a, 0'
|
|
# (e.g. `mi < c->nmovers` with nmovers==0) whose branch reads $p, with a
|
|
# loop-invariant signed-compare bias `LDAfi contactY; EORi16imm #0x8000'
|
|
# scheduled BETWEEN the CMP and the branch. LDA/EOR set N/Z on hardware but
|
|
# are NOT modeled with Defs=[P], so they physically trample the CMP's Z. The
|
|
# StackSlotCleanup pass must bracket both in PHP/PLP so BEQ still sees the CMP's
|
|
# flags. Before the fix its corruptor set (isLdaLike) omitted EORi16imm, so it
|
|
# stopped the backward walk AT the EOR (misclassifying it as the "test"), found
|
|
# no corruptor between it and BEQ, and inserted NO wrap -- the guard branched on
|
|
# (contactY^0x8000)==0 instead of nmovers==0, entered the zero-trip loop, and
|
|
# spun ~65536 iterations reading out of bounds.
|
|
#
|
|
# EXPECTED after the fix: a PHP is inserted before the LDAfi and a PLP after the
|
|
# EORi16imm (the smoke check greps for `PHP` between the CMP and the BEQ).
|
|
# Without the fix there is no PHP/PLP at all.
|
|
--- |
|
|
target datalayout = "e-m:e-p:32:16-i16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S8"
|
|
target triple = "w65816"
|
|
define void @flagWrapLoopGuard() { ret void }
|
|
...
|
|
---
|
|
name: flagWrapLoopGuard
|
|
alignment: 1
|
|
tracksRegLiveness: true
|
|
frameInfo:
|
|
maxAlignment: 2
|
|
adjustsStack: true
|
|
fixedStack:
|
|
- { id: 0, type: default, offset: 4, size: 2, alignment: 1, isImmutable: true }
|
|
stack:
|
|
- { id: 0, name: '', type: spill-slot, offset: 0, size: 2, alignment: 2 }
|
|
body: |
|
|
bb.0:
|
|
successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
|
liveins: $a
|
|
; loop-guard test: nmovers == 0 (the value the BEQ must actually branch on)
|
|
CMPi16imm $a, 0, implicit-def $p
|
|
; loop-invariant signed-compare bias scheduled into the guard gap; these
|
|
; physically set N/Z but are not modeled Defs=[P] -> must be PHP/PLP-wrapped
|
|
$a = LDAfi %fixed-stack.0, 0
|
|
$a = EORi16imm killed $a, -32768
|
|
STAfi killed $a, %stack.0, 0, implicit-def $a
|
|
BEQ %bb.2, implicit $p
|
|
BRA %bb.1
|
|
|
|
bb.1:
|
|
RTS
|
|
|
|
bb.2:
|
|
RTS
|
|
...
|