On 10/30/19 1:53 PM, Mikael Tillenius wrote: > The AVR example was interesting since it generates reasonable code. > > After a few experiments I strongly believe that it is the call to > __mulhi3 that stops GCC from doing CSE on the pointer expressions. If I > add a fake mulhi3 insn CSE seems to do its work and just generates the > address calculation once. But of course the code will not work since the > instruction is not present in the hardware. I see at least three > possible solutions: > > 1) Teach CSE to work even for calls to __mulhi3 THe name shouldn't matter at all to CSE. What's important to CSE is interpreting the REG_EQUAL note in this case and finding the bounds of the insn chain that computes the value in the REG_EQUAL note. > > 2) Add an insn that generates the H8S mulxu.w (16x16 => 32) instruction > in this case. "int" is 16-bit and the size of the struct is also small > in this case. Note that GCC should know how to generate mulxu.w for the H8/300H and above variants. Just quickly looking at the MD file I see: > (define_expand "umulhisi3" > [(set (match_operand:SI 0 "register_operand" "") > (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "")) > ;; intentionally-mismatched modes > (match_operand:HI 2 "reg_or_nibble_operand" "")))] > "TARGET_H8300H || TARGET_H8300S" > { > if (GET_MODE (operands[2]) != VOIDmode) > operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]); > }) Note the HImode on operand 2. That seems wrong. Hopefully it wasn't something *I* did eons ago. Anyway, that might be a place to start looking. I wouldn't be surprised if all the work we've done in the last decade to tighten up our checking of predicates is somehow causing us to not use umulhisi3 in this context. Jeff