Hi gcc-patches mailing list,
Richard Earnshaw via Sourceware Forge 
<[email protected]> has requested that the 
following forgejo pull request
be published on the mailing list.

Created on: 2026-07-30 15:40:01+00:00
Latest update: 2026-07-31 16:04:30+00:00
Changes: 6 changed files, 135 additions, 49 deletions
Head revision: rearnsha/gcc ref vdupq commit 
ce89660a99eedb891437c537b4f98f2b95aed94e
Base revision: gcc/gcc ref trunk commit 
b90df55625eb40b05e0628097765d0a2cb368ced r17-2853-gb90df55625eb40
Merge base: b90df55625eb40b05e0628097765d0a2cb368ced
Full diff url: https://forge.sourceware.org/gcc/gcc/pulls/208.diff
Discussion:  https://forge.sourceware.org/gcc/gcc/pulls/208
Requested Reviewers: azoff

Changes since v1:
- address comments from Christophe and Torbjorn
- Handle core regs to HF and BF vector modes
- Disambiguate the pattern names


Changed files:
- M: gcc/config/arm/neon.md
- M: gcc/config/arm/vfp.md
- M: gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c
- M: gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c
- M: gcc/testsuite/gcc.target/arm/crypto-vsha1mq_u32.c
- M: gcc/testsuite/gcc.target/arm/crypto-vsha1pq_u32.c


Richard Earnshaw (2):
  arm: handle neon vec_dup from select of 128-bit vector
  arm: Thumb2 reg preferencing for vfp variant of movsi [PR124043]

 gcc/config/arm/neon.md                        | 164 ++++++++++++++----
 gcc/config/arm/vfp.md                         |   8 +-
 .../gcc.target/arm/crypto-vsha1cq_u32.c       |   3 +-
 .../gcc.target/arm/crypto-vsha1h_u32.c        |   3 +-
 .../gcc.target/arm/crypto-vsha1mq_u32.c       |   3 +-
 .../gcc.target/arm/crypto-vsha1pq_u32.c       |   3 +-
 6 files changed, 135 insertions(+), 49 deletions(-)

Range-diff against v1:
1:  abeec128d7b6 ! 1:  117d454d98cc arm: handle neon vec_dup from select of 
128-bit vector
    @@ Commit message
         some cases we can use the core reg directly (when no shift is needed)
         since the upper bits are ignored.
     
    +    I've also disambiguated the two paterns named
    +    neon_vdup_lane<mode>_internal by inserting the iterator name into the
    +    pattern.  This doesn't change anything in terms of generated code, but
    +    makes the pattern names in the MD file unique.
    +
         gcc/ChangeLog:
     
    -            * config/arm/neon.md (neon_vdup_lane<mode>_internal): Handle
    -            core registers as the input vector operand by splitting.
    -            (neon_vdupq_lane<mode>_internal): New pattern
    +            * config/arm/neon.md (neon_vdup_lane<VDQW:mode>_internal):
    +            Handle core registers as the input vector operand by splitting.
    +            (neon_vdup_lane<VHFBF:mode>_internal): Likewise.
    +            (neon_vdupq_lane<VQ2BF:mode>_internal): New pattern.
     
         gcc/testsuite/ChangeLog:
     
    @@ gcc/config/arm/neon.md: if (BYTES_BIG_ENDIAN)
     -          (vec_select:<V_elem>
     -            (match_operand:<V_double_vector_mode> 1 "s_register_operand" 
"w")
     -            (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
    -+(define_insn_and_split "neon_vdup_lane<mode>_internal"
    ++(define_insn_and_split "neon_vdup_lane<VDQW:mode>_internal"
     +  [(set (match_operand:VDQW 0 "s_register_operand" "=w,w")
     +  (vec_duplicate:VDQW
     +    (vec_select:<V_elem>
    @@ gcc/config/arm/neon.md: if (BYTES_BIG_ENDIAN)
     +  }
     +  [(set_attr "length" "4,8")
     +   (set_attr "type" "neon_dup<q>")]
    -+)
    -+
    + )
    + 
    +-(define_insn "neon_vdup_lane<mode>_internal"
    +- [(set (match_operand:VHFBF 0 "s_register_operand" "=w")
    +-   (vec_duplicate:VHFBF
    +-    (vec_select:<V_elem>
    +-     (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
    +-     (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
    +- "TARGET_NEON && (TARGET_FP16 || TARGET_BF16_SIMD)"
    +-{
    +-  if (BYTES_BIG_ENDIAN)
    +-    {
    +-      int elt = INTVAL (operands[2]);
     +; There isn't an intrinsic for this, but the compiler can generate it
     +; idomatically from other operations.
    -+(define_insn_and_split "neon_vdupq_lane<mode>_internal"
    ++(define_insn_and_split "neon_vdupq_lane<VQ2BF:mode>_internal"
     +  [(set (match_operand:VQ2BF 0 "s_register_operand" "=w,w")
     +  (vec_duplicate:VQ2BF
     +    (vec_select:<V_elem>
    @@ gcc/config/arm/neon.md: if (BYTES_BIG_ENDIAN)
     +   (clobber (match_scratch:<V_elem> 3 "=X,r"))]
     +  "TARGET_NEON"
     +  "#"
    -+  "" ;; && reload_completed"
    ++  ""
     +  [(parallel
     +    [(set (match_dup 0)
     +       (vec_duplicate:VQ2BF
    @@ gcc/config/arm/neon.md: if (BYTES_BIG_ENDIAN)
     +  }
     +  [(set_attr "type" "neon_dup<q>")
     +   (set_attr "length" "4,8")]
    ++)
    ++
    ++(define_insn_and_split "neon_vdup_lane<VHFBF:mode>_internal"
    ++  [(set (match_operand:VHFBF 0 "s_register_operand" "=w,w")
    ++    (vec_duplicate:VHFBF
    ++     (vec_select:<V_elem>
    ++      (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w,r")
    ++      (parallel [(match_operand:SI 2 "immediate_operand" "i,i")]))))
    ++   (clobber (match_scratch:<V_elem> 3 "=X,r"))]
    ++  "TARGET_NEON && (TARGET_FP16 || TARGET_BF16_SIMD)"
    ++  {
    ++    if (BYTES_BIG_ENDIAN)
    ++      {
    ++  int elt = INTVAL (operands[2]);
    ++  elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
    ++  operands[2] = GEN_INT (elt);
    ++      }
    ++    if (<Is_d_reg>)
    ++      return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
    ++    else
    ++      return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
    ++  }
    ++  "&& REGNO (operands[1]) <= LAST_ARM_REGNUM"
    ++  [(set (match_dup 0)
    ++  (vec_duplicate:VHFBF (match_dup 3)))]
    ++  {
    ++    unsigned HOST_WIDE_INT elt = UINTVAL (operands[2]);
    ++    if (BYTES_BIG_ENDIAN)
    +       elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
    +-      operands[2] = GEN_INT (elt);
    +-    }
    +-  if (<Is_d_reg>)
    +-    return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
    +-  else
    +-    return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
    +-}
    +-  [(set_attr "type" "neon_dup<q>")]
    ++    unsigned HOST_WIDE_INT size = GET_MODE_SIZE (<V_elem>mode);
    ++    int base_regno = REGNO (operands[1]);
    ++    int regno = (base_regno
    ++           + subreg_regno_offset (base_regno, <V_double_vector_mode>mode,
    ++                                  elt * size, SImode));
    ++    unsigned HOST_WIDE_INT offset = (elt * size) % GET_MODE_SIZE (SImode);
    ++    if (offset != 0)
    ++      {
    ++  gcc_assert (offset < 4);
    ++  rtx reg = gen_rtx_REG (SImode, regno);
    ++  rtx shift = gen_rtx_LSHIFTRT (SImode, reg,
    ++                                GEN_INT (offset * BITS_PER_UNIT));
    ++  emit_move_insn (gen_rtx_SUBREG (SImode, operands[3], 0),
    ++                  shift);
    ++      }
    ++    else
    ++      operands[3] = gen_rtx_REG (<V_elem>mode, regno);
    ++  }
    ++  [(set_attr "length" "4,8")
    ++   (set_attr "type" "neon_dup<q>")]
      )
      
    - (define_insn "neon_vdup_lane<mode>_internal"
    + (define_expand "neon_vdup_lane<mode>"
     
      ## gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c ##
     @@ gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c: 
TEST_SHA1C_VEC_SELECT (GET_LANE)
    @@ gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c: TEST_SHA1C_VEC_SELECT 
(GET_LA
      /* { dg-final { scan-assembler-times {sha1c.32\tq[0-9]+, q[0-9]+} 5 } } */
      /* { dg-final { scan-assembler-times {vdup.32\tq[0-9]+, 
(?:r[0-9]+|d[0-9]+\[[0-9]+\])} 4 { xfail { arm_thumb2 && arm_hf_eabi } } } } */
     -/* { dg-final { scan-assembler-times {vmov.32\tr[0-9]+, 
d[0-9]+\[[0-9]+\]} 3 } } */
    -+
     
      ## gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c ##
     @@ gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c: TEST_SHA1H_VEC_SELECT 
(GET_LANE)
2:  3b9cc3468af3 ! 2:  ce89660a99ee arm: Thumb2 reg preferencing for vfp 
variant of movsi [PR124043]
    @@ gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c: uint32_t foo (void)
      
      /* { dg-final { scan-assembler-times {sha1c.32\tq[0-9]+, q[0-9]+} 5 } } */
     -/* { dg-final { scan-assembler-times {vdup.32\tq[0-9]+, 
(?:r[0-9]+|d[0-9]+\[[0-9]+\])} 4 { xfail { arm_thumb2 && arm_hf_eabi } } } } */
    --
     +/* { dg-final { scan-assembler-times {vdup.32\tq[0-9]+, 
(?:r[0-9]+|d[0-9]+\[[0-9]+\])} 4 } } */
     
      ## gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c ##
-- 
2.54.0

Reply via email to