https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119509
--- Comment #9 from Jeffrey A. Law <law at gcc dot gnu.org> ---
So I was looking at this for riscv. While I think the code can clearly be
improved, the path for doing so is far from obvious.
In the .optimize dump we have:
_5 = val_2(D) & 16776960;
_1 = _5 > 255;
_3 = (unsigned int) _1;
return _3;
Other formulations are going to be more expensive from a gimple standpoint. So
for now let's assume this is what we'll be dealing with from gimple.
In RTL we have:
(insn 7 3 8 2 (set (reg:SI 140)
(const_int 16776960 [0xffff00])) "j.c":9:39 272 {*mvconst_internal}
(nil))
(insn 8 7 9 2 (set (reg:SI 139 [ _5 ])
(and:SI (reg:SI 145 [ val ])
(reg:SI 140))) "j.c":9:39 103 {*andsi3}
(expr_list:REG_DEAD (reg:SI 145 [ val ])
(expr_list:REG_DEAD (reg:SI 140)
(nil))))
(insn 9 8 10 2 (set (reg:SI 144)
(leu:SI (reg:SI 139 [ _5 ])
(const_int 255 [0xff]))) "j.c":9:39 434 {*sleu_sisi}
(expr_list:REG_DEAD (reg:SI 139 [ _5 ])
(nil)))
(note 10 9 15 2 NOTE_INSN_DELETED)
(insn 15 10 16 2 (set (reg/i:SI 10 a0)
(xor:SI (reg:SI 144)
(const_int 1 [0x1]))) "j.c":10:1 106 {*xorsi3}
(expr_list:REG_DEAD (reg:SI 144)
(nil)))
I think the best rv32gcb formulation I see is to shift right by 8 bits, zero
extend and sCC, so 3 insns. We don't support 4->3 splits. Nothing looks good
as a bridge pattern and I'm not keen to introduce a define_insn_and_split. So
I don't really see a path forward right now.