https://gcc.gnu.org/g:2e1c12409662c20f45b0e4dabaadff033ef674f7

commit r16-4060-g2e1c12409662c20f45b0e4dabaadff033ef674f7
Author: Richard Earnshaw <rearn...@arm.com>
Date:   Fri Sep 5 15:25:55 2025 +0100

    arm: mve: fix out-of range literal pool for a const_vector [PR121810]
    
    For the pattern mve_mov<mode>, the alternative that describes literal
    pool support is incorrect.  This leads to compiler getting the
    calculations wrong for the available distance to the next pool
    fragment because the selected alternative is a shorter sequence than
    the correct one.  In particular the sequence generated for a 128-bit
    constant is
    
            vldr.64  d0, Pool    // Insn length 4, alternative 7 (part 1)
            vldr.64  d1, Pool+8  // Insn length 4, alternative 7 (part 2)
    
    Note that the second instruction needs 4 bytes more range than the
    first because the PC has advanced by 4 bytes, but the next slot in the
    pool has advanced by 8.
    
    The fix is to move the 'Ui' constraint to the correct alternative
    and to move the pool-range attributes to that alternative as well.
    
    I've fixed a couple of other nits in this code at the same time:
    - the thumb2_neg_pool_range attribute was misnamed (as neg_pool_range),
    meaning it was ignored in Thumb state, which is the only time this
    pattern is available.
    - the load range was not a multiple of 4, which makes no sense for
    an insn sequence that is a multiple of 4 bytes long.  I've rounded the
    value down out of caution, but it may well have been OK with 1020 as
    the forward range.
    
    I'm not adding a testcase for this patch; the code to reproduce is
    simply too complex to reliably test for a regression.
    
    gcc/ChangeLog:
            PR target/121810
            * config/arm/mve.md (mve_mov<mode>): Move the Ui constraint
            and pool_range attributes to the final alternative.  Fix
            the forward range value and correctly name the negative
            range.

Diff:
---
 gcc/config/arm/mve.md | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 8527bd753e30..96faa05908f0 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -18,8 +18,8 @@
 ;; <http://www.gnu.org/licenses/>.
 
 (define_insn "mve_mov<mode>"
-  [(set (match_operand:MVE_types 0 "nonimmediate_operand" "=w,w,r,w   , w,   
r,Ux,w")
-       (match_operand:MVE_types 1 "general_operand"      " 
w,r,w,DnDm,UxUi,r,w, Ul"))]
+  [(set (match_operand:MVE_types 0 "nonimmediate_operand" "=w,w,r,w   ,w, 
r,Ux,w")
+       (match_operand:MVE_types 1 "general_operand"      " w,r,w,DnDm,Ux,r,w, 
UlUi"))]
   "TARGET_HAVE_MVE || TARGET_HAVE_MVE_FLOAT"
 {
   switch (which_alternative)
@@ -56,7 +56,7 @@
          }
       }
 
-    case 4:  /* [w,UxUi].  */
+    case 4:  /* [w,Ux].  */
       if (<MODE>mode == V2DFmode || <MODE>mode == V2DImode
          || <MODE>mode == TImode)
        return "vldrw.u32\t%q0, %E1";
@@ -73,7 +73,7 @@
       else
        return "vstr<V_sz_elem1>.<V_sz_elem>\t%q1, %E0";
 
-    case 7:  /* [w,Ul].  */
+    case 7:  /* [w,UlUi].  */
        return output_move_neon (operands);
 
     default:
@@ -91,8 +91,8 @@
                                                   (symbol_ref 
"CODE_FOR_nothing")])
    (set_attr "type" 
"mve_move,mve_move,mve_move,mve_move,mve_load,multiple,mve_store,mve_load")
    (set_attr "length" "4,8,8,4,4,8,4,8")
-   (set_attr "thumb2_pool_range" "*,*,*,*,1018,*,*,*")
-   (set_attr "neg_pool_range" "*,*,*,*,996,*,*,*")])
+   (set_attr "thumb2_pool_range" "*,*,*,*,*,*,*,1016")
+   (set_attr "thumb2_neg_pool_range" "*,*,*,*,*,*,*,996")])
 
 ;;
 ;; [vdupq_n_u, vdupq_n_s, vdupq_n_f]

Reply via email to