On Wed, 2017-09-13 at 22:39 +0000, Wilco Dijkstra wrote: > Steve Ellcey wrote: > > > And in aarch64 rtl expansion I see: > > > > (insn 10 9 11 (set (reg:QI 81) > > (mem:QI (reg/v/f:DI 80 [ string ]) [0 *string_9(D)+0 S1 > A8])) "pr77729.c":3 -1 > > (nil)) > > Yes using QI/HI mode anywhere in the RTL seems perverse and incorrect given > AArch64 > doesn't support registers narrower than 32 bits. Shift counts seem to have > the same > issue and expand into very complex sequences of ANDs with subreg - and nobody > seems > to understand what subreg really means... > > My feeling is that we should only use SI/DI mode in patterns and aggressively > widen all > 8/16-bit operations to SI mode (which is what C requires anyway). > > Wilco
I was wondering if I should widen to SImode or DImode? Here is a patch I am testing now that steals some code from the arm32 md file, I put it in the "mov<mode>" define_expand. I decided on DImode since that is the 'natural' size of the registers but using SImode works too for the pr77729 test case. Which mode do you think I should use? Steve Ellcey sell...@cavium.com diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index f8cdb06..41f9e8c 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -864,6 +864,12 @@ (match_operand:SHORT 1 "general_operand" ""))] "" " + if (can_create_pseudo_p () && MEM_P (operands[1]) && optimize > 0) + { + rtx reg = gen_reg_rtx (DImode); + emit_insn (gen_zero_extend<mode>di2 (reg, operands[1])); + operands[1] = gen_lowpart (<MODE>mode, reg); + } if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx) operands[1] = force_reg (<MODE>mode, operands[1]);