32 lines
1.3 KiB
LLVM
32 lines
1.3 KiB
LLVM
; Pin: MachineCopyPropagation must NOT eliminate `COPY $img = $reg` —
|
|
; that COPY actually expands to STA_DP $D? (a DP-memory store to an
|
|
; IMG slot). Libcalls (softDouble, softFloat) use those same DP
|
|
; slots for their own arg-save scratch, so dropping the COPY makes
|
|
; the subsequent LDA_DP read stale memory. Caught by `g = g/x`
|
|
; Newton loop: iter-1's saved x_ml at $D0 was never actually written
|
|
; because MCP dropped the COPY, so iter-2's call to __divdf3 read
|
|
; garbage as its x_ml argument. See feedback_jslpseudo_libcall_img_clobber.md.
|
|
;
|
|
; Fix: disable MachineCopyPropagation in addPostRegAlloc.
|
|
;
|
|
; Symptom shape we pin: for an i64-first-arg double function that
|
|
; calls a libcall, the entry must contain BOTH `stx 0xd?` AND `sta
|
|
; 0xd?` (for I64FirstArg's Img16 arg-save dance) — and they must
|
|
; survive to the asm output. Without the MCP-disable, only one of
|
|
; those (or neither) appears.
|
|
;
|
|
; RUN: llc -mtriple=w65816 -O2 < %s | FileCheck %s
|
|
|
|
declare double @ext_div(double %a, double %b)
|
|
|
|
define double @div_chain(double %x) {
|
|
; CHECK-LABEL: div_chain:
|
|
; Img16 arg-save at function entry — both halves must reach asm:
|
|
; CHECK: stx 0xd
|
|
; CHECK: sta 0xd
|
|
; CHECK: jsl ext_div
|
|
; CHECK: rtl
|
|
entry:
|
|
%r = call double @ext_div(double %x, double %x)
|
|
ret double %r
|
|
}
|