2016-10-24 13:33 GMT+03:00 Georg-Johann Lay <a...@gjlay.de>:
> This fixes issues with casesi that originate from taking hard coded
> subreg:HI of the SImode switch value:
>
> * The subreg is cutting away the upper bytes which is wrong code if the
> switch actually operates on a value > 16 bits.
>
> * The hard-coded subreg will ICE on DImode because of nested subregs.
>
> The fix is simple: Just avoid subreg in casesi expander.
>
> What's not so simple is to generate code that performs as efficiently as
> with the old solution for switch values <= 16 bits.
>
> The performance issue is cured by a new pass that scans the insn stream,
> recognizes extension + casesi insns and then rectifies the situation by
> using the non-extended switch value.  This code is straight forward but
> somewhat tedious to write down...
>
> A much superior solution would be to add one more operand to casesi and pass
> down, say (zero_extend:SI (reg:QI 42)), to the casesi expander so that be
> back-end could take advantage of this information.  Again, going across all
> targets is beyond what I can do for GCC, even if it would be much less code
> compared to the current solution...
>
> The performance fix assumes that the extension appears right before the
> casesi sequence which is due to how the middle-end prepares casesi operands.
>
> No regressions with ATmega128 and ATmega2560.
>
> Ok for trunk?


Approved.
Please apply.

>
> Johann
>
>
> gcc/
>         PR target/71676
>         PR target/71678
>         * config/avr/avr.md (casesi): Rewrite avoiding subregs of SI.
>         (casesi_<mode>_sequence): New insn.
>         (*cmp<mode>) [qi,qq,uqq,hi,hq,uhq,ha,uha]: Rename to cmp<mode>3.
>         * config/avr/predicates.md (extend_operator): New.
>         * config/avr/avr-passes.def (avr_pass_casesi): Register new pass.
>         * config/avr/avr-protos.h (avr_casei_sequence_check_operands)
>         (make_avr_pass_casesi): New prototypes.
>         * config/avr/avr.c (print-rtl.h): Include it.
>         (pass_data avr_pass_data_casesi): Data for new pass.
>         (avr_pass_casesi): New class implementing rtl_opt_pass .avr-casesi.
>         (make_avr_pass_casesi, avr_parallel_insn_from_insns)
>         (avr_is_casesi_sequence, avr_casei_sequence_check_operands)
>         (avr_optimize_casesi): New functions.
>
> gcc/testsuite/
>         PR target/71676
>         PR target/71678
>         * gcc.target/avr/pr71676-1.c: New test.
>         * gcc.target/avr/pr71676-2.c: New test.
>         * gcc.target/avr/pr71676-3.c: New test.
>         * gcc.target/avr/pr71676.c: New test.
>         * gcc.target/avr/pr71678.c: New test.
>
>

Reply via email to