x86-64 validation of #7132's profitability refusal (measured on webserver2, Intel Xeon Icelake, commit a3b31c0d8; full data in #7128 (comment)) returned verdict (b): the refusal over-fires on x86-64.
The evidence
The documented root cause of the mandelbrot regression is half AArch64-specific: on ARM, the double-typed counter lets LLVM fuse both loop-exit tests with fcmp+fccmp into one block (12 insn / 1 block), and the i32 form loses that fusion (14 insn / 2 blocks, +2 insn per iteration). x86-64 has no fccmp — the double form already pays two compares and two branches:
| target |
arm A (double) |
arm B (i32) |
Δ insn |
Δ blocks |
| AArch64 (control) |
12 insn / 1 block |
14 / 2 |
+2 |
+1 |
| x86-64 Icelake |
13 insn / 2 blocks |
14 / 2 |
+1 |
0 |
| x86-64 generic SSE2 |
17 / 2 |
18 / 2 |
+1 |
0 |
The residual +1 (induction-phi mov) costs no time: 41 alternating runs, median B/A = 1.0000 — the loop is FP-latency-bound and arm B moves the counter onto idle integer ports (9 FP ops/iter vs 11).
So on x86-64 the refusal denies 9 promotions across 7 workloads and buys nothing. It is not a regression there either — which argues for a per-target term in the cost model, not for weakening the rule where it is right (AArch64).
Suggested shape
collectors/repsel_benefit.rs currently answers "does every hot consumer want a double?" target-independently. The branch-fusion penalty term should be conditioned on the target (present on AArch64-class targets with fccmp, absent on x86-64). The conversion-cost term (sitofp/ucvtf) is target-independent and stays.
Caveats from the measurement
- The x86-64 instruction delta is analytic (exact for the straight-line body × printed trip count); the box's PMU is not virtualised, so there is no directly-counted instructions-retired figure.
- Only
15_mandelbrot was timed; the other six refusal sites are different syntactic shapes and remain unmeasured on x86-64.
x86-64 validation of #7132's profitability refusal (measured on
webserver2, Intel Xeon Icelake, commita3b31c0d8; full data in #7128 (comment)) returned verdict (b): the refusal over-fires on x86-64.The evidence
The documented root cause of the mandelbrot regression is half AArch64-specific: on ARM, the double-typed counter lets LLVM fuse both loop-exit tests with
fcmp+fccmpinto one block (12 insn / 1 block), and the i32 form loses that fusion (14 insn / 2 blocks, +2 insn per iteration). x86-64 has nofccmp— the double form already pays two compares and two branches:The residual +1 (induction-phi
mov) costs no time: 41 alternating runs, median B/A = 1.0000 — the loop is FP-latency-bound and arm B moves the counter onto idle integer ports (9 FP ops/iter vs 11).So on x86-64 the refusal denies 9 promotions across 7 workloads and buys nothing. It is not a regression there either — which argues for a per-target term in the cost model, not for weakening the rule where it is right (AArch64).
Suggested shape
collectors/repsel_benefit.rscurrently answers "does every hot consumer want a double?" target-independently. The branch-fusion penalty term should be conditioned on the target (present on AArch64-class targets withfccmp, absent on x86-64). The conversion-cost term (sitofp/ucvtf) is target-independent and stays.Caveats from the measurement
15_mandelbrotwas timed; the other six refusal sites are different syntactic shapes and remain unmeasured on x86-64.