From f8f8909af1b5dab515adae5b93b51f3c731b9929 Mon Sep 17 00:00:00 2001 From: Aaron Sawdey Date: Tue, 17 Nov 2020 11:38:20 -0500 Subject: [PATCH] Make MMA builtins use opaque modes This patch changes powerpc MMA builtins to use the new opaque mode class and use modes OO (32 bytes) and XO (64 bytes) instead of POI/PXI. Using the opaque modes prevents optimization from trying to do anything with vector pair/quad, which was the problem we were seeing with the partial integer modes. gcc/ * config/rs6000/mma.md (unspec): Add assemble/extract UNSPECs. (movoi): Change to movoo. (*movpoi): Change to *movoo. (movxi): Change to movxo. (*movpxi): Change to *movxo. (mma_assemble_pair): Change to OO mode. (*mma_assemble_pair): New define_insn_and_split. (mma_disassemble_pair): New define_expand. (*mma_disassemble_pair): New define_insn_and_split. (mma_assemble_acc): Change to XO mode. (*mma_assemble_acc): Change to XO mode. (mma_disassemble_acc): New define_expand. (*mma_disassemble_acc): New define_insn_and_split. (mma_): Change to XO mode. (mma_): Change to XO mode. (mma_): Change to XO mode. (mma_): Change to OO mode. (mma_): Change to XO/OO mode. (mma_): Change to XO mode. (mma_): Change to XO mode. (mma_): Change to XO mode. (mma_): Change to XO mode. (mma_): Change to XO mode. (mma_): Change to XO mode. (mma_): Change to XO/OO mode. (mma_): Change to XO/OO mode. (mma_): Change to XO mode. (mma_): Change to XO mode. * config/rs6000/predicates.md (input_operand): Allow opaque. (mma_disassemble_output_operand): New predicate. * config/rs6000/rs6000-builtin.def: Changes to disassemble builtins. * config/rs6000/rs6000-call.c (rs6000_return_in_memory): Disallow __vector_pair/__vector_quad as return types. (rs6000_promote_function_mode): Remove function return type check because we can't test it here any more. (rs6000_function_arg): Do not allow __vector_pair/__vector_quad as as function arguments. (rs6000_gimple_fold_mma_builtin): Handle mma_disassemble_* builtins. (rs6000_init_builtins): Create types for XO/OO modes. * config/rs6000/rs6000-modes.def: DElete OI, XI, POI, and PXI modes, and create XO and OO modes. * config/rs6000/rs6000-string.c (expand_block_move): Update to OO mode. * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok_uncached): Update for XO/OO modes. (rs6000_rtx_costs): Make UNSPEC_MMA_XXSETACCZ cost 0. (rs6000_modes_tieable_p): Update for XO/OO modes. (rs6000_debug_reg_global): Update for XO/OO modes. (rs6000_setup_reg_addr_masks): Update for XO/OO modes. (rs6000_init_hard_regno_mode_ok): Update for XO/OO modes. (reg_offset_addressing_ok_p): Update for XO/OO modes. (rs6000_emit_move): Update for XO/OO modes. (rs6000_preferred_reload_class): Update for XO/OO modes. (rs6000_split_multireg_move): Update for XO/OO modes. (rs6000_mangle_type): Update for opaque types. (rs6000_invalid_conversion): Update for XO/OO modes. * config/rs6000/rs6000.h (VECTOR_ALIGNMENT_P): Update for XO/OO modes. * config/rs6000/rs6000.md (RELOAD): Update for XO/OO modes. gcc/testsuite/ * gcc.target/powerpc/mma-double-test.c (main): Call abort for failure. * gcc.target/powerpc/mma-single-test.c (main): Call abort for failure. * gcc.target/powerpc/pr96506.c: Rename to pr96506-1.c. * gcc.target/powerpc/pr96506-2.c: New test. --- gcc/config/rs6000/mma.md | 421 ++++++++++-------- gcc/config/rs6000/predicates.md | 12 + gcc/config/rs6000/rs6000-builtin.def | 14 +- gcc/config/rs6000/rs6000-call.c | 160 +++---- gcc/config/rs6000/rs6000-modes.def | 10 +- gcc/config/rs6000/rs6000-string.c | 6 +- gcc/config/rs6000/rs6000.c | 193 ++++---- gcc/config/rs6000/rs6000.h | 3 +- gcc/config/rs6000/rs6000.md | 2 +- .../gcc.target/powerpc/mma-double-test.c | 3 + .../gcc.target/powerpc/mma-single-test.c | 3 + .../powerpc/{pr96506.c => pr96506-1.c} | 24 - gcc/testsuite/gcc.target/powerpc/pr96506-2.c | 38 ++ 13 files changed, 517 insertions(+), 372 deletions(-) rename gcc/testsuite/gcc.target/powerpc/{pr96506.c => pr96506-1.c} (61%) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr96506-2.c diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index a3fd28bdd0a..4d291c42f7a 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -19,24 +19,18 @@ ;; along with GCC; see the file COPYING3. If not see ;; . -;; The MMA patterns use the multi-register PXImode and POImode partial -;; integer modes to implement the target specific __vector_quad and -;; __vector_pair types that the MMA built-in functions reference. -;; To use these modes, we must define XImode and OImode move patterns -;; so the independent parts of the compiler can use our large partial -;; integer modes. However, if we enable the XImode and OImode move -;; patterns, then the compiler will attempt to use them and this can -;; cause byte swapping issues on litte-endian systems. We don't need -;; the XImode and OImode move patterns for actual code generation, -;; therefore, we define the XImode and OImode move patterns, but we -;; disable their use with a "false" condition flag. +;; The MMA patterns use the multi-register XOmode and OOmode opaque +;; modes to implement the target specific __vector_quad and +;; __vector_pair types that the MMA built-in functions reference. We +;; use OPAQUE_MODE to prevent anything from trying to open them up. (define_constants [(MAX_MMA_OPERANDS 7)]) ;; Constants for creating unspecs (define_c_enum "unspec" - [UNSPEC_MMA_ASSEMBLE_ACC + [UNSPEC_MMA_ASSEMBLE + UNSPEC_MMA_EXTRACT UNSPEC_MMA_PMXVBF16GER2 UNSPEC_MMA_PMXVBF16GER2NN UNSPEC_MMA_PMXVBF16GER2NP @@ -97,6 +91,7 @@ UNSPEC_MMA_XVI8GER4SPP UNSPEC_MMA_XXMFACC UNSPEC_MMA_XXMTACC + UNSPEC_MMA_XXSETACCZ ]) ;; MMA instructions with 1 accumulator argument @@ -265,31 +260,22 @@ (UNSPEC_MMA_PMXVI8GER4SPP "pmxvi8ger4spp")]) -;; Define a disabled OImode move pattern, so we can use POImode. -(define_expand "movoi" - [(set (match_operand:OI 0 "nonimmediate_operand") - (match_operand:OI 1 "input_operand"))] - "0" -{ - gcc_unreachable (); -}) - -;; Vector pair support. POImode can only live in VSRs. -(define_expand "movpoi" - [(set (match_operand:POI 0 "nonimmediate_operand") - (match_operand:POI 1 "input_operand"))] +;; Vector pair support. OOmode can only live in VSRs. +(define_expand "movoo" + [(set (match_operand:OO 0 "nonimmediate_operand") + (match_operand:OO 1 "input_operand"))] "TARGET_MMA" { - rs6000_emit_move (operands[0], operands[1], POImode); + rs6000_emit_move (operands[0], operands[1], OOmode); DONE; }) -(define_insn_and_split "*movpoi" - [(set (match_operand:POI 0 "nonimmediate_operand" "=wa,m,wa") - (match_operand:POI 1 "input_operand" "m,wa,wa"))] +(define_insn_and_split "*movoo" + [(set (match_operand:OO 0 "nonimmediate_operand" "=wa,m,wa") + (match_operand:OO 1 "input_operand" "m,wa,wa"))] "TARGET_MMA - && (gpc_reg_operand (operands[0], POImode) - || gpc_reg_operand (operands[1], POImode))" + && (gpc_reg_operand (operands[0], OOmode) + || gpc_reg_operand (operands[1], OOmode))" "@ lxvp%X1 %x0,%1 stxvp%X0 %x1,%0 @@ -305,287 +291,370 @@ (set_attr "length" "*,*,8")]) -;; Define a disabled XImode move pattern, so we can use PXImode. -(define_expand "movxi" - [(set (match_operand:XI 0 "nonimmediate_operand") - (match_operand:XI 1 "input_operand"))] - "0" -{ - gcc_unreachable (); -}) - -;; Vector quad support. PXImode can only live in FPRs. -(define_expand "movpxi" - [(set (match_operand:PXI 0 "nonimmediate_operand") - (match_operand:PXI 1 "input_operand"))] +;; Vector quad support. XOmode can only live in FPRs. +(define_expand "movxo" + [(set (match_operand:XO 0 "nonimmediate_operand") + (match_operand:XO 1 "input_operand"))] "TARGET_MMA" { - rs6000_emit_move (operands[0], operands[1], PXImode); + rs6000_emit_move (operands[0], operands[1], XOmode); DONE; }) -(define_insn_and_split "*movpxi" - [(set (match_operand:PXI 0 "nonimmediate_operand" "=d,m,d,d") - (match_operand:PXI 1 "input_operand" "m,d,d,O"))] +(define_insn_and_split "*movxo" + [(set (match_operand:XO 0 "nonimmediate_operand" "=d,m,d") + (match_operand:XO 1 "input_operand" "m,d,d"))] "TARGET_MMA - && (gpc_reg_operand (operands[0], PXImode) - || gpc_reg_operand (operands[1], PXImode))" + && (gpc_reg_operand (operands[0], XOmode) + || gpc_reg_operand (operands[1], XOmode))" "@ # # - # - xxsetaccz %A0" - "&& reload_completed - && !(fpr_reg_operand (operands[0], PXImode) && operands[1] == const0_rtx)" + #" + "&& reload_completed" [(const_int 0)] { rs6000_split_multireg_move (operands[0], operands[1]); DONE; } - [(set_attr "type" "vecload,vecstore,veclogical,mma") - (set_attr "length" "8,8,16,*") - (set_attr "max_prefixed_insns" "2,2,*,*")]) + [(set_attr "type" "vecload,vecstore,veclogical") + (set_attr "length" "8,8,16") + (set_attr "max_prefixed_insns" "2,2,*")]) (define_expand "mma_assemble_pair" - [(match_operand:POI 0 "vsx_register_operand") - (match_operand:V16QI 1 "input_operand") - (match_operand:V16QI 2 "input_operand")] + [(match_operand:OO 0 "vsx_register_operand") + (match_operand:V16QI 1 "mma_assemble_input_operand") + (match_operand:V16QI 2 "mma_assemble_input_operand")] "TARGET_MMA" { - rtx dst; + rtx src = gen_rtx_UNSPEC (OOmode, + gen_rtvec (2, operands[1], operands[2]), + UNSPEC_MMA_ASSEMBLE); + emit_move_insn (operands[0], src); + DONE; +}) - /* Let the compiler know the code below fully defines our output value. */ - emit_clobber (operands[0]); +(define_insn_and_split "*mma_assemble_pair" + [(set (match_operand:OO 0 "vsx_register_operand" "=wa") + (unspec:OO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa") + (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")] + UNSPEC_MMA_ASSEMBLE))] + "TARGET_MMA" + "#" + "&& reload_completed" + [(const_int 0)] +{ + rtx src = gen_rtx_UNSPEC (OOmode, + gen_rtvec (2, operands[1], operands[2]), + UNSPEC_MMA_ASSEMBLE); + rs6000_split_multireg_move (operands[0], src); + DONE; +}) + +(define_expand "mma_disassemble_pair" + [(match_operand:V16QI 0 "mma_disassemble_output_operand") + (match_operand:OO 1 "vsx_register_operand") + (match_operand 2 "const_0_to_1_operand")] + "TARGET_MMA" +{ + rtx src; + int regoff = INTVAL (operands[2]); + src = gen_rtx_UNSPEC (V16QImode, + gen_rtvec (2, operands[1], GEN_INT (regoff)), + UNSPEC_MMA_EXTRACT); + emit_move_insn (operands[0], src); + DONE; +}) - dst = simplify_gen_subreg (V16QImode, operands[0], POImode, 0); - emit_move_insn (dst, operands[1]); - dst = simplify_gen_subreg (V16QImode, operands[0], POImode, 16); - emit_move_insn (dst, operands[2]); +(define_insn_and_split "*mma_disassemble_pair" + [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa") + (unspec:V16QI [(match_operand:OO 1 "vsx_register_operand" "wa") + (match_operand 2 "const_0_to_1_operand")] + UNSPEC_MMA_EXTRACT))] + "TARGET_MMA + && vsx_register_operand (operands[1], OOmode)" + "#" + "&& reload_completed" + [(const_int 0)] +{ + int reg = REGNO (operands[1]); + int regoff = INTVAL (operands[2]); + rtx src = gen_rtx_REG (V16QImode, reg + regoff); + emit_move_insn (operands[0], src); DONE; }) (define_expand "mma_assemble_acc" - [(match_operand:PXI 0 "fpr_reg_operand") - (match_operand:V16QI 1 "input_operand") - (match_operand:V16QI 2 "input_operand") - (match_operand:V16QI 3 "input_operand") - (match_operand:V16QI 4 "input_operand")] + [(match_operand:XO 0 "fpr_reg_operand") + (match_operand:V16QI 1 "mma_assemble_input_operand") + (match_operand:V16QI 2 "mma_assemble_input_operand") + (match_operand:V16QI 3 "mma_assemble_input_operand") + (match_operand:V16QI 4 "mma_assemble_input_operand")] "TARGET_MMA" { - rtx src = gen_rtx_UNSPEC (PXImode, + rtx src = gen_rtx_UNSPEC (XOmode, gen_rtvec (4, operands[1], operands[2], operands[3], operands[4]), - UNSPEC_MMA_ASSEMBLE_ACC); + UNSPEC_MMA_ASSEMBLE); emit_move_insn (operands[0], src); DONE; }) (define_insn_and_split "*mma_assemble_acc" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=d") - (unspec:PXI [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa") - (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa") - (match_operand:V16QI 3 "mma_assemble_input_operand" "mwa") - (match_operand:V16QI 4 "mma_assemble_input_operand" "mwa")] - UNSPEC_MMA_ASSEMBLE_ACC))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=d") + (unspec:XO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa") + (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa") + (match_operand:V16QI 3 "mma_assemble_input_operand" "mwa") + (match_operand:V16QI 4 "mma_assemble_input_operand" "mwa")] + UNSPEC_MMA_ASSEMBLE))] "TARGET_MMA - && fpr_reg_operand (operands[0], PXImode)" + && fpr_reg_operand (operands[0], XOmode)" "#" "&& reload_completed" [(const_int 0)] { - rtx src = gen_rtx_UNSPEC (PXImode, + rtx src = gen_rtx_UNSPEC (XOmode, gen_rtvec (4, operands[1], operands[2], operands[3], operands[4]), - UNSPEC_MMA_ASSEMBLE_ACC); + UNSPEC_MMA_ASSEMBLE); rs6000_split_multireg_move (operands[0], src); DONE; }) +(define_expand "mma_disassemble_acc" + [(match_operand:V16QI 0 "mma_disassemble_output_operand") + (match_operand:XO 1 "fpr_reg_operand") + (match_operand 2 "const_0_to_3_operand")] + "TARGET_MMA" +{ + rtx src; + int regoff = INTVAL (operands[2]); + src = gen_rtx_UNSPEC (V16QImode, + gen_rtvec (2, operands[1], GEN_INT (regoff)), + UNSPEC_MMA_EXTRACT); + emit_move_insn (operands[0], src); + DONE; +}) + +(define_insn_and_split "*mma_disassemble_acc" + [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa") + (unspec:V16QI [(match_operand:XO 1 "fpr_reg_operand" "d") + (match_operand 2 "const_0_to_3_operand")] + UNSPEC_MMA_EXTRACT))] + "TARGET_MMA + && fpr_reg_operand (operands[1], XOmode)" + "#" + "&& reload_completed" + [(const_int 0)] +{ + int reg = REGNO (operands[1]); + int regoff = INTVAL (operands[2]); + rtx src = gen_rtx_REG (V16QImode, reg + regoff); + emit_move_insn (operands[0], src); + DONE; +}) + ;; MMA instructions that do not use their accumulators as an input, still ;; must not allow their vector operands to overlap the registers used by ;; the accumulator. We enforce this by marking the output as early clobber. (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0")] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")] MMA_ACC))] "TARGET_MMA" " %A0" [(set_attr "type" "mma")]) +;; We can't have integer constants in XOmode so we wrap this in an UNSPEC. + (define_expand "mma_xxsetaccz" - [(set (match_operand:PXI 0 "fpr_reg_operand") + [(set (match_operand:XO 0 "fpr_reg_operand") (const_int 0))] "TARGET_MMA" { - emit_insn (gen_movpxi (operands[0], const0_rtx)); + rtx xo0 = gen_rtx_UNSPEC (XOmode, gen_rtvec (1, const0_rtx), + UNSPEC_MMA_XXSETACCZ); + emit_insn (gen_rtx_SET (operands[0], xo0)); DONE; }) +(define_insn_and_split "*mma_xxsetaccz" + [(set (match_operand:XO 0 "fpr_reg_operand" "=d") + (unspec:XO [(match_operand 1 "const_0_to_1_operand" "O")] + UNSPEC_MMA_XXSETACCZ))] + "TARGET_MMA" + "xxsetaccz %A0" + "&& reload_completed" + [(set (match_dup 0) (unspec:XO [(match_dup 1)] UNSPEC_MMA_XXSETACCZ))] + "" + [(set_attr "type" "mma") + (set_attr "length" "4")]) + (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa") - (match_operand:V16QI 2 "vsx_register_operand" "wa")] - MMA_VV))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa") + (match_operand:V16QI 2 "vsx_register_operand" "wa")] + MMA_VV))] "TARGET_MMA" " %A0,%x1,%x2" [(set_attr "type" "mma")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:V16QI 3 "vsx_register_operand" "wa")] - MMA_AVV))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:V16QI 3 "vsx_register_operand" "wa")] + MMA_AVV))] "TARGET_MMA" " %A0,%x2,%x3" [(set_attr "type" "mma")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:POI 1 "vsx_register_operand" "wa") - (match_operand:V16QI 2 "vsx_register_operand" "wa")] - MMA_PV))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:OO 1 "vsx_register_operand" "wa") + (match_operand:V16QI 2 "vsx_register_operand" "wa")] + MMA_PV))] "TARGET_MMA" " %A0,%x1,%x2" [(set_attr "type" "mma")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0") - (match_operand:POI 2 "vsx_register_operand" "wa") - (match_operand:V16QI 3 "vsx_register_operand" "wa")] - MMA_APV))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0") + (match_operand:OO 2 "vsx_register_operand" "wa") + (match_operand:V16QI 3 "vsx_register_operand" "wa")] + MMA_APV))] "TARGET_MMA" " %A0,%x2,%x3" [(set_attr "type" "mma")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:SI 3 "const_0_to_15_operand" "n") - (match_operand:SI 4 "const_0_to_15_operand" "n") - (match_operand:SI 5 "u8bit_cint_operand" "n")] - MMA_VVI4I4I8))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:SI 3 "const_0_to_15_operand" "n") + (match_operand:SI 4 "const_0_to_15_operand" "n") + (match_operand:SI 5 "u8bit_cint_operand" "n")] + MMA_VVI4I4I8))] "TARGET_MMA" " %A0,%x1,%x2,%3,%4,%5" [(set_attr "type" "mma") (set_attr "length" "8")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:V16QI 3 "vsx_register_operand" "wa") - (match_operand:SI 4 "const_0_to_15_operand" "n") - (match_operand:SI 5 "const_0_to_15_operand" "n") - (match_operand:SI 6 "u8bit_cint_operand" "n")] - MMA_AVVI4I4I8))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:V16QI 3 "vsx_register_operand" "wa") + (match_operand:SI 4 "const_0_to_15_operand" "n") + (match_operand:SI 5 "const_0_to_15_operand" "n") + (match_operand:SI 6 "u8bit_cint_operand" "n")] + MMA_AVVI4I4I8))] "TARGET_MMA" " %A0,%x2,%x3,%4,%5,%6" [(set_attr "type" "mma") (set_attr "length" "8")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:SI 3 "const_0_to_15_operand" "n") - (match_operand:SI 4 "const_0_to_15_operand" "n") - (match_operand:SI 5 "const_0_to_3_operand" "n")] - MMA_VVI4I4I2))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:SI 3 "const_0_to_15_operand" "n") + (match_operand:SI 4 "const_0_to_15_operand" "n") + (match_operand:SI 5 "const_0_to_3_operand" "n")] + MMA_VVI4I4I2))] "TARGET_MMA" " %A0,%x1,%x2,%3,%4,%5" [(set_attr "type" "mma") (set_attr "length" "8")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:V16QI 3 "vsx_register_operand" "wa") - (match_operand:SI 4 "const_0_to_15_operand" "n") - (match_operand:SI 5 "const_0_to_15_operand" "n") - (match_operand:SI 6 "const_0_to_3_operand" "n")] - MMA_AVVI4I4I2))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:V16QI 3 "vsx_register_operand" "wa") + (match_operand:SI 4 "const_0_to_15_operand" "n") + (match_operand:SI 5 "const_0_to_15_operand" "n") + (match_operand:SI 6 "const_0_to_3_operand" "n")] + MMA_AVVI4I4I2))] "TARGET_MMA" " %A0,%x2,%x3,%4,%5,%6" [(set_attr "type" "mma") (set_attr "length" "8")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:SI 3 "const_0_to_15_operand" "n") - (match_operand:SI 4 "const_0_to_15_operand" "n")] - MMA_VVI4I4))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:SI 3 "const_0_to_15_operand" "n") + (match_operand:SI 4 "const_0_to_15_operand" "n")] + MMA_VVI4I4))] "TARGET_MMA" " %A0,%x1,%x2,%3,%4" [(set_attr "type" "mma") (set_attr "length" "8")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:V16QI 3 "vsx_register_operand" "wa") - (match_operand:SI 4 "const_0_to_15_operand" "n") - (match_operand:SI 5 "const_0_to_15_operand" "n")] - MMA_AVVI4I4))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:V16QI 3 "vsx_register_operand" "wa") + (match_operand:SI 4 "const_0_to_15_operand" "n") + (match_operand:SI 5 "const_0_to_15_operand" "n")] + MMA_AVVI4I4))] "TARGET_MMA" " %A0,%x2,%x3,%4,%5" [(set_attr "type" "mma") (set_attr "length" "8")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:POI 1 "vsx_register_operand" "wa") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:SI 3 "const_0_to_15_operand" "n") - (match_operand:SI 4 "const_0_to_3_operand" "n")] - MMA_PVI4I2))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:OO 1 "vsx_register_operand" "wa") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:SI 3 "const_0_to_15_operand" "n") + (match_operand:SI 4 "const_0_to_3_operand" "n")] + MMA_PVI4I2))] "TARGET_MMA" " %A0,%x1,%x2,%3,%4" [(set_attr "type" "mma") (set_attr "length" "8")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0") - (match_operand:POI 2 "vsx_register_operand" "wa") - (match_operand:V16QI 3 "vsx_register_operand" "wa") - (match_operand:SI 4 "const_0_to_15_operand" "n") - (match_operand:SI 5 "const_0_to_3_operand" "n")] - MMA_APVI4I2))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0") + (match_operand:OO 2 "vsx_register_operand" "wa") + (match_operand:V16QI 3 "vsx_register_operand" "wa") + (match_operand:SI 4 "const_0_to_15_operand" "n") + (match_operand:SI 5 "const_0_to_3_operand" "n")] + MMA_APVI4I2))] "TARGET_MMA" " %A0,%x2,%x3,%4,%5" [(set_attr "type" "mma") (set_attr "length" "8")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:V16QI 1 "vsx_register_operand" "wa") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:SI 3 "const_0_to_15_operand" "n") - (match_operand:SI 4 "const_0_to_15_operand" "n") - (match_operand:SI 5 "const_0_to_15_operand" "n")] - MMA_VVI4I4I4))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "wa") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:SI 3 "const_0_to_15_operand" "n") + (match_operand:SI 4 "const_0_to_15_operand" "n") + (match_operand:SI 5 "const_0_to_15_operand" "n")] + MMA_VVI4I4I4))] "TARGET_MMA" " %A0,%x1,%x2,%3,%4,%5" [(set_attr "type" "mma") (set_attr "length" "8")]) (define_insn "mma_" - [(set (match_operand:PXI 0 "fpr_reg_operand" "=&d") - (unspec:PXI [(match_operand:PXI 1 "fpr_reg_operand" "0") - (match_operand:V16QI 2 "vsx_register_operand" "wa") - (match_operand:V16QI 3 "vsx_register_operand" "wa") - (match_operand:SI 4 "const_0_to_15_operand" "n") - (match_operand:SI 5 "const_0_to_15_operand" "n") - (match_operand:SI 6 "const_0_to_15_operand" "n")] - MMA_AVVI4I4I4))] + [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:V16QI 3 "vsx_register_operand" "wa") + (match_operand:SI 4 "const_0_to_15_operand" "n") + (match_operand:SI 5 "const_0_to_15_operand" "n") + (match_operand:SI 6 "const_0_to_15_operand" "n")] + MMA_AVVI4I4I4))] "TARGET_MMA" " %A0,%x2,%x3,%4,%5,%6" [(set_attr "type" "mma") diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 4c2fe7fa312..9ad5ae67302 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1144,6 +1144,18 @@ (match_test "(mode == V16QImode && (vsx_register_operand (op, mode) || MEM_P (op)))")) +;; Return 1 if this operand is valid for an MMA disassemble insn. +(define_predicate "mma_disassemble_output_operand" + (match_code "reg,subreg,mem") +{ + if (SUBREG_P (op)) + op = SUBREG_REG (op); + if (!REG_P (op)) + return true; + + return vsx_register_operand (op, mode); +}) + ;; Return true if operand is an operator used in rotate-and-mask instructions. (define_predicate "rotate_mask_operator" (match_code "rotate,ashift,lshiftrt")) diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index a58102c3785..47b1f74e616 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -352,7 +352,7 @@ | RS6000_BTC_UNARY), \ CODE_FOR_ ## ICODE) /* ICODE */ -#define BU_MMA_V2(ENUM, NAME, ATTR, ICODE) \ +#define BU_MMA_2(ENUM, NAME, ATTR, ICODE) \ RS6000_BUILTIN_M (MMA_BUILTIN_ ## ENUM, /* ENUM */ \ "__builtin_mma_" NAME, /* NAME */ \ RS6000_BTM_MMA, /* MASK */ \ @@ -360,7 +360,13 @@ | RS6000_BTC_BINARY \ | RS6000_BTC_VOID \ | RS6000_BTC_GIMPLE), \ - CODE_FOR_nothing) /* ICODE */ + CODE_FOR_nothing) /* ICODE */ \ + RS6000_BUILTIN_M (MMA_BUILTIN_ ## ENUM ## _INTERNAL, /* ENUM */ \ + "__builtin_mma_" NAME "_internal", /* NAME */ \ + RS6000_BTM_MMA, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ #define BU_MMA_3(ENUM, NAME, ATTR, ICODE) \ RS6000_BUILTIN_M (MMA_BUILTIN_ ## ENUM, /* ENUM */ \ @@ -3108,8 +3114,8 @@ BU_MMA_1 (XXMFACC, "xxmfacc", QUAD, mma_xxmfacc) BU_MMA_1 (XXMTACC, "xxmtacc", QUAD, mma_xxmtacc) BU_MMA_1 (XXSETACCZ, "xxsetaccz", MISC, mma_xxsetaccz) -BU_MMA_V2 (DISASSEMBLE_ACC, "disassemble_acc", QUAD, nothing) -BU_MMA_V2 (DISASSEMBLE_PAIR,"disassemble_pair", PAIR, nothing) +BU_MMA_2 (DISASSEMBLE_ACC, "disassemble_acc", QUAD, mma_disassemble_acc) +BU_MMA_2 (DISASSEMBLE_PAIR,"disassemble_pair", PAIR, mma_disassemble_pair) BU_MMA_3 (ASSEMBLE_PAIR, "assemble_pair", MISC, mma_assemble_pair) BU_MMA_3 (XVBF16GER2, "xvbf16ger2", MISC, mma_xvbf16ger2) diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c index d619e231b09..1572671067a 100644 --- a/gcc/config/rs6000/rs6000-call.c +++ b/gcc/config/rs6000/rs6000-call.c @@ -6325,6 +6325,22 @@ rs6000_discover_homogeneous_aggregate (machine_mode mode, const_tree type, bool rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) { + /* We do not allow MMA types being used as return values. Only report + the invalid return value usage the first time we encounter it. */ + if (cfun + && !cfun->machine->mma_return_type_error + && TREE_TYPE (cfun->decl) == fntype + && (TYPE_MODE (type) == OOmode || TYPE_MODE (type) == XOmode)) + { + /* Record we have now handled function CFUN, so the next time we + are called, we do not re-report the same error. */ + cfun->machine->mma_return_type_error = true; + if (TYPE_CANONICAL (type) != NULL_TREE) + type = TYPE_CANONICAL (type); + error ("invalid use of MMA type %qs as a function return value", + IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); + } + /* For the Darwin64 ABI, test if we can fit the return value in regs. */ if (TARGET_MACHO && rs6000_darwin64_abi @@ -6577,30 +6593,8 @@ machine_mode rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, machine_mode mode, int *punsignedp ATTRIBUTE_UNUSED, - const_tree, int for_return) + const_tree, int for_return ATTRIBUTE_UNUSED) { - /* Warning: this is a static local variable and not always NULL! - This function is called multiple times for the same function - and return value. PREV_FUNC is used to keep track of the - first time we encounter a function's return value in order - to not report an error with that return value multiple times. */ - static struct function *prev_func = NULL; - - /* We do not allow MMA types being used as return values. Only report - the invalid return value usage the first time we encounter it. */ - if (for_return - && prev_func != cfun - && (mode == POImode || mode == PXImode)) - { - /* Record we have now handled function CFUN, so the next time we - are called, we do not re-report the same error. */ - prev_func = cfun; - if (TYPE_CANONICAL (type) != NULL_TREE) - type = TYPE_CANONICAL (type); - error ("invalid use of MMA type %qs as a function return value", - IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); - } - PROMOTE_MODE (mode, *punsignedp, type); return mode; @@ -7552,7 +7546,7 @@ rs6000_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) int n_elts; /* We do not allow MMA types being used as function arguments. */ - if (mode == POImode || mode == PXImode) + if (mode == OOmode || mode == XOmode) { if (TYPE_CANONICAL (type) != NULL_TREE) type = TYPE_CANONICAL (type); @@ -10073,7 +10067,8 @@ mma_expand_builtin (tree exp, rtx target, bool *expandedp) } unsigned attr_args = attr & RS6000_BTC_OPND_MASK; - if (attr & RS6000_BTC_QUAD) + if (attr & RS6000_BTC_QUAD + || fcode == MMA_BUILTIN_DISASSEMBLE_PAIR_INTERNAL) attr_args++; gcc_assert (nopnds == attr_args); @@ -11687,23 +11682,24 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi) gimple *new_call; tree new_decl; - if (rs6000_builtin_info[fncode + 1].icode == CODE_FOR_nothing) + if (fncode == MMA_BUILTIN_DISASSEMBLE_ACC + || fncode == MMA_BUILTIN_DISASSEMBLE_PAIR) { /* This is an MMA disassemble built-in function. */ - gcc_assert (fncode == MMA_BUILTIN_DISASSEMBLE_ACC - || fncode == MMA_BUILTIN_DISASSEMBLE_PAIR); - push_gimplify_context (true); + unsigned nvec = (fncode == MMA_BUILTIN_DISASSEMBLE_ACC) ? 4 : 2; tree dst_ptr = gimple_call_arg (stmt, 0); tree src_ptr = gimple_call_arg (stmt, 1); tree src_type = TREE_TYPE (src_ptr); tree src = make_ssa_name (TREE_TYPE (src_type)); gimplify_assign (src, build_simple_mem_ref (src_ptr), &new_seq); - /* If we are not disassembling an accumulator or our destination is - another accumulator, then just copy the entire thing as is. */ - if (fncode != MMA_BUILTIN_DISASSEMBLE_ACC - || TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_quad_type_node) + /* If we are not disassembling an accumulator/pair or our destination is + another accumulator/pair, then just copy the entire thing as is. */ + if ((fncode == MMA_BUILTIN_DISASSEMBLE_ACC + && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_quad_type_node) + || (fncode == MMA_BUILTIN_DISASSEMBLE_PAIR + && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_pair_type_node)) { tree dst = build_simple_mem_ref (build1 (VIEW_CONVERT_EXPR, src_type, dst_ptr)); @@ -11713,29 +11709,33 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi) return true; } - /* We're disassembling an accumulator into a different type, so we need + /* If we're disassembling an accumulator into a different type, we need to emit a xxmfacc instruction now, since we cannot do it later. */ - new_decl = rs6000_builtin_decls[MMA_BUILTIN_XXMFACC_INTERNAL]; - new_call = gimple_build_call (new_decl, 1, src); - src = make_ssa_name (vector_quad_type_node); - gimple_call_set_lhs (new_call, src); - gimple_seq_add_stmt (&new_seq, new_call); + if (fncode == MMA_BUILTIN_DISASSEMBLE_ACC) + { + new_decl = rs6000_builtin_decls[MMA_BUILTIN_XXMFACC_INTERNAL]; + new_call = gimple_build_call (new_decl, 1, src); + src = make_ssa_name (vector_quad_type_node); + gimple_call_set_lhs (new_call, src); + gimple_seq_add_stmt (&new_seq, new_call); + } - /* Copy the accumulator vector by vector. */ + /* Copy the accumulator/pair vector by vector. */ + new_decl = rs6000_builtin_decls[fncode + 1]; tree dst_type = build_pointer_type_for_mode (unsigned_V16QI_type_node, ptr_mode, true); tree dst_base = build1 (VIEW_CONVERT_EXPR, dst_type, dst_ptr); - tree array_type = build_array_type_nelts (unsigned_V16QI_type_node, 4); - tree src_array = build1 (VIEW_CONVERT_EXPR, array_type, src); - for (unsigned i = 0; i < 4; i++) + for (unsigned i = 0; i < nvec; i++) { - unsigned index = WORDS_BIG_ENDIAN ? i : 3 - i; - tree ref = build4 (ARRAY_REF, unsigned_V16QI_type_node, src_array, - build_int_cst (size_type_node, i), - NULL_TREE, NULL_TREE); + unsigned index = WORDS_BIG_ENDIAN ? i : nvec - 1 - i; tree dst = build2 (MEM_REF, unsigned_V16QI_type_node, dst_base, build_int_cst (dst_type, index * 16)); - gimplify_assign (dst, ref, &new_seq); + tree dstssa = make_ssa_name (unsigned_V16QI_type_node); + new_call = gimple_build_call (new_decl, 2, src, + build_int_cstu (uint16_type_node, i)); + gimple_call_set_lhs (new_call, dstssa); + gimple_seq_add_stmt (&new_seq, new_call); + gimplify_assign (dst, dstssa, &new_seq); } pop_gimplify_context (NULL); gsi_replace_with_seq (gsi, new_seq, true); @@ -13206,17 +13206,23 @@ rs6000_init_builtins (void) /* Vector pair and vector quad support. */ if (TARGET_EXTRA_BUILTINS) { - vector_pair_type_node = make_unsigned_type (256); + vector_pair_type_node = make_node (OPAQUE_TYPE); + SET_TYPE_MODE (vector_pair_type_node, OOmode); + TYPE_SIZE (vector_pair_type_node) = bitsize_int (GET_MODE_BITSIZE (OOmode)); + TYPE_PRECISION (vector_pair_type_node) = GET_MODE_BITSIZE (OOmode); + TYPE_SIZE_UNIT (vector_pair_type_node) = size_int (GET_MODE_SIZE (OOmode)); SET_TYPE_ALIGN (vector_pair_type_node, 256); - SET_TYPE_MODE (vector_pair_type_node, POImode); - layout_type (vector_pair_type_node); + TYPE_USER_ALIGN (vector_pair_type_node) = 0; lang_hooks.types.register_builtin_type (vector_pair_type_node, "__vector_pair"); - vector_quad_type_node = make_unsigned_type (512); + vector_quad_type_node = make_node (OPAQUE_TYPE); + SET_TYPE_MODE (vector_quad_type_node, XOmode); + TYPE_SIZE (vector_quad_type_node) = bitsize_int (GET_MODE_BITSIZE (XOmode)); + TYPE_PRECISION (vector_quad_type_node) = GET_MODE_BITSIZE (XOmode); + TYPE_SIZE_UNIT (vector_quad_type_node) = size_int (GET_MODE_SIZE (XOmode)); SET_TYPE_ALIGN (vector_quad_type_node, 512); - SET_TYPE_MODE (vector_quad_type_node, PXImode); - layout_type (vector_quad_type_node); + TYPE_USER_ALIGN (vector_quad_type_node) = 0; lang_hooks.types.register_builtin_type (vector_quad_type_node, "__vector_quad"); } @@ -13252,8 +13258,8 @@ rs6000_init_builtins (void) builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node; builtin_mode_to_type[V16QImode][0] = V16QI_type_node; builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node; - builtin_mode_to_type[POImode][1] = vector_pair_type_node; - builtin_mode_to_type[PXImode][1] = vector_quad_type_node; + builtin_mode_to_type[OOmode][1] = vector_pair_type_node; + builtin_mode_to_type[XOmode][1] = vector_quad_type_node; tdecl = add_builtin_type ("__bool char", bool_char_type_node); TYPE_NAME (bool_char_type_node) = tdecl; @@ -14065,21 +14071,21 @@ mma_init_builtins (void) } else { - if ((attr & RS6000_BTC_QUAD) == 0) + if (!(d->code == MMA_BUILTIN_DISASSEMBLE_ACC_INTERNAL + || d->code == MMA_BUILTIN_DISASSEMBLE_PAIR_INTERNAL) + && (attr & RS6000_BTC_QUAD) == 0) attr_args--; /* Ensure we have the correct number and type of operands. */ gcc_assert (attr_args == insn_data[icode].n_operands - 1); } - if (icode == CODE_FOR_nothing) + /* This is a disassemble pair/acc function. */ + if (d->code == MMA_BUILTIN_DISASSEMBLE_ACC + || d->code == MMA_BUILTIN_DISASSEMBLE_PAIR) { - /* This is a disassemble MMA built-in function. */ - gcc_assert (attr_args == RS6000_BTC_BINARY - && (d->code == MMA_BUILTIN_DISASSEMBLE_ACC - || d->code == MMA_BUILTIN_DISASSEMBLE_PAIR)); op[nopnds++] = build_pointer_type (void_type_node); - if (attr & RS6000_BTC_QUAD) + if (d->code == MMA_BUILTIN_DISASSEMBLE_ACC) op[nopnds++] = build_pointer_type (vector_quad_type_node); else op[nopnds++] = build_pointer_type (vector_pair_type_node); @@ -14087,13 +14093,17 @@ mma_init_builtins (void) else { /* This is a normal MMA built-in function. */ - unsigned j = (attr & RS6000_BTC_QUAD) ? 1 : 0; + unsigned j = 0; + if (attr & RS6000_BTC_QUAD + && d->code != MMA_BUILTIN_DISASSEMBLE_ACC_INTERNAL + && d->code != MMA_BUILTIN_DISASSEMBLE_PAIR_INTERNAL) + j = 1; for (; j < (unsigned) insn_data[icode].n_operands; j++) { machine_mode mode = insn_data[icode].operand[j].mode; - if (gimple_func && mode == PXImode) + if (gimple_func && mode == XOmode) op[nopnds++] = build_pointer_type (vector_quad_type_node); - else if (gimple_func && mode == POImode + else if (gimple_func && mode == OOmode && d->code == MMA_BUILTIN_ASSEMBLE_PAIR) op[nopnds++] = build_pointer_type (vector_pair_type_node); else @@ -14725,7 +14735,7 @@ rs6000_common_init_builtins (void) continue; } - if (icode == CODE_FOR_nothing) + if (icode == CODE_FOR_nothing) { if (TARGET_DEBUG_BUILTIN) fprintf (stderr, "rs6000_builtin, skip ternary %s (no code)\n", @@ -14791,7 +14801,7 @@ rs6000_common_init_builtins (void) continue; } - if (icode == CODE_FOR_nothing) + if (icode == CODE_FOR_nothing) { if (TARGET_DEBUG_BUILTIN) fprintf (stderr, "rs6000_builtin, skip binary %s (no code)\n", @@ -14800,9 +14810,9 @@ rs6000_common_init_builtins (void) continue; } - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; - mode2 = insn_data[icode].operand[2].mode; + mode0 = insn_data[icode].operand[0].mode; + mode1 = insn_data[icode].operand[1].mode; + mode2 = insn_data[icode].operand[2].mode; type = builtin_function_type (mode0, mode1, mode2, VOIDmode, d->code, d->name); @@ -14835,7 +14845,7 @@ rs6000_common_init_builtins (void) NULL_TREE); } else - { + { enum insn_code icode = d->icode; if (d->name == 0) { @@ -14846,7 +14856,7 @@ rs6000_common_init_builtins (void) continue; } - if (icode == CODE_FOR_nothing) + if (icode == CODE_FOR_nothing) { if (TARGET_DEBUG_BUILTIN) fprintf (stderr, "rs6000_builtin, skip unary %s (no code)\n", @@ -14855,8 +14865,8 @@ rs6000_common_init_builtins (void) continue; } - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; + mode0 = insn_data[icode].operand[0].mode; + mode1 = insn_data[icode].operand[1].mode; type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode, d->code, d->name); diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def index ddb218b3fba..e81a32c8c36 100644 --- a/gcc/config/rs6000/rs6000-modes.def +++ b/gcc/config/rs6000/rs6000-modes.def @@ -83,12 +83,6 @@ VECTOR_MODE (INT, SI, 2); /* V2SI */ combination. */ PARTIAL_INT_MODE (TI, 128, PTI); -/* Define, but don't use the larger integer modes. We need an integer mode - defined that is the same size as the vector pair and vector quad modes. */ - -INT_MODE (OI, 32); -INT_MODE (XI, 64); - /* Modes used by __vector_pair and __vector_quad. */ -PARTIAL_INT_MODE (OI, 256, POI); /* __vector_pair. */ -PARTIAL_INT_MODE (XI, 512, PXI); /* __vector_quad. */ +OPAQUE_MODE (OO, 32); +OPAQUE_MODE (XO, 64); diff --git a/gcc/config/rs6000/rs6000-string.c b/gcc/config/rs6000/rs6000-string.c index 82cc24ecdda..a2e6821d353 100644 --- a/gcc/config/rs6000/rs6000-string.c +++ b/gcc/config/rs6000/rs6000-string.c @@ -2787,7 +2787,7 @@ expand_block_move (rtx operands[], bool might_overlap) rtx src, dest; bool move_with_length = false; - /* Use POImode for paired vsx load/store. Use V2DI for single + /* Use OOmode for paired vsx load/store. Use V2DI for single unaligned vsx load/store, for consistency with what other expansions (compare) already do, and so we can use lxvd2x on p8. Order is VSX pair unaligned, VSX unaligned, Altivec, VSX @@ -2799,8 +2799,8 @@ expand_block_move (rtx operands[], bool might_overlap) && (align >= 256 || !STRICT_ALIGNMENT)) { move_bytes = 32; - mode = POImode; - gen_func.mov = gen_movpoi; + mode = OOmode; + gen_func.mov = gen_movoo; } else if (TARGET_POWERPC64 && TARGET_BLOCK_OPS_UNALIGNED_VSX && VECTOR_MEM_VSX_P (V2DImode) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d7dcd93f088..bd8205c87f7 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1826,15 +1826,12 @@ rs6000_hard_regno_mode_ok_uncached (int regno, machine_mode mode) mode = GET_MODE_INNER (mode); /* Vector pair modes need even/odd VSX register pairs. Only allow vector - registers. We need to allow OImode to have the same registers as POImode, - even though we do not enable the move pattern for OImode. */ - if (mode == POImode || mode == OImode) + registers. */ + if (mode == OOmode) return (TARGET_MMA && VSX_REGNO_P (regno) && (regno & 1) == 0); - /* MMA accumulator modes need FPR registers divisible by 4. We need to allow - XImode to have the same registers as PXImode, even though we do not enable - the move pattern for XImode. */ - if (mode == PXImode || mode == XImode) + /* MMA accumulator modes need FPR registers divisible by 4. */ + if (mode == XOmode) return (TARGET_MMA && FP_REGNO_P (regno) && (regno & 3) == 0); /* PTImode can only go in GPRs. Quad word memory operations require even/odd @@ -1941,8 +1938,8 @@ rs6000_hard_regno_mode_ok (unsigned int regno, machine_mode mode) GPR registers, and TImode can go in any GPR as well as VSX registers (PR 57744). - Similarly, don't allow POImode (vector pair, restricted to even VSX - registers) or PXImode (vector quad, restricted to FPR registers divisible + Similarly, don't allow OOmode (vector pair, restricted to even VSX + registers) or XOmode (vector quad, restricted to FPR registers divisible by 4) to tie with other modes. Altivec/VSX vector tests were moved ahead of scalar float mode, so that IEEE @@ -1951,8 +1948,8 @@ rs6000_hard_regno_mode_ok (unsigned int regno, machine_mode mode) static bool rs6000_modes_tieable_p (machine_mode mode1, machine_mode mode2) { - if (mode1 == PTImode || mode1 == POImode || mode1 == PXImode - || mode2 == PTImode || mode2 == POImode || mode2 == PXImode) + if (mode1 == PTImode || mode1 == OOmode || mode1 == XOmode + || mode2 == PTImode || mode2 == OOmode || mode2 == XOmode) return mode1 == mode2; if (ALTIVEC_OR_VSX_VECTOR_MODE (mode1)) @@ -2241,10 +2238,8 @@ rs6000_debug_reg_global (void) V2DFmode, V8SFmode, V4DFmode, - OImode, - XImode, - POImode, - PXImode, + OOmode, + XOmode, CCmode, CCUNSmode, CCEQmode, @@ -2706,13 +2701,13 @@ rs6000_setup_reg_addr_masks (void) since it will be broken into two vector moves. Vector quads can only do offset loads. */ else if ((addr_mask != 0) && TARGET_MMA - && (m2 == POImode || m2 == PXImode)) + && (m2 == OOmode || m2 == XOmode)) { addr_mask |= RELOAD_REG_OFFSET; if (rc == RELOAD_REG_FPR || rc == RELOAD_REG_VMX) { addr_mask |= RELOAD_REG_QUAD_OFFSET; - if (m2 == POImode) + if (m2 == OOmode) addr_mask |= RELOAD_REG_INDEXED; } } @@ -2921,13 +2916,13 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) /* Add support for vector pairs and vector quad registers. */ if (TARGET_MMA) { - rs6000_vector_unit[POImode] = VECTOR_NONE; - rs6000_vector_mem[POImode] = VECTOR_VSX; - rs6000_vector_align[POImode] = 256; + rs6000_vector_unit[OOmode] = VECTOR_NONE; + rs6000_vector_mem[OOmode] = VECTOR_VSX; + rs6000_vector_align[OOmode] = 256; - rs6000_vector_unit[PXImode] = VECTOR_NONE; - rs6000_vector_mem[PXImode] = VECTOR_VSX; - rs6000_vector_align[PXImode] = 512; + rs6000_vector_unit[XOmode] = VECTOR_NONE; + rs6000_vector_mem[XOmode] = VECTOR_VSX; + rs6000_vector_align[XOmode] = 512; } /* Register class constraints for the constraints that depend on compile @@ -3064,10 +3059,10 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) if (TARGET_MMA) { - reg_addr[POImode].reload_store = CODE_FOR_reload_poi_di_store; - reg_addr[POImode].reload_load = CODE_FOR_reload_poi_di_load; - reg_addr[PXImode].reload_store = CODE_FOR_reload_pxi_di_store; - reg_addr[PXImode].reload_load = CODE_FOR_reload_pxi_di_load; + reg_addr[OOmode].reload_store = CODE_FOR_reload_oo_di_store; + reg_addr[OOmode].reload_load = CODE_FOR_reload_oo_di_load; + reg_addr[XOmode].reload_store = CODE_FOR_reload_xo_di_store; + reg_addr[XOmode].reload_load = CODE_FOR_reload_xo_di_load; } } } @@ -8129,8 +8124,8 @@ reg_offset_addressing_ok_p (machine_mode mode) /* The vector pair/quad types support offset addressing if the underlying vectors support offset addressing. */ - case E_POImode: - case E_PXImode: + case E_OOmode: + case E_XOmode: return TARGET_MMA; case E_SDmode: @@ -10323,11 +10318,11 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode) operands[1] = force_const_mem (mode, operands[1]); break; - case E_POImode: - case E_PXImode: + case E_OOmode: + case E_XOmode: if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) != 0) error ("%qs is an opaque type, and you can't set it to other values.", - (mode == POImode) ? "__vector_pair" : "__vector_quad"); + (mode == OOmode) ? "__vector_pair" : "__vector_quad"); break; case E_SImode: @@ -12596,10 +12591,10 @@ rs6000_preferred_reload_class (rtx x, enum reg_class rclass) the GPR registers. */ if (rclass == GEN_OR_FLOAT_REGS) { - if (mode == POImode) + if (mode == OOmode) return VSX_REGS; - if (mode == PXImode) + if (mode == XOmode) return FLOAT_REGS; if (GET_MODE_CLASS (mode) == MODE_INT) @@ -16323,15 +16318,15 @@ rs6000_split_multireg_move (rtx dst, rtx src) /* If we have a vector quad register for MMA, and this is a load or store, see if we can use vector paired load/stores. */ - if (mode == PXImode && TARGET_MMA + if (mode == XOmode && TARGET_MMA && (MEM_P (dst) || MEM_P (src))) { - reg_mode = POImode; + reg_mode = OOmode; nregs /= 2; } /* If we have a vector pair/quad mode, split it into two/four separate vectors. */ - else if (mode == POImode || mode == PXImode) + else if (mode == OOmode || mode == XOmode) reg_mode = V1TImode; else if (FP_REGNO_P (reg)) reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : @@ -16377,12 +16372,16 @@ rs6000_split_multireg_move (rtx dst, rtx src) return; } - /* The __vector_pair and __vector_quad modes are multi-register modes, - so if have to load or store the registers, we have to be careful to - properly swap them if we're in little endian mode below. This means - the last register gets the first memory location. */ - if (mode == POImode || mode == PXImode) + /* The __vector_pair and __vector_quad modes are multi-register + modes, so if we have to load or store the registers, we have to be + careful to properly swap them if we're in little endian mode + below. This means the last register gets the first memory + location. We also need to be careful of using the right register + numbers if we are splitting XO to OO. */ + if (mode == OOmode || mode == XOmode) { + nregs = hard_regno_nregs (reg, mode); + int reg_mode_nregs = hard_regno_nregs (reg, reg_mode); if (MEM_P (dst)) { unsigned offset = 0; @@ -16391,15 +16390,15 @@ rs6000_split_multireg_move (rtx dst, rtx src) /* If we are reading an accumulator register, we have to deprime it before we can access it. */ if (TARGET_MMA - && GET_MODE (src) == PXImode && FP_REGNO_P (REGNO (src))) + && GET_MODE (src) == XOmode && FP_REGNO_P (REGNO (src))) emit_insn (gen_mma_xxmfacc (src, src)); - for (int i = 0; i < nregs; i++) + for (int i = 0; i < nregs; i += reg_mode_nregs) { - unsigned subreg = (WORDS_BIG_ENDIAN) - ? i * size : (nregs - 1 - i) * size; + unsigned subreg = + (WORDS_BIG_ENDIAN) ? i : (nregs - reg_mode_nregs - i); rtx dst2 = adjust_address (dst, reg_mode, offset); - rtx src2 = simplify_gen_subreg (reg_mode, src, mode, subreg); + rtx src2 = gen_rtx_REG (reg_mode, reg + subreg); offset += size; emit_insn (gen_rtx_SET (dst2, src2)); } @@ -16412,11 +16411,11 @@ rs6000_split_multireg_move (rtx dst, rtx src) unsigned offset = 0; unsigned size = GET_MODE_SIZE (reg_mode); - for (int i = 0; i < nregs; i++) + for (int i = 0; i < nregs; i += reg_mode_nregs) { - unsigned subreg = (WORDS_BIG_ENDIAN) - ? i * size : (nregs - 1 - i) * size; - rtx dst2 = simplify_gen_subreg (reg_mode, dst, mode, subreg); + unsigned subreg = + (WORDS_BIG_ENDIAN) ? i : (nregs - reg_mode_nregs - i); + rtx dst2 = gen_rtx_REG (reg_mode, reg + subreg); rtx src2 = adjust_address (src, reg_mode, offset); offset += size; emit_insn (gen_rtx_SET (dst2, src2)); @@ -16425,7 +16424,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) /* If we are writing an accumulator register, we have to prime it after we've written it. */ if (TARGET_MMA - && GET_MODE (dst) == PXImode && FP_REGNO_P (REGNO (dst))) + && GET_MODE (dst) == XOmode && FP_REGNO_P (REGNO (dst))) emit_insn (gen_mma_xxmtacc (dst, dst)); return; @@ -16433,9 +16432,12 @@ rs6000_split_multireg_move (rtx dst, rtx src) if (GET_CODE (src) == UNSPEC) { - gcc_assert (REG_P (dst) - && FP_REGNO_P (REGNO (dst)) - && XINT (src, 1) == UNSPEC_MMA_ASSEMBLE_ACC); + gcc_assert (XINT (src, 1) == UNSPEC_MMA_ASSEMBLE); + gcc_assert (REG_P (dst)); + if (GET_MODE (src) == XOmode) + gcc_assert (FP_REGNO_P (REGNO (dst))); + if (GET_MODE (src) == OOmode) + gcc_assert (VSX_REGNO_P (REGNO (dst))); reg_mode = GET_MODE (XVECEXP (src, 0, 0)); for (int i = 0; i < XVECLEN (src, 0); i++) @@ -16446,7 +16448,8 @@ rs6000_split_multireg_move (rtx dst, rtx src) /* We are writing an accumulator register, so we have to prime it after we've written it. */ - emit_insn (gen_mma_xxmtacc (dst, dst)); + if (GET_MODE (src) == XOmode) + emit_insn (gen_mma_xxmtacc (dst, dst)); return; } @@ -16459,22 +16462,35 @@ rs6000_split_multireg_move (rtx dst, rtx src) /* If we are reading an accumulator register, we have to deprime it before we can access it. */ if (TARGET_MMA - && GET_MODE (src) == PXImode && FP_REGNO_P (REGNO (src))) + && GET_MODE (src) == XOmode && FP_REGNO_P (REGNO (src))) emit_insn (gen_mma_xxmfacc (src, src)); /* Move register range backwards, if we might have destructive overlap. */ int i; - for (i = nregs - 1; i >= 0; i--) - emit_insn (gen_rtx_SET (simplify_gen_subreg (reg_mode, dst, mode, - i * reg_mode_size), - simplify_gen_subreg (reg_mode, src, mode, - i * reg_mode_size))); + /* XO/OO are opaque so cannot use subregs. */ + if (mode == OOmode || mode == XOmode ) + { + for (i = nregs - 1; i >= 0; i--) + { + rtx dst_i = gen_rtx_REG (reg_mode, REGNO (dst) + i); + rtx src_i = gen_rtx_REG (reg_mode, REGNO (src) + i); + emit_insn (gen_rtx_SET (dst_i, src_i)); + } + } + else + { + for (i = nregs - 1; i >= 0; i--) + emit_insn (gen_rtx_SET (simplify_gen_subreg (reg_mode, dst, mode, + i * reg_mode_size), + simplify_gen_subreg (reg_mode, src, mode, + i * reg_mode_size))); + } /* If we are writing an accumulator register, we have to prime it after we've written it. */ if (TARGET_MMA - && GET_MODE (dst) == PXImode && FP_REGNO_P (REGNO (dst))) + && GET_MODE (dst) == XOmode && FP_REGNO_P (REGNO (dst))) emit_insn (gen_mma_xxmtacc (dst, dst)); } else @@ -16611,7 +16627,7 @@ rs6000_split_multireg_move (rtx dst, rtx src) /* If we are reading an accumulator register, we have to deprime it before we can access it. */ if (TARGET_MMA && REG_P (src) - && GET_MODE (src) == PXImode && FP_REGNO_P (REGNO (src))) + && GET_MODE (src) == XOmode && FP_REGNO_P (REGNO (src))) emit_insn (gen_mma_xxmfacc (src, src)); for (i = 0; i < nregs; i++) @@ -16626,16 +16642,24 @@ rs6000_split_multireg_move (rtx dst, rtx src) if (j == 0 && used_update) continue; - emit_insn (gen_rtx_SET (simplify_gen_subreg (reg_mode, dst, mode, - j * reg_mode_size), - simplify_gen_subreg (reg_mode, src, mode, - j * reg_mode_size))); + /* XO/OO are opaque so cannot use subregs. */ + if (mode == OOmode || mode == XOmode ) + { + rtx dst_i = gen_rtx_REG (reg_mode, REGNO (dst) + j); + rtx src_i = gen_rtx_REG (reg_mode, REGNO (src) + j); + emit_insn (gen_rtx_SET (dst_i, src_i)); + } + else + emit_insn (gen_rtx_SET (simplify_gen_subreg (reg_mode, dst, mode, + j * reg_mode_size), + simplify_gen_subreg (reg_mode, src, mode, + j * reg_mode_size))); } /* If we are writing an accumulator register, we have to prime it after we've written it. */ if (TARGET_MMA && REG_P (dst) - && GET_MODE (dst) == PXImode && FP_REGNO_P (REGNO (dst))) + && GET_MODE (dst) == XOmode && FP_REGNO_P (REGNO (dst))) emit_insn (gen_mma_xxmtacc (dst, dst)); if (restore_basereg != NULL_RTX) @@ -19865,7 +19889,8 @@ rs6000_mangle_type (const_tree type) type = TYPE_MAIN_VARIANT (type); if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE - && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE) + && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE + && TREE_CODE (type) != OPAQUE_TYPE) return NULL; if (type == bool_char_type_node) return "U6__boolc"; @@ -21753,6 +21778,14 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, } break; + case UNSPEC: + if (XINT (x, 1) == UNSPEC_MMA_XXSETACCZ) + { + *total = 0; + return true; + } + break; + default: break; } @@ -27186,14 +27219,14 @@ rs6000_invalid_conversion (const_tree fromtype, const_tree totype) if (frommode != tomode) { - /* Do not allow conversions to/from PXImode and POImode types. */ - if (frommode == PXImode) + /* Do not allow conversions to/from XOmode and OOmode types. */ + if (frommode == XOmode) return N_("invalid conversion from type %<__vector_quad%>"); - if (tomode == PXImode) + if (tomode == XOmode) return N_("invalid conversion to type %<__vector_quad%>"); - if (frommode == POImode) + if (frommode == OOmode) return N_("invalid conversion from type %<__vector_pair%>"); - if (tomode == POImode) + if (tomode == OOmode) return N_("invalid conversion to type %<__vector_pair%>"); } else if (POINTER_TYPE_P (fromtype) && POINTER_TYPE_P (totype)) @@ -27202,19 +27235,19 @@ rs6000_invalid_conversion (const_tree fromtype, const_tree totype) frommode = TYPE_MODE (TREE_TYPE (fromtype)); tomode = TYPE_MODE (TREE_TYPE (totype)); - /* Do not allow conversions to/from PXImode and POImode pointer + /* Do not allow conversions to/from XOmode and OOmode pointer types, except to/from void pointers. */ if (frommode != tomode && frommode != VOIDmode && tomode != VOIDmode) { - if (frommode == PXImode) + if (frommode == XOmode) return N_("invalid conversion from type %<* __vector_quad%>"); - if (tomode == PXImode) + if (tomode == XOmode) return N_("invalid conversion to type %<* __vector_quad%>"); - if (frommode == POImode) + if (frommode == OOmode) return N_("invalid conversion from type %<* __vector_pair%>"); - if (tomode == POImode) + if (tomode == OOmode) return N_("invalid conversion to type %<* __vector_pair%>"); } } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 5a47aa14722..f35aaf4ffd1 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1041,7 +1041,7 @@ enum data_align { align_abi, align_opt, align_both }; /* Modes that are not vectors, but require vector alignment. Treat these like vectors in terms of loads and stores. */ #define VECTOR_ALIGNMENT_P(MODE) \ - (FLOAT128_VECTOR_P (MODE) || (MODE) == POImode || (MODE) == PXImode) + (FLOAT128_VECTOR_P (MODE) || (MODE) == OOmode || (MODE) == XOmode) #define ALTIVEC_VECTOR_MODE(MODE) \ ((MODE) == V16QImode \ @@ -2556,6 +2556,7 @@ typedef struct GTY(()) machine_function bool fpr_is_wrapped_separately[32]; bool lr_is_wrapped_separately; bool toc_is_wrapped_separately; + bool mma_return_type_error; } machine_function; #endif diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 7de31cab80b..0e799198a50 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -778,7 +778,7 @@ ;; supplement addressing modes. (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI SF SD SI DF DD DI TI PTI KF IF TF - POI PXI]) + OO XO]) ;; Iterate over smin, smax (define_code_iterator fp_minmax [smin smax]) diff --git a/gcc/testsuite/gcc.target/powerpc/mma-double-test.c b/gcc/testsuite/gcc.target/powerpc/mma-double-test.c index 53843794a95..254af7f8f79 100755 --- a/gcc/testsuite/gcc.target/powerpc/mma-double-test.c +++ b/gcc/testsuite/gcc.target/powerpc/mma-double-test.c @@ -181,6 +181,9 @@ main (int argc, char *argv[]) printf ("MMA double test fail: %d errors\n",ret); else printf ("MMA single test success: 0 MMA errors\n"); +#else + if (ret) + abort(); #endif return ret; diff --git a/gcc/testsuite/gcc.target/powerpc/mma-single-test.c b/gcc/testsuite/gcc.target/powerpc/mma-single-test.c index ac4125ba329..ebbc5ae2e1b 100755 --- a/gcc/testsuite/gcc.target/powerpc/mma-single-test.c +++ b/gcc/testsuite/gcc.target/powerpc/mma-single-test.c @@ -189,6 +189,9 @@ main (int argc, char *argv[]) printf ("MMA single test fail: %d errors\n",ret); else printf ("MMA single test success: 0 MMA errors\n"); +#else + if (ret) + abort(); #endif return ret; diff --git a/gcc/testsuite/gcc.target/powerpc/pr96506.c b/gcc/testsuite/gcc.target/powerpc/pr96506-1.c similarity index 61% rename from gcc/testsuite/gcc.target/powerpc/pr96506.c rename to gcc/testsuite/gcc.target/powerpc/pr96506-1.c index b1b40c5a5c8..91835cec30c 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr96506.c +++ b/gcc/testsuite/gcc.target/powerpc/pr96506-1.c @@ -40,27 +40,3 @@ foo3 (void) vquad_t v; bar3 (v); /* { dg-error "invalid use of MMA operand of type .__vector_quad. as a function parameter" } */ } - -__vector_pair -foo4 (__vector_pair *src) /* { dg-error "invalid use of MMA type .__vector_pair. as a function return value" } */ -{ - return *src; -} - -vpair_t -foo5 (vpair_t *src) /* { dg-error "invalid use of MMA type .__vector_pair. as a function return value" } */ -{ - return *src; -} - -__vector_quad -foo6 (__vector_quad *src) /* { dg-error "invalid use of MMA type .__vector_quad. as a function return value" } */ -{ - return *src; -} - -vquad_t -foo7 (vquad_t *src) /* { dg-error "invalid use of MMA type .__vector_quad. as a function return value" } */ -{ - return *src; -} diff --git a/gcc/testsuite/gcc.target/powerpc/pr96506-2.c b/gcc/testsuite/gcc.target/powerpc/pr96506-2.c new file mode 100644 index 00000000000..9cffd2576c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr96506-2.c @@ -0,0 +1,38 @@ +/* PR target/96506 */ +/* { dg-do compile } */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +extern void bar0(); +extern void bar1(); +extern void bar2(); +extern void bar3(); + +typedef __vector_pair vpair_t; +typedef __vector_quad vquad_t; + +/* Verify we flag errors on the following. */ + +__vector_pair +foo4 (__vector_pair *src) +{ /* { dg-error "invalid use of MMA type .__vector_pair. as a function return value" } */ + return *src; +} + +vpair_t +foo5 (vpair_t *src) +{ /* { dg-error "invalid use of MMA type .__vector_pair. as a function return value" } */ + return *src; +} + +__vector_quad +foo6 (__vector_quad *src) +{ /* { dg-error "invalid use of MMA type .__vector_quad. as a function return value" } */ + return *src; +} + +vquad_t +foo7 (vquad_t *src) +{ /* { dg-error "invalid use of MMA type .__vector_quad. as a function return value" } */ + return *src; +} -- 2.30.2