When I first added the patterns for LFIWAX and LFIWZX instructions (back in 2010), I wanted to add support for these instructions, but at the time we didn't have automatic sign/zero extension from SImode to DImode, and I was worried about allowing SImode in the floating point and vector registers. The initial pattern that is generated is: (insn 6 5 7 (parallel [ (set (reg:DF 120) (float:DF (mem:SI (reg/v/f:DI 119 [ p ]) [1 *p_3(D)+0 S4 A32]))) (clobber (scratch:DI)) ]) "foo50.c":1:30 -1 (nil)) After the split1 pass we generate: (insn 15 6 16 2 (set (reg:DI 122) (unspec:DI [ (mem:SI (reg:DI 121) [1 *p_3(D)+0 S4 A32]) ] UNSPEC_LFIWAX)) "foo50.c":1:1 -1 (nil)) (insn 16 15 12 2 (set (reg/i:DF 33 1) (float:DF (reg:DI 122))) "foo50.c":1:1 -1 (nil)) Instead, we should generate in the split1 pass: (insn 15 6 16 2 (set (reg:DI 122) (sign_extend:DI (mem:SI (reg:DI 121)))) (insn 16 15 12 2 (set (reg/i:DF 33 1) (float:DF (reg:DI 122))) "foo50.c":1:1 -1 (nil)) And delete the lfiwax (and similar lfiwzx) patterns. Obviously, we want to make sure we don't affect code generation for the power7 targets (for lfiwax/lfiwzx) and power6 targets (for just lfiwax).
gen_lfiwax is called by the splitters of floatsi<mode>2_lfiwax and floatsi<mode>2_lfiwax_mem, which you say can go away (nice :-) ); but it is also called by *round32<mode>2_fprs, which needs to be dealt with first (and similarly *roundu32<mode>2_fprs). Do we need most of these splitters at all?
Round can call sign/zero_extend directly. My thought is I want to redo the splitters so they are similar to the QImode and HImode float patterns in power9. I.e. keep the insn until after reload and then split into sign/zero extend and convert. The reason is for offset addresses, the register allocator seems to think it is a better idea to load it into a GPR (which has offset loads) and then do a direct move to the fpr/vector registers. Instead I tend to think LI of the offset and using the LFIWAX/LFIWZX instructions to load it to a fpr/vector register directly.
Unfortunately, it won't be possible to eliminate the lfiwax and lfiwzx patterns completely. These are still needed on 32-bit system, where the sign/zero extend SImode to DImode is only done in GPR registers. But for 64-bit systems, we can eliminate using lfiwax/lfiwzk and use the normal patterns.
I split part of the issue off into a separate bug (PR target/91009).
GCC 10.1 has been released.
GCC 10.2 is released, adjusting target milestone.
GCC 10.3 is being released, retargeting bugs to GCC 10.4.
GCC 10.4 is being released, retargeting bugs to GCC 10.5.