# 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 ...