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.
---
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 8527bd753e3..96faa05908f 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 @@ (define_insn "mve_mov<mode>"
}
}
- 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 @@ (define_insn "mve_mov<mode>"
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 @@ (define_insn "mve_mov<mode>"
(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]
--
2.43.0