diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2022-06-17 10:30:57 +0100 |
---|---|---|
committer | Richard Earnshaw <rearnsha@arm.com> | 2022-06-17 10:33:15 +0100 |
commit | 94018fd2675190a4353cb199da4957538f070886 (patch) | |
tree | 372eceff777e3b38d9d8f480b4c164d0ff941a53 /gcc/config | |
parent | bc7e9f76756f2f164bb5dc70b59bc0d838f9fa96 (diff) | |
download | gcc-94018fd2675190a4353cb199da4957538f070886.zip gcc-94018fd2675190a4353cb199da4957538f070886.tar.gz gcc-94018fd2675190a4353cb199da4957538f070886.tar.bz2 |
arm: mve: Don't force trivial vector literals to the pool
A bug in the ordering of the operands in the mve_mov<mode> pattern
meant that all literal values were being pushed to the literal pool.
This patch fixes that and simplifies some of the logic slightly so
that we can use as simple switch statement.
For example:
void f (uint32_t *a)
{
int i;
for (i = 0; i < 100; i++)
a[i] += 1;
}
Now compiles to:
push {lr}
mov lr, #25
vmov.i32 q2, #0x1 @ v4si
...
instead of
push {lr}
mov lr, #25
vldr.64 d4, .L6
vldr.64 d5, .L6+8
...
.L7:
.align 3
.L6:
.word 1
.word 1
.word 1
.word 1
gcc/ChangeLog:
* config/arm/mve.md (*mve_mov<mode>): Re-order constraints
to avoid spilling trivial literals to the constant pool.
gcc/testsuite/ChangeLog:
* gcc.target/arm/acle/cde-mve-full-assembly.c: Adjust expected
output.
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/arm/mve.md | 99 |
1 files changed, 53 insertions, 46 deletions
diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index f16991c..c4dec01 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -18,66 +18,73 @@ ;; <http://www.gnu.org/licenses/>. (define_insn "*mve_mov<mode>" - [(set (match_operand:MVE_types 0 "nonimmediate_operand" "=w,w,r,w,w,r,w,Ux,w") - (match_operand:MVE_types 1 "general_operand" "w,r,w,Dn,UxUi,r,Dm,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,UxUi,r,w, Ul"))] "TARGET_HAVE_MVE || TARGET_HAVE_MVE_FLOAT" { - if (which_alternative == 3 || which_alternative == 6) + switch (which_alternative) { - int width, is_valid; - static char templ[40]; + case 0: /* [w,w]. */ + return "vmov\t%q0, %q1"; - is_valid = simd_immediate_valid_for_move (operands[1], <MODE>mode, - &operands[1], &width); + case 1: /* [w,r]. */ + return "vmov\t%e0, %Q1, %R1 %@ <mode>\;vmov\t%f0, %J1, %K1"; + + case 2: /* [r,w]. */ + return "vmov\t%Q0, %R0, %e1 %@ <mode>\;vmov\t%J0, %K0, %f1"; + + case 3: /* [w,DnDm]. */ + { + int width, is_valid; + + is_valid = simd_immediate_valid_for_move (operands[1], <MODE>mode, + &operands[1], &width); + + gcc_assert (is_valid); + + if (width == 0) + return "vmov.f32\t%q0, %1 %@ <mode>"; + else + { + const int templ_size = 40; + static char templ[templ_size]; + if (snprintf (templ, templ_size, + "vmov.i%d\t%%q0, %%x1 %%@ <mode>", width) + > templ_size) + abort (); + return templ; + } + } + + case 4: /* [w,UxUi]. */ + if (<MODE>mode == V2DFmode || <MODE>mode == V2DImode + || <MODE>mode == TImode) + return "vldrw.u32\t%q0, %E1"; + else + return "vldr<V_sz_elem1>.<V_sz_elem>\t%q0, %E1"; - gcc_assert (is_valid != 0); + case 5: /* [r,r]. */ + return output_move_quad (operands); - if (width == 0) - return "vmov.f32\t%q0, %1 @ <mode>"; + case 6: /* [Ux,w]. */ + if (<MODE>mode == V2DFmode || <MODE>mode == V2DImode + || <MODE>mode == TImode) + return "vstrw.32\t%q1, %E0"; else - sprintf (templ, "vmov.i%d\t%%q0, %%x1 @ <mode>", width); - return templ; - } + return "vstr<V_sz_elem1>.<V_sz_elem>\t%q1, %E0"; - if (which_alternative == 4 || which_alternative == 7) - { - if (<MODE>mode == V2DFmode || <MODE>mode == V2DImode || <MODE>mode == TImode) - { - if (which_alternative == 7) - output_asm_insn ("vstrw.32\t%q1, %E0", operands); - else - output_asm_insn ("vldrw.u32\t%q0, %E1",operands); - } - else - { - if (which_alternative == 7) - output_asm_insn ("vstr<V_sz_elem1>.<V_sz_elem>\t%q1, %E0", operands); - else - output_asm_insn ("vldr<V_sz_elem1>.<V_sz_elem>\t%q0, %E1", operands); - } - return ""; - } - switch (which_alternative) - { - case 0: - return "vmov\t%q0, %q1"; - case 1: - return "vmov\t%e0, %Q1, %R1 @ <mode>\;vmov\t%f0, %J1, %K1"; - case 2: - return "vmov\t%Q0, %R0, %e1 @ <mode>\;vmov\t%J0, %K0, %f1"; - case 5: - return output_move_quad (operands); - case 8: + case 7: /* [w,Ul]. */ return output_move_neon (operands); + default: gcc_unreachable (); return ""; } } - [(set_attr "type" "mve_move,mve_move,mve_move,mve_move,mve_load,multiple,mve_move,mve_store,mve_load") - (set_attr "length" "4,8,8,4,8,8,4,4,4") - (set_attr "thumb2_pool_range" "*,*,*,*,1018,*,*,*,*") - (set_attr "neg_pool_range" "*,*,*,*,996,*,*,*,*")]) + [(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,*,*,*")]) (define_insn "*mve_vdup<mode>" [(set (match_operand:MVE_vecs 0 "s_register_operand" "=w") |