[simplify-rtx] Simplify vec_merge of vec_duplicates into vec_concat
commit9bffba28176797a1f3513c6545816c9a6b73fba5
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Nov 2017 18:29:38 +0000 (8 18:29 +0000)
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Nov 2017 18:29:38 +0000 (8 18:29 +0000)
tree01ecc67421aa14ffdb9721f699664279b29b4320
parent2c29869d8e66c0a84dcccf51954ece4522eafdd3
[simplify-rtx] Simplify vec_merge of vec_duplicates into vec_concat

Another vec_merge simplification that's missing from simplify-rtx.c is transforming
a vec_merge of two vec_duplicates. For example:
(set (reg:V2DF 80)
    (vec_merge:V2DF (vec_duplicate:V2DF (reg:DF 84))
        (vec_duplicate:V2DF (reg:DF 81))
        (const_int 2)))

Can be transformed into the simpler:
(set (reg:V2DF 80)
    (vec_concat:V2DF (reg:DF 81)
                (reg:DF 84)))

I believe this should always be beneficial.
I'm still looking into finding a small testcase demonstrating this, but on aarch64 SPEC
I've seen this eliminate some really bizzare codegen where GCC was generating nonsense like:
  ldr q18, [sp, 448]
  ins v18.d[0], v23.d[0]
  ins v18.d[1], v22.d[0]

With q18 being pushed and popped off the stack in the prologue and epilogue of the function!
These are large files from SPEC that I haven't been able to analyse yet as to why GCC even attempts
to do that, but with this patch it doesn't try to load a register and overwrite all its lanes.
This patch shaves off about 5k of code size from zeusmp on aarch64 at -O3, so I believe it's a good
thing to do.

* simplify-rtx.c (simplify_ternary_operation): Simplify vec_merge
of two vec_duplicates into a vec_concat.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254550 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/ChangeLog
gcc/simplify-rtx.c