On 5/27/2026 9:20 PM, Wang Yaduo wrote:
Hi Jeff,
Thanks for the overview :)
My primary focus is on improving benchmark performance,
particularly on SPEC CPU2017. So I'm most interested in areas that
have a direct impact on benchmark scores.
Are there any known issues or ongoing efforts — on either the scalar
or vector side — that are currently limiting SPEC performance?
I'd love to pick up something in that space if there's work that could
use attention.
Ha! There's where Robin and I have lived the last 3 years ;-)
Robin has several ideas in the vector space. I won't try to prioritize
them or even enumerate them all.
On the scalar side, improving the zicond behavior is definitely useful.
We have this tendency to use paired ziconds to implement a generic
conditional move but often there's better sequences. THe way to attack
this (IMHO) is to use a QEMU plugin to dump hot blocks (I can pass along
our plug in if you want it). Then in the output files it generates look
for paired czeros then look for alternate sequences.
Daniel and I were working on a class of these in deepsjeng. Just
looking at a datafile I have lying around:
0x000000000001cfec 19052519606 1.1575%
_Z5fevalP7state_tiP12t_eval_comps.constprop.0
ld a4,48(sp)
ld a5,128(sp)
ld t3,32(sp)
ld t5,136(sp)
or a1,a5,a4
ld a5,64(sp)
or a1,a1,a5
sh3add a5,t0,s1
ld t1,1856(a5)
ld a5,104(sp)
or a1,a1,t2
and a4,t1,t3
snez a4,a4
sh3add a5,t0,a5
ld a0,-1728(a5)
addiw a2,a4,1
and a5,t1,a3
czero.eqz a2,a2,a5
czero.nez a5,a4,a5
add a4,a5,a2
[ ... ]
That says that 1.15% of all the dynamic instructions are in that code
fragment. We use that as a signal to gauge hotness when deciding if a
code generation inefficiency is likely worth chasing. Let's assume for
the sake of argument we want to look more deeply at this case.
Note the czeros with opposite polarity (eqz/nez, both using a5 as the
condition) where the outputs of the czero are consumed in a subsequent
add instruction. That's a conditional move idiom. If we look at the
inputs to the two czero instructions, they're in a2 and a4 respectively
and working backwards we see that a2 and a4 are related (a2 = a4 + 1).
So we've effectively got
a4 = (a5 == 0) ? a4 : a4 + 1
Which we can more efficiently implement as:
a4 = a4 + (a5 != 0)
There was a patch recently posted which may fix this specific instance
(I strongly suspect the sign extend in the add is spoiling the
conditional zero paths through ifcvt.cc). But that's the basic process.
I also suspect there's stuff lying around in leela as I've spent the
least amount of time studying it, though I did just squash out roughly
1% of its instruction stream (see pr 124955). I haven't tested that on
any design yet.
The same procedure was used to find the perlbench case in pr124766.
Anyway, we're happy for any efforts you can do in this space.
jeff