Thank you for feedback and discussion regarding my first draft of this patch with Segher Boessenkool and Bill Schmidt. This revision of the patch differs from the first in the following regards:
1. I have also removed the vector_altivec_load_<mode> and vectore_altivec_store_<mode> expansions from vector.md. 2. I have removed the unused rs6000_address_for_altivec function from rs6000.c. I have once again bootstrapped and regression tested on both little- endian and big-endian targets. The remainder of this description is borrowed from my initial submission of the patch. While working to assure rs6000 documentation of built-in functions is consistent with the implementation of built-in functions, I discovered some apparent typographic errors in the definitions of the ST_INTERNAL_4sf and ST_INTERNAL_2df built-in functions. As I endeavored to fix these definitions and write test cases to prove that I had properly fixed them, I discovered that these functions are no longer in use. This patch removes the unnecessary definitions and related back-end functions. This has bootstrapped and tested without regressions on both powerpc64le-unknown-linux (P8) and on powerpc-linux (P7 big-endian, with both -m32 and -m64 target options). Is this patch ok for trunk? gcc/ChangeLog: 2018-03-14 Kelvin Nilsen <kel...@gcc.gnu.org> * config/rs6000/rs6000-builtin.def: Remove various BU_ALTIVEC_X macro expansions for definition of ST_INTERNAL_<mode> and LD_INTERNAL_<mode> builtins. * config/rs6000/rs6000-protos.h (rs6000_address_for_altivec): Remove prototype. * config/rs6000/rs6000.c (altivec_expand_ld_builtin): Delete this function. (altivec_expand_st_builtin): Likewise. (altivec_expand_builtin): Remove calls to deleted functions. (rs6000_address_for_altivec): Delete this function. * config/rs6000/vector.md: Remove expands for vector_altivec_load_<mode> and vector_altivec_store_<mode>. Index: gcc/config/rs6000/rs6000-builtin.def =================================================================== --- gcc/config/rs6000/rs6000-builtin.def (revision 258338) +++ gcc/config/rs6000/rs6000-builtin.def (working copy) @@ -1210,20 +1210,6 @@ BU_ALTIVEC_P (VCMPGTSB_P, "vcmpgtsb_p", CONST, BU_ALTIVEC_P (VCMPGTUB_P, "vcmpgtub_p", CONST, vector_gtu_v16qi_p) /* AltiVec builtins that are handled as special cases. */ -BU_ALTIVEC_X (ST_INTERNAL_4si, "st_internal_4si", MEM) -BU_ALTIVEC_X (LD_INTERNAL_4si, "ld_internal_4si", MEM) -BU_ALTIVEC_X (ST_INTERNAL_8hi, "st_internal_8hi", MEM) -BU_ALTIVEC_X (LD_INTERNAL_8hi, "ld_internal_8hi", MEM) -BU_ALTIVEC_X (ST_INTERNAL_16qi, "st_internal_16qi", MEM) -BU_ALTIVEC_X (LD_INTERNAL_16qi, "ld_internal_16qi", MEM) -BU_ALTIVEC_X (ST_INTERNAL_4sf, "st_internal_16qi", MEM) -BU_ALTIVEC_X (LD_INTERNAL_4sf, "ld_internal_4sf", MEM) -BU_ALTIVEC_X (ST_INTERNAL_2df, "st_internal_4sf", MEM) -BU_ALTIVEC_X (LD_INTERNAL_2df, "ld_internal_2df", MEM) -BU_ALTIVEC_X (ST_INTERNAL_2di, "st_internal_2di", MEM) -BU_ALTIVEC_X (LD_INTERNAL_2di, "ld_internal_2di", MEM) -BU_ALTIVEC_X (ST_INTERNAL_1ti, "st_internal_1ti", MEM) -BU_ALTIVEC_X (LD_INTERNAL_1ti, "ld_internal_1ti", MEM) BU_ALTIVEC_X (MTVSCR, "mtvscr", MISC) BU_ALTIVEC_X (MFVSCR, "mfvscr", MISC) BU_ALTIVEC_X (DSSALL, "dssall", MISC) Index: gcc/config/rs6000/rs6000-protos.h =================================================================== --- gcc/config/rs6000/rs6000-protos.h (revision 258338) +++ gcc/config/rs6000/rs6000-protos.h (working copy) @@ -162,7 +162,6 @@ extern void rs6000_emit_parity (rtx, rtx); extern rtx rs6000_machopic_legitimize_pic_address (rtx, machine_mode, rtx); extern rtx rs6000_address_for_fpconvert (rtx); -extern rtx rs6000_address_for_altivec (rtx); extern rtx rs6000_allocate_stack_temp (machine_mode, bool, bool); extern int rs6000_loop_align (rtx); extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool); Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 258338) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -15183,127 +15183,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode return target; } -/* Expand the lvx builtins. */ -static rtx -altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp) -{ - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); - unsigned int fcode = DECL_FUNCTION_CODE (fndecl); - tree arg0; - machine_mode tmode, mode0; - rtx pat, op0; - enum insn_code icode; - switch (fcode) - { - case ALTIVEC_BUILTIN_LD_INTERNAL_16qi: - icode = CODE_FOR_vector_altivec_load_v16qi; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_8hi: - icode = CODE_FOR_vector_altivec_load_v8hi; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_4si: - icode = CODE_FOR_vector_altivec_load_v4si; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_4sf: - icode = CODE_FOR_vector_altivec_load_v4sf; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_2df: - icode = CODE_FOR_vector_altivec_load_v2df; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_2di: - icode = CODE_FOR_vector_altivec_load_v2di; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_1ti: - icode = CODE_FOR_vector_altivec_load_v1ti; - break; - default: - *expandedp = false; - return NULL_RTX; - } - - *expandedp = true; - - arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); - tmode = insn_data[icode].operand[0].mode; - mode0 = insn_data[icode].operand[1].mode; - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - - pat = GEN_FCN (icode) (target, op0); - if (! pat) - return 0; - emit_insn (pat); - return target; -} - -/* Expand the stvx builtins. */ -static rtx -altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, - bool *expandedp) -{ - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); - unsigned int fcode = DECL_FUNCTION_CODE (fndecl); - tree arg0, arg1; - machine_mode mode0, mode1; - rtx pat, op0, op1; - enum insn_code icode; - - switch (fcode) - { - case ALTIVEC_BUILTIN_ST_INTERNAL_16qi: - icode = CODE_FOR_vector_altivec_store_v16qi; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_8hi: - icode = CODE_FOR_vector_altivec_store_v8hi; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_4si: - icode = CODE_FOR_vector_altivec_store_v4si; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_4sf: - icode = CODE_FOR_vector_altivec_store_v4sf; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_2df: - icode = CODE_FOR_vector_altivec_store_v2df; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_2di: - icode = CODE_FOR_vector_altivec_store_v2di; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_1ti: - icode = CODE_FOR_vector_altivec_store_v1ti; - break; - default: - *expandedp = false; - return NULL_RTX; - } - - arg0 = CALL_EXPR_ARG (exp, 0); - arg1 = CALL_EXPR_ARG (exp, 1); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; - - if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); - - pat = GEN_FCN (icode) (op0, op1); - if (pat) - emit_insn (pat); - - *expandedp = true; - return NULL_RTX; -} - /* Expand the dst builtins. */ static rtx altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, @@ -15507,14 +15387,6 @@ altivec_expand_builtin (tree exp, rtx target, bool return expand_call (exp, target, false); } - target = altivec_expand_ld_builtin (exp, target, expandedp); - if (*expandedp) - return target; - - target = altivec_expand_st_builtin (exp, target, expandedp); - if (*expandedp) - return target; - target = altivec_expand_dst_builtin (exp, target, expandedp); if (*expandedp) return target; @@ -37995,29 +37867,6 @@ rs6000_address_for_fpconvert (rtx x) return x; } -/* Given a memory reference, if it is not in the form for altivec memory - reference instructions (i.e. reg or reg+reg addressing with AND of -16), - convert to the altivec format. */ - -rtx -rs6000_address_for_altivec (rtx x) -{ - gcc_assert (MEM_P (x)); - if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x))) - { - rtx addr = XEXP (x, 0); - - if (!legitimate_indexed_address_p (addr, reload_completed) - && !legitimate_indirect_address_p (addr, reload_completed)) - addr = copy_to_mode_reg (Pmode, addr); - - addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16)); - x = change_address (x, GET_MODE (x), addr); - } - - return x; -} - /* Implement TARGET_LEGITIMATE_CONSTANT_P. On the RS/6000, all integer constants are acceptable, most won't be valid Index: gcc/config/rs6000/vector.md =================================================================== --- gcc/config/rs6000/vector.md (revision 258338) +++ gcc/config/rs6000/vector.md (working copy) @@ -180,55 +180,6 @@ DONE; }) -;; Vector floating point load/store instructions that uses the Altivec -;; instructions even if we are compiling for VSX, since the Altivec -;; instructions silently ignore the bottom 3 bits of the address, and VSX does -;; not. -(define_expand "vector_altivec_load_<mode>" - [(set (match_operand:VEC_M 0 "vfloat_operand") - (match_operand:VEC_M 1 "memory_operand"))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - gcc_assert (VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)); - - if (VECTOR_MEM_VSX_P (<MODE>mode)) - { - operands[1] = rs6000_address_for_altivec (operands[1]); - rtx and_op = XEXP (operands[1], 0); - gcc_assert (GET_CODE (and_op) == AND); - rtx addr = XEXP (and_op, 0); - if (GET_CODE (addr) == PLUS) - emit_insn (gen_altivec_lvx_<mode>_2op (operands[0], XEXP (addr, 0), - XEXP (addr, 1))); - else - emit_insn (gen_altivec_lvx_<mode>_1op (operands[0], operands[1])); - DONE; - } -}) - -(define_expand "vector_altivec_store_<mode>" - [(set (match_operand:VEC_M 0 "memory_operand") - (match_operand:VEC_M 1 "vfloat_operand"))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - gcc_assert (VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)); - - if (VECTOR_MEM_VSX_P (<MODE>mode)) - { - operands[0] = rs6000_address_for_altivec (operands[0]); - rtx and_op = XEXP (operands[0], 0); - gcc_assert (GET_CODE (and_op) == AND); - rtx addr = XEXP (and_op, 0); - if (GET_CODE (addr) == PLUS) - emit_insn (gen_altivec_stvx_<mode>_2op (operands[1], XEXP (addr, 0), - XEXP (addr, 1))); - else - emit_insn (gen_altivec_stvx_<mode>_1op (operands[1], operands[0])); - DONE; - } -}) - - ;; Generic floating point vector arithmetic support (define_expand "add<mode>3"