diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7136f6bbb9a..9d21ce38b03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-04-09 Matthew Malcomson + + PR target/90024 + * config/arm/arm.c (neon_valid_immediate): Disallow VOIDmode parameter. + * config/arm/constraints.md (Dm, DN, Dn): Split previous Dn constraint + into three. + * config/arm/neon.md (*neon_mov): Account for TImode and DImode + differences directly. + (*smax3_neon, vashl3, vashr3_imm): Use Dm constraint. + 2019-04-09 Jakub Jelinek PR translation/90011 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 7ce063f43d2..12ccb7d6901 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -11998,8 +11998,7 @@ neon_valid_immediate (rtx op, machine_mode mode, int inverse, else { n_elts = 1; - if (mode == VOIDmode) - mode = DImode; + gcc_assert (mode != VOIDmode); } innersize = GET_MODE_UNIT_SIZE (mode); diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index 57ec0639622..d4a4c5967ae 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -31,8 +31,8 @@ ;; 'H' was previously used for FPA. ;; The following multi-letter normal constraints have been used: -;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, Dl, DL, Do, Dv, Dy, Di, Dt, Dp, -;; Dz, Tu +;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, DN, Dm, Dl, DL, Do, Dv, Dy, Di, +;; Dt, Dp, Dz, Tu ;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe ;; in Thumb-2 state: Ha, Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py, Pz ;; in all states: Pf @@ -298,14 +298,28 @@ (and (match_code "const_double,const_int") (match_test "TARGET_32BIT && arm_const_double_by_immediates (op)"))) -(define_constraint "Dn" +(define_constraint "Dm" "@internal - In ARM/Thumb-2 state a const_vector or const_int which can be loaded with a - Neon vmov immediate instruction." - (and (match_code "const_vector,const_int") + In ARM/Thumb-2 state a const_vector which can be loaded with a Neon vmov + immediate instruction." + (and (match_code "const_vector") (match_test "TARGET_32BIT && imm_for_neon_mov_operand (op, GET_MODE (op))"))) +(define_constraint "Dn" + "@internal + In ARM/Thumb-2 state a DImode const_int which can be loaded with a Neon vmov + immediate instruction." + (and (match_code "const_int") + (match_test "TARGET_32BIT && imm_for_neon_mov_operand (op, DImode)"))) + +(define_constraint "DN" + "@internal + In ARM/Thumb-2 state a TImode const_int which can be loaded with a Neon vmov + immediate instruction." + (and (match_code "const_int") + (match_test "TARGET_32BIT && imm_for_neon_mov_operand (op, TImode)"))) + (define_constraint "Dl" "@internal In ARM/Thumb-2 state a const_vector which can be used with a Neon vorr or diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 48556d9dd5f..726b7281a11 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -25,14 +25,14 @@ (define_insn "*neon_mov" [(set (match_operand:VDX 0 "nonimmediate_operand" - "=w,Un,w, w, ?r,?w,?r, ?Us,*r") + "=w,Un,w, w, w, ?r,?w,?r, ?Us,*r") (match_operand:VDX 1 "general_operand" - " w,w, Dn,Uni, w, r, Usi,r,*r"))] + " w,w, Dm,Dn,Uni, w, r, Usi,r,*r"))] "TARGET_NEON && (register_operand (operands[0], mode) || register_operand (operands[1], mode))" { - if (which_alternative == 2) + if (which_alternative == 2 || which_alternative == 3) { int width, is_valid; static char templ[40]; @@ -53,32 +53,33 @@ switch (which_alternative) { case 0: return "vmov\t%P0, %P1 @ "; - case 1: case 3: return output_move_neon (operands); - case 2: gcc_unreachable (); - case 4: return "vmov\t%Q0, %R0, %P1 @ "; - case 5: return "vmov\t%P0, %Q1, %R1 @ "; - case 8: return "#"; + case 1: case 4: return output_move_neon (operands); + case 2: case 3: gcc_unreachable (); + case 5: return "vmov\t%Q0, %R0, %P1 @ "; + case 6: return "vmov\t%P0, %Q1, %R1 @ "; + case 9: return "#"; default: return output_move_double (operands, true, NULL); } } [(set_attr "type" "neon_move,neon_store1_1reg,neon_move,\ - neon_load1_1reg, neon_to_gp,neon_from_gp,\ - neon_load1_2reg, neon_store1_2reg, multiple") - (set_attr "length" "4,4,4,4,4,4,8,8,8") - (set_attr "arm_pool_range" "*,*,*,1020,*,*,1020,*,*") - (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,1018,*,*") - (set_attr "neg_pool_range" "*,*,*,1004,*,*,1004,*,*")]) + neon_move,neon_load1_1reg, neon_to_gp,\ + neon_from_gp,neon_load1_2reg, neon_store1_2reg,\ + multiple") + (set_attr "length" "4,4,4,4,4,4,4,8,8,8") + (set_attr "arm_pool_range" "*,*,*,*,1020,*,*,1020,*,*") + (set_attr "thumb2_pool_range" "*,*,*,*,1018,*,*,1018,*,*") + (set_attr "neg_pool_range" "*,*,*,*,1004,*,*,1004,*,*")]) (define_insn "*neon_mov" [(set (match_operand:VQXMOV 0 "nonimmediate_operand" - "=w,Un,w, w, ?r,?w,?r,?r, ?Us") + "=w,Un,w, w, w, ?r,?w,?r,?r, ?Us") (match_operand:VQXMOV 1 "general_operand" - " w,w, Dn,Uni, w, r, r, Usi, r"))] + " w,w, Dm,DN,Uni, w, r, r, Usi, r"))] "TARGET_NEON && (register_operand (operands[0], mode) || register_operand (operands[1], mode))" { - if (which_alternative == 2) + if (which_alternative == 2 || which_alternative == 3) { int width, is_valid; static char templ[40]; @@ -99,20 +100,20 @@ switch (which_alternative) { case 0: return "vmov\t%q0, %q1 @ "; - case 1: case 3: return output_move_neon (operands); - case 2: gcc_unreachable (); - case 4: return "vmov\t%Q0, %R0, %e1 @ \;vmov\t%J0, %K0, %f1"; - case 5: return "vmov\t%e0, %Q1, %R1 @ \;vmov\t%f0, %J1, %K1"; + case 1: case 4: return output_move_neon (operands); + case 2: case 3: gcc_unreachable (); + case 5: return "vmov\t%Q0, %R0, %e1 @ \;vmov\t%J0, %K0, %f1"; + case 6: return "vmov\t%e0, %Q1, %R1 @ \;vmov\t%f0, %J1, %K1"; default: return output_move_quad (operands); } } [(set_attr "type" "neon_move_q,neon_store2_2reg_q,neon_move_q,\ - neon_load2_2reg_q,neon_to_gp_q,neon_from_gp_q,\ - mov_reg,neon_load1_4reg,neon_store1_4reg") - (set_attr "length" "4,8,4,8,8,8,16,8,16") - (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*") - (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*") - (set_attr "neg_pool_range" "*,*,*,996,*,*,*,996,*")]) + neon_move_q,neon_load2_2reg_q,neon_to_gp_q,\ + neon_from_gp_q,mov_reg,neon_load1_4reg,neon_store1_4reg") + (set_attr "length" "4,8,4,4,8,8,8,16,8,16") + (set_attr "arm_pool_range" "*,*,*,*,1020,*,*,*,1020,*") + (set_attr "thumb2_pool_range" "*,*,*,*,1018,*,*,*,1018,*") + (set_attr "neg_pool_range" "*,*,*,*,996,*,*,*,996,*")]) /* We define these mov expanders to match the standard mov$a optab to prevent the mid-end from trying to do a subreg for these modes which is the most @@ -1066,7 +1067,7 @@ (define_insn "vashl3" [(set (match_operand:VDQIW 0 "s_register_operand" "=w,w") (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w,w") - (match_operand:VDQIW 2 "imm_lshift_or_reg_neon" "w,Dn")))] + (match_operand:VDQIW 2 "imm_lshift_or_reg_neon" "w,Dm")))] "TARGET_NEON" { switch (which_alternative) @@ -1085,7 +1086,7 @@ (define_insn "vashr3_imm" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))] + (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dm")))] "TARGET_NEON" { return neon_output_shift_immediate ("vshr", 's', &operands[2], @@ -1098,7 +1099,7 @@ (define_insn "vlshr3_imm" [(set (match_operand:VDQIW 0 "s_register_operand" "=w") (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w") - (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))] + (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dm")))] "TARGET_NEON" { return neon_output_shift_immediate ("vshr", 'u', &operands[2], diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 29d1a81c8d8..71eaabc4997 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-09 Matthew Malcomson + + PR target/90024 + * gcc.dg/torture/neon-immediate-timode.c: New test. + 2019-04-09 Jakub Jelinek PR tree-optimization/89998 diff --git a/gcc/testsuite/gcc.dg/torture/neon-immediate-timode.c b/gcc/testsuite/gcc.dg/torture/neon-immediate-timode.c new file mode 100644 index 00000000000..35f7d2cd32c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/neon-immediate-timode.c @@ -0,0 +1,10 @@ +union a { + char b; + long long c; +}; +union a d; +int g(int, union a, union a); +void e() { + union a f[2] = {-1L}; + g(0, d, f[0]); +}