Save 2 insns for constants like 0x5555555555555555 where the low 32-bits can be replicated to the high 32-bits.
Cc: David Edelsohn <dje....@gmail.com> --- * config/rs6000/rs6000.c (genimm_ppc::exam_search): Check for two equal 32-bit pieces. (genimm_ppc::generate): Handle VEC_DUPLICATE. --- gcc/config/rs6000/rs6000.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6af5cf3..59c5014 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -8173,6 +8173,13 @@ genimm_ppc::exam_search (HOST_WIDE_INT c, int budget) if (exam_mask (-1, c, sub_budget)) return true; + /* If the two halves are equal, use an insert. */ + if (c >> 32 == test && exam_sub (test, sub_budget)) + { + opN (VEC_DUPLICATE, 0xffffffffu); /* RLDIMI */ + return true; + } + /* Shift the constant left. */ test = HOST_WIDE_INT_UC (0xffffffff00000000); if ((c & test) == c && exam_sub (c >> 32, sub_budget)) @@ -8230,6 +8237,14 @@ genimm_ppc::generate (rtx dest, machine_mode mode) const case ASHIFT: x = gen_rtx_fmt_ee (r, mode, op1, op2); break; + case VEC_DUPLICATE: + /* Abusing the rtx code to indicate RLDIMI. + This should match *rotl<mode>3_insert_3. */ + x = GEN_INT (exact_log2 (op[i] + 1)); + x = gen_rtx_IOR (mode, + gen_rtx_AND (mode, op1, op2), + gen_rtx_ASHIFT (mode, op1, x)); + break; default: gcc_unreachable (); } -- 2.4.3