? testsuite/gcc.dg/vect/vect-72.c Index: alias.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/alias.c,v retrieving revision 1.239 diff -c -3 -p -r1.239 alias.c *** alias.c 30 Aug 2004 19:13:02 -0000 1.239 --- alias.c 14 Sep 2004 16:43:01 -0000 *************** get_alias_set (tree t) *** 465,471 **** } /* Check for accesses through restrict-qualified pointers. */ ! if (TREE_CODE (inner) == INDIRECT_REF) { tree decl = find_base_decl (TREE_OPERAND (inner, 0)); --- 465,473 ---- } /* Check for accesses through restrict-qualified pointers. */ ! if (TREE_CODE (inner) == INDIRECT_REF ! || TREE_CODE (inner) == ALIGN_INDIRECT_REF ! || TREE_CODE (inner) == MISALIGNED_INDIRECT_REF) { tree decl = find_base_decl (TREE_OPERAND (inner, 0)); *************** nonoverlapping_memrefs_p (rtx x, rtx y) *** 2021,2027 **** moffsetx = adjust_offset_for_component_ref (exprx, moffsetx); exprx = t; } ! else if (TREE_CODE (exprx) == INDIRECT_REF) { exprx = TREE_OPERAND (exprx, 0); if (flag_argument_noalias < 2 --- 2023,2031 ---- moffsetx = adjust_offset_for_component_ref (exprx, moffsetx); exprx = t; } ! else if (TREE_CODE (exprx) == INDIRECT_REF ! || TREE_CODE (exprx) == ALIGN_INDIRECT_REF ! || TREE_CODE (exprx) == MISALIGNED_INDIRECT_REF) { exprx = TREE_OPERAND (exprx, 0); if (flag_argument_noalias < 2 *************** nonoverlapping_memrefs_p (rtx x, rtx y) *** 2038,2044 **** moffsety = adjust_offset_for_component_ref (expry, moffsety); expry = t; } ! else if (TREE_CODE (expry) == INDIRECT_REF) { expry = TREE_OPERAND (expry, 0); if (flag_argument_noalias < 2 --- 2042,2050 ---- moffsety = adjust_offset_for_component_ref (expry, moffsety); expry = t; } ! else if (TREE_CODE (expry) == INDIRECT_REF ! || TREE_CODE (expry) == ALIGN_INDIRECT_REF ! || TREE_CODE (expry) == MISALIGNED_INDIRECT_REF) { expry = TREE_OPERAND (expry, 0); if (flag_argument_noalias < 2 Index: builtin-types.def =================================================================== RCS file: /cvs/gcc/gcc/gcc/builtin-types.def,v retrieving revision 1.28 diff -c -3 -p -r1.28 builtin-types.def *** builtin-types.def 9 Jul 2004 23:04:31 -0000 1.28 --- builtin-types.def 14 Sep 2004 16:43:01 -0000 *************** DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_ *** 75,80 **** --- 75,81 ---- DEF_PRIMITIVE_TYPE (BT_COMPLEX_FLOAT, complex_float_type_node) DEF_PRIMITIVE_TYPE (BT_COMPLEX_DOUBLE, complex_double_type_node) DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONGDOUBLE, complex_long_double_type_node) + DEF_PRIMITIVE_TYPE (BT_CHAR_VECTOR, (*build_vector_type) (char_type_node, 16)) DEF_PRIMITIVE_TYPE (BT_PTR, ptr_type_node) DEF_PRIMITIVE_TYPE (BT_FILEPTR, fileptr_type_node) *************** DEF_FUNCTION_TYPE_1 (BT_FN_STRING_CONST_ *** 160,165 **** --- 161,167 ---- DEF_FUNCTION_TYPE_1 (BT_FN_WORD_PTR, BT_WORD, BT_PTR) DEF_FUNCTION_TYPE_1 (BT_FN_INT_WINT, BT_INT, BT_WINT) DEF_FUNCTION_TYPE_1 (BT_FN_WINT_WINT, BT_WINT, BT_WINT) + DEF_FUNCTION_TYPE_1 (BT_FN_CHAR_VECTOR_PTR, BT_CHAR_VECTOR, BT_PTR) DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_INT, BT_VOID, BT_PTR, BT_INT) DEF_FUNCTION_TYPE_2 (BT_FN_STRING_STRING_CONST_STRING, Index: builtins.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/builtins.c,v retrieving revision 1.382 diff -c -3 -p -r1.382 builtins.c *** builtins.c 9 Sep 2004 16:33:17 -0000 1.382 --- builtins.c 14 Sep 2004 16:43:02 -0000 *************** static rtx result_vector (int, rtx); *** 88,93 **** --- 88,96 ---- static rtx expand_builtin_setjmp (tree, rtx); static void expand_builtin_update_setjmp_buf (rtx); static void expand_builtin_prefetch (tree); + #if defined (HAVE_build_vector_mask_for_load) || defined (HAVE_build_cc_mask_for_load) + static rtx expand_builtin_build_mask_for_load (tree); + #endif static rtx expand_builtin_apply_args (void); static rtx expand_builtin_apply_args_1 (void); static rtx expand_builtin_apply (rtx, rtx, rtx); *************** expand_builtin_prefetch (tree arglist) *** 970,975 **** --- 973,1031 ---- emit_insn (op0); } + #if defined (HAVE_build_vector_mask_for_load) || defined (HAVE_build_cc_mask_for_load) + /* Expand a call to __builtin_build_[*]_mask_for_load. The target is expected to + support some kind of mask creation functionality. */ + + static rtx + expand_builtin_build_mask_for_load (tree arglist) + { + tree arg; + rtx op, temp = const0_rtx; + + /* Argument 0 is an address. */ + if (!validate_arglist (arglist, POINTER_TYPE, 0)) + return const0_rtx; + + arg = TREE_VALUE (arglist); + op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL); + + #ifdef HAVE_build_vector_mask_for_load + if (HAVE_build_vector_mask_for_load) + { + int icode = (int) CODE_FOR_build_vector_mask_for_load; + enum machine_mode mode0 = insn_data[icode].operand[0].mode; + enum machine_mode mode1 = insn_data[icode].operand[1].mode; + rtx pat; + + temp = gen_reg_rtx (mode0); + + if (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE) + { + op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL); + op = memory_address (mode1, op); + op = gen_rtx_MEM (mode1, op); + } + else + abort (); + + pat = gen_build_vector_mask_for_load (temp, op); + emit_insn (pat); + } + #else + #ifdef HAVE_build_cc_mask_for_load + if (HAVE_build_cc_mask_for_load) + { + /* Not implemented yet. */ + abort (); + } + #endif /* HAVE_build_cc_mask_for_load */ + #endif /* HAVE_build_vector_mask_for_load */ + + return temp; + } + #endif /* HAVE_build_mask_for_load */ + /* Get a MEM rtx for expression EXP which is the address of an operand to be used to be used in a string instruction (cmpstrsi, movmemsi, ..). */ *************** expand_builtin (tree exp, rtx target, rt *** 6074,6080 **** case BUILT_IN_PREFETCH: expand_builtin_prefetch (arglist); return const0_rtx; ! case BUILT_IN_PROFILE_FUNC_ENTER: return expand_builtin_profile_func (false); case BUILT_IN_PROFILE_FUNC_EXIT: --- 6130,6140 ---- case BUILT_IN_PREFETCH: expand_builtin_prefetch (arglist); return const0_rtx; ! #if defined (HAVE_build_vector_mask_for_load) || defined (HAVE_build_cc_mask_for_load) ! case BUILT_IN_BUILD_VECTOR_MASK_FOR_LOAD: ! case BUILT_IN_BUILD_CC_MASK_FOR_LOAD: ! return expand_builtin_build_mask_for_load (arglist); ! #endif case BUILT_IN_PROFILE_FUNC_ENTER: return expand_builtin_profile_func (false); case BUILT_IN_PROFILE_FUNC_EXIT: Index: builtins.def =================================================================== RCS file: /cvs/gcc/gcc/gcc/builtins.def,v retrieving revision 1.91 diff -c -3 -p -r1.91 builtins.def *** builtins.def 5 Sep 2004 02:55:25 -0000 1.91 --- builtins.def 14 Sep 2004 16:43:03 -0000 *************** DEF_GCC_BUILTIN (BUILT_IN_POPCOUN *** 603,608 **** --- 603,610 ---- DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NULL) + DEF_GCC_BUILTIN (BUILT_IN_BUILD_VECTOR_MASK_FOR_LOAD, "build_vector_mask_for_load", BT_FN_CHAR_VECTOR_PTR, ATTR_NULL) + DEF_GCC_BUILTIN (BUILT_IN_BUILD_CC_MASK_FOR_LOAD, "build_cc_mask_for_load", BT_FN_WORD_PTR, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL) Index: emit-rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v retrieving revision 1.414 diff -c -3 -p -r1.414 emit-rtl.c *** emit-rtl.c 11 Sep 2004 01:49:39 -0000 1.414 --- emit-rtl.c 14 Sep 2004 16:43:04 -0000 *************** mem_expr_equal_p (tree expr1, tree expr2 *** 1485,1491 **** && mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */ TREE_OPERAND (expr2, 1)); ! if (TREE_CODE (expr1) == INDIRECT_REF) return mem_expr_equal_p (TREE_OPERAND (expr1, 0), TREE_OPERAND (expr2, 0)); --- 1485,1493 ---- && mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */ TREE_OPERAND (expr2, 1)); ! if (TREE_CODE (expr1) == INDIRECT_REF ! || TREE_CODE (expr1) == ALIGN_INDIRECT_REF ! || TREE_CODE (expr1) == MISALIGNED_INDIRECT_REF) return mem_expr_equal_p (TREE_OPERAND (expr1, 0), TREE_OPERAND (expr2, 0)); *************** set_mem_attributes_minus_bitpos (rtx ref *** 1546,1552 **** /* We can set the alignment from the type if we are making an object, this is an INDIRECT_REF, or if TYPE_ALIGN_OK. */ ! if (objectp || TREE_CODE (t) == INDIRECT_REF || TYPE_ALIGN_OK (type)) align = MAX (align, TYPE_ALIGN (type)); /* If the size is known, we can set that. */ --- 1548,1557 ---- /* We can set the alignment from the type if we are making an object, this is an INDIRECT_REF, or if TYPE_ALIGN_OK. */ ! if (objectp || TREE_CODE (t) == INDIRECT_REF ! || TREE_CODE (t) == MISALIGNED_INDIRECT_REF ! || TREE_CODE (t) == ALIGN_INDIRECT_REF ! || TYPE_ALIGN_OK (type)) align = MAX (align, TYPE_ALIGN (type)); /* If the size is known, we can set that. */ *************** set_mem_attributes_minus_bitpos (rtx ref *** 1672,1678 **** the size we got from the type? */ } else if (flag_argument_noalias > 1 ! && TREE_CODE (t2) == INDIRECT_REF && TREE_CODE (TREE_OPERAND (t2, 0)) == PARM_DECL) { expr = t2; --- 1677,1685 ---- the size we got from the type? */ } else if (flag_argument_noalias > 1 ! && (TREE_CODE (t2) == INDIRECT_REF ! || TREE_CODE (t2) == ALIGN_INDIRECT_REF ! || TREE_CODE (t2) == MISALIGNED_INDIRECT_REF) && TREE_CODE (TREE_OPERAND (t2, 0)) == PARM_DECL) { expr = t2; *************** set_mem_attributes_minus_bitpos (rtx ref *** 1683,1689 **** /* If this is a Fortran indirect argument reference, record the parameter decl. */ else if (flag_argument_noalias > 1 ! && TREE_CODE (t) == INDIRECT_REF && TREE_CODE (TREE_OPERAND (t, 0)) == PARM_DECL) { expr = t; --- 1690,1698 ---- /* If this is a Fortran indirect argument reference, record the parameter decl. */ else if (flag_argument_noalias > 1 ! && (TREE_CODE (t) == INDIRECT_REF ! || TREE_CODE (t) == ALIGN_INDIRECT_REF ! || TREE_CODE (t) == MISALIGNED_INDIRECT_REF) && TREE_CODE (TREE_OPERAND (t, 0)) == PARM_DECL) { expr = t; Index: expr.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/expr.c,v retrieving revision 1.720 diff -c -3 -p -r1.720 expr.c *** expr.c 11 Sep 2004 17:48:22 -0000 1.720 --- expr.c 14 Sep 2004 16:43:06 -0000 *************** safe_from_p (rtx x, tree exp, int top_p) *** 5829,5834 **** --- 5830,5837 ---- } break; + case MISALIGNED_INDIRECT_REF: + case ALIGN_INDIRECT_REF: case INDIRECT_REF: if (MEM_P (x) && alias_sets_conflict_p (MEM_ALIAS_SET (x), *************** expand_expr_real_1 (tree exp, rtx target *** 6739,6744 **** --- 6744,6751 ---- return target; } + case MISALIGNED_INDIRECT_REF: + case ALIGN_INDIRECT_REF: case INDIRECT_REF: { tree exp1 = TREE_OPERAND (exp, 0); *************** expand_expr_real_1 (tree exp, rtx target *** 6755,6760 **** --- 6762,6771 ---- op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM); op0 = memory_address (mode, op0); + + if (code == ALIGN_INDIRECT_REF) + op0 = expand_addr_floor_op (mode, op0); + temp = gen_rtx_MEM (mode, op0); orig = REF_ORIGINAL (exp); *************** expand_expr_real_1 (tree exp, rtx target *** 6762,6767 **** --- 6773,6784 ---- orig = exp; set_mem_attributes (temp, orig, 0); + if (code == MISALIGNED_INDIRECT_REF) + { + op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0); + temp = expand_addr_misaligned_op (mode, temp, op1); + } + return temp; } *************** expand_expr_real_1 (tree exp, rtx target *** 8197,8202 **** --- 8214,8239 ---- return expand_expr_real (TREE_OPERAND (exp, 0), original_target, tmode, modifier, alt_rtl); + case REALIGN_LOAD_EXPR: + { + tree oprnd0 = TREE_OPERAND (exp, 0); + tree oprnd1 = TREE_OPERAND (exp, 1); + tree oprnd2 = TREE_OPERAND (exp, 2); + rtx op2; + + this_optab = optab_for_tree_code (code, type); + if (this_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) + abort (); + expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, 0); + op2 = expand_expr (oprnd2, NULL_RTX, VOIDmode, 0); + temp = expand_realign_op (mode, this_optab, op0, op1, op2, + target, unsignedp); + if (temp == 0) + abort (); + return temp; + } + + default: return lang_hooks.expand_expr (exp, original_target, tmode, modifier, alt_rtl); Index: fold-const.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v retrieving revision 1.455 diff -c -3 -p -r1.455 fold-const.c *** fold-const.c 11 Sep 2004 19:48:53 -0000 1.455 --- fold-const.c 14 Sep 2004 16:43:08 -0000 *************** non_lvalue (tree x) *** 1990,1995 **** --- 1990,1997 ---- case COMPONENT_REF: case INDIRECT_REF: + case ALIGN_INDIRECT_REF: + case MISALIGNED_INDIRECT_REF: case ARRAY_REF: case ARRAY_RANGE_REF: case BIT_FIELD_REF: *************** operand_equal_p (tree arg0, tree arg1, u *** 2466,2471 **** --- 2468,2475 ---- switch (TREE_CODE (arg0)) { case INDIRECT_REF: + case ALIGN_INDIRECT_REF: + case MISALIGNED_INDIRECT_REF: case REALPART_EXPR: case IMAGPART_EXPR: return operand_equal_p (TREE_OPERAND (arg0, 0), *************** build_fold_addr_expr_with_type (tree t, *** 10501,10507 **** if (TREE_CODE (t) == WITH_SIZE_EXPR) t = TREE_OPERAND (t, 0); ! if (TREE_CODE (t) == INDIRECT_REF) { t = TREE_OPERAND (t, 0); if (TREE_TYPE (t) != ptrtype) --- 10506,10514 ---- if (TREE_CODE (t) == WITH_SIZE_EXPR) t = TREE_OPERAND (t, 0); ! if (TREE_CODE (t) == INDIRECT_REF ! || TREE_CODE (t) == MISALIGNED_INDIRECT_REF ! /* Note: doesn't apply to ALIGN_INDIRECT_REF */) { t = TREE_OPERAND (t, 0); if (TREE_TYPE (t) != ptrtype) Index: genopinit.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/genopinit.c,v retrieving revision 1.80 diff -c -3 -p -r1.80 genopinit.c *** genopinit.c 9 Sep 2004 13:22:34 -0000 1.80 --- genopinit.c 14 Sep 2004 16:43:08 -0000 *************** static const char * const optabs[] = *** 169,175 **** "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)", "vec_set_optab->handlers[$A].insn_code = CODE_FOR_$(vec_set$a$)", "vec_extract_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract$a$)", ! "vec_init_optab->handlers[$A].insn_code = CODE_FOR_$(vec_init$a$)" }; static void gen_insn (rtx); --- 169,179 ---- "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)", "vec_set_optab->handlers[$A].insn_code = CODE_FOR_$(vec_set$a$)", "vec_extract_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract$a$)", ! "vec_init_optab->handlers[$A].insn_code = CODE_FOR_$(vec_init$a$)", ! "vec_realign_store_optab->handlers[$A].insn_code = CODE_FOR_$(vec_realign_store_$a$)", ! "vec_realign_load_optab->handlers[$A].insn_code = CODE_FOR_$(vec_realign_load_$a$)", ! "addr_floor_optab->handlers[$A].insn_code = CODE_FOR_$(addr_floor_$a$)", ! "addr_misaligned_optab->handlers[$A].insn_code = CODE_FOR_$(addr_misaligned_$a$)" }; static void gen_insn (rtx); Index: gimplify.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v retrieving revision 2.76 diff -c -3 -p -r2.76 gimplify.c *** gimplify.c 11 Sep 2004 00:25:00 -0000 2.76 --- gimplify.c 14 Sep 2004 16:43:08 -0000 *************** gimplify_addr_expr (tree *expr_p, tree * *** 3051,3060 **** --- 3051,3062 ---- switch (TREE_CODE (op0)) { case INDIRECT_REF: + case MISALIGNED_INDIRECT_REF: /* Check if we are dealing with an expression of the form '&*ptr'. While the front end folds away '&*ptr' into 'ptr', these expressions may be generated internally by the compiler (e.g., builtins like __builtin_va_end). */ + /* Note: Doesn't apply to ALIGN_INDIRECT_REF */ *expr_p = TREE_OPERAND (op0, 0); ret = GS_OK; break; *************** gimplify_expr (tree *expr_p, tree *pre_p *** 3621,3626 **** --- 3623,3630 ---- recalculate_side_effects (*expr_p); break; + case ALIGN_INDIRECT_REF: + case MISALIGNED_INDIRECT_REF: case INDIRECT_REF: ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, is_gimple_reg, fb_rvalue); Index: optabs.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/optabs.c,v retrieving revision 1.241 diff -c -3 -p -r1.241 optabs.c *** optabs.c 10 Sep 2004 11:02:24 -0000 1.241 --- optabs.c 14 Sep 2004 16:43:09 -0000 *************** optab_for_tree_code (enum tree_code code *** 286,291 **** --- 286,303 ---- case MIN_EXPR: return TYPE_UNSIGNED (type) ? umin_optab : smin_optab; + case REALIGN_STORE_EXPR: + return vec_realign_store_optab; + + case REALIGN_LOAD_EXPR: + return vec_realign_load_optab; + + case ALIGN_INDIRECT_REF: + return addr_floor_optab; + + case MISALIGNED_INDIRECT_REF: + return addr_misaligned_optab; + default: break; } *************** optab_for_tree_code (enum tree_code code *** 313,318 **** --- 325,467 ---- } } + + /* Generate code to perform a realign_op operation specified by REALIGN_OPTAB + on operands OP0,OP1,OP2 with result having machine-mode MODE. + + realign_op extracts elements from two input vectors + OP0,OP1 of size VS, according to the offset OFF defined by OP2 as + follows: + + If realign_optab == realign_load_optab: + If OFF > 0, the last VS - OFF elements of vector OP0 are concatenated to + the first OFF elements of the vector OP1. + If OFF == 0, then the returned vector is OP1. + + If realign_optab == realign_store_optab: + If OFF > 0, the last OFF elements of vector OP0 are concatenated to + the first VS - OFF elements of the vector OP1. + If OFF == 0, then the returned vector is OP0. + + On different targets, OP2 may take different forms; The default is + that OP2 is an address, and its low log2(VS)-1 bits define the offset OFF. + + If TARGET is nonzero, the value + is generated there, if it is convenient to do so. + In all cases an rtx is returned for the locus of the value; + this may or may not be TARGET. */ + + rtx + expand_realign_op (enum machine_mode mode, optab realign_optab, + rtx op0, rtx op1, rtx op2, rtx target, int unsignedp) + { + int icode = (int) realign_optab->handlers[(int) mode].insn_code; + enum machine_mode mode0 = insn_data[icode].operand[1].mode; + enum machine_mode mode1 = insn_data[icode].operand[2].mode; + enum machine_mode mode2 = insn_data[icode].operand[3].mode; + rtx temp; + rtx pat; + rtx xop0 = op0, xop1 = op1, xop2 = op2; + + if (realign_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) + abort (); + + if (!target + || ! (*insn_data[icode].operand[0].predicate) (target, mode)) + temp = gen_reg_rtx (mode); + else + temp = target; + + /* In case the insn wants input operands in modes different from + those of the actual operands, convert the operands. It would + seem that we don't need to convert CONST_INTs, but we do, so + that they're properly zero-extended, sign-extended or truncated + for their mode. */ + + if (GET_MODE (op0) != mode0 && mode0 != VOIDmode) + xop0 = convert_modes (mode0, + GET_MODE (op0) != VOIDmode + ? GET_MODE (op0) + : mode, + xop0, unsignedp); + + if (GET_MODE (op1) != mode1 && mode1 != VOIDmode) + xop1 = convert_modes (mode1, + GET_MODE (op1) != VOIDmode + ? GET_MODE (op1) + : mode, + xop1, unsignedp); + + if (GET_MODE (op2) != mode2 && mode2 != VOIDmode) + xop2 = convert_modes (mode2, + GET_MODE (op2) != VOIDmode + ? GET_MODE (op2) + : mode, + xop2, unsignedp); + + /* Now, if insn's predicates don't allow our operands, put them into + pseudo regs. */ + + if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0) + && mode0 != VOIDmode) + xop0 = copy_to_mode_reg (mode0, xop0); + + if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1) + && mode1 != VOIDmode) + xop1 = copy_to_mode_reg (mode1, xop1); + + if (! (*insn_data[icode].operand[3].predicate) (xop2, mode2) + && mode2 != VOIDmode) + xop2 = copy_to_mode_reg (mode2, xop2); + + pat = GEN_FCN (icode) (temp, xop0, xop1, xop2); + + /* CHECKME: Need special handling if PAT is composed of more than one insn? */ + + emit_insn (pat); + return temp; + } + + /* Generate code to align an address that will be used in a vector + load/store operation. */ + extern rtx + expand_addr_floor_op (enum machine_mode mode ATTRIBUTE_UNUSED, rtx op0) + { + int icode; + rtx pat; + rtx temp = gen_reg_rtx (GET_MODE (op0)); + + if (addr_floor_optab->handlers[mode].insn_code == CODE_FOR_nothing) + abort (); + + icode = (int) addr_floor_optab->handlers[mode].insn_code; + + pat = GEN_FCN (icode) (temp, op0); + + emit_insn (pat); + return temp; + } + + /* Generate code to handle an unaligned address that will be used in a vector + load/store operation. */ + extern rtx + expand_addr_misaligned_op (enum machine_mode mode, rtx op0, rtx op1) + { + int icode; + rtx pat; + rtx temp = gen_reg_rtx (mode); + + if (addr_misaligned_optab->handlers[mode].insn_code == CODE_FOR_nothing) + abort (); + + icode = (int) addr_misaligned_optab->handlers[mode].insn_code; + + pat = GEN_FCN (icode) (temp, op0, op1); + + emit_insn (pat); + return temp; + } + /* Like expand_binop, but return a constant rtx if the result can be calculated at compile time. The arguments and return value are otherwise the same as for expand_binop. */ *************** init_optabs (void) *** 4657,4662 **** --- 4806,4815 ---- vec_extract_optab = init_optab (UNKNOWN); vec_set_optab = init_optab (UNKNOWN); vec_init_optab = init_optab (UNKNOWN); + vec_realign_load_optab = init_optab (UNKNOWN); + addr_floor_optab = init_optab (UNKNOWN); + addr_misaligned_optab = init_optab (UNKNOWN); + /* Conversions. */ sext_optab = init_convert_optab (SIGN_EXTEND); zext_optab = init_convert_optab (ZERO_EXTEND); Index: optabs.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/optabs.h,v retrieving revision 1.35 diff -c -3 -p -r1.35 optabs.h *** optabs.h 4 Sep 2004 07:55:04 -0000 1.35 --- optabs.h 14 Sep 2004 16:43:09 -0000 *************** enum optab_index *** 228,233 **** --- 228,241 ---- OTI_vec_extract, /* Initialize vector operand. */ OTI_vec_init, + /* Extract specified elements from vectors, for vector store. */ + OTI_vec_realign_store, + /* Extract specified elements from vectors, for vector load. */ + OTI_vec_realign_load, + /* Drop low bits of address. */ + OTI_addr_floor, + /* Possibly misaligned address. */ + OTI_addr_misaligned, OTI_MAX }; *************** extern GTY(()) optab optab_table[OTI_MAX *** 330,335 **** --- 338,347 ---- #define vec_set_optab (optab_table[OTI_vec_set]) #define vec_extract_optab (optab_table[OTI_vec_extract]) #define vec_init_optab (optab_table[OTI_vec_init]) + #define vec_realign_store_optab (optab_table[OTI_vec_realign_store]) + #define vec_realign_load_optab (optab_table[OTI_vec_realign_load]) + #define addr_floor_optab (optab_table[OTI_addr_floor]) + #define addr_misaligned_optab (optab_table[OTI_addr_misaligned]) /* Conversion optabs have their own table and indexes. */ enum convert_optab_index *************** extern enum insn_code cmpmem_optab[NUM_M *** 405,410 **** --- 417,452 ---- /* Define functions given in optabs.c. */ + /* Generate code to extract elements from two input vectors + OP0,OP1 of size VS, according to the offset OFF defined by OP2 as + follows: + + If realign_optab == realign_load_optab: + If OFF > 0, the last VS - OFF elements of vector OP0 are concatenated to + the first OFF elements of the vector OP1. + If OFF == 0, then the returned vector is OP1. + + If realign_optab == realign_store_optab: + If OFF > 0, the last OFF elements of vector OP0 are concatenated to + the first VS - OFF elements of the vector OP1. + If OFF == 0, then the returned vector is OP0. + + On different targets, OP2 may take different forms; The default is + that OP2 is an address, and its low log2(VS)-1 bits define the offset. */ + extern rtx + expand_realign_op (enum machine_mode mode, optab realign_optab, + rtx op0, rtx op1, rtx op2, rtx target, int unsignedp); + + /* Generate code to align an address that will be used in a vector + load/store operation. */ + extern rtx + expand_addr_floor_op (enum machine_mode mode, rtx op); + + /* Generate code to handle an unaligned address that will be used in a vector + load/store operation. */ + extern rtx + expand_addr_misaligned_op (enum machine_mode mode, rtx op0, rtx op1); + /* Expand a binary operation given optab and rtx operands. */ extern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int, enum optab_methods); Index: print-rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/print-rtl.c,v retrieving revision 1.116 diff -c -3 -p -r1.116 print-rtl.c *** print-rtl.c 16 Aug 2004 23:05:03 -0000 1.116 --- print-rtl.c 14 Sep 2004 16:43:09 -0000 *************** print_mem_expr (FILE *outfile, tree expr *** 86,91 **** --- 86,103 ---- print_mem_expr (outfile, TREE_OPERAND (expr, 0)); fputs (")", outfile); } + else if (TREE_CODE (expr) == ALIGN_INDIRECT_REF) + { + fputs (" (A*", outfile); + print_mem_expr (outfile, TREE_OPERAND (expr, 0)); + fputs (")", outfile); + } + else if (TREE_CODE (expr) == MISALIGNED_INDIRECT_REF) + { + fputs (" (M*", outfile); + print_mem_expr (outfile, TREE_OPERAND (expr, 0)); + fputs (")", outfile); + } else if (DECL_NAME (expr)) fprintf (outfile, " %s", IDENTIFIER_POINTER (DECL_NAME (expr))); else if (TREE_CODE (expr) == RESULT_DECL) Index: tree-dump.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-dump.c,v retrieving revision 1.32 diff -c -3 -p -r1.32 tree-dump.c *** tree-dump.c 10 Sep 2004 08:20:10 -0000 1.32 --- tree-dump.c 14 Sep 2004 16:43:10 -0000 *************** dequeue_and_dump (dump_info_p di) *** 527,532 **** --- 527,534 ---- case TRUTH_NOT_EXPR: case ADDR_EXPR: case INDIRECT_REF: + case ALIGN_INDIRECT_REF: + case MISALIGNED_INDIRECT_REF: case CLEANUP_POINT_EXPR: case SAVE_EXPR: case REALPART_EXPR: Index: tree-eh.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-eh.c,v retrieving revision 2.18 diff -c -3 -p -r2.18 tree-eh.c *** tree-eh.c 9 Sep 2004 07:54:07 -0000 2.18 --- tree-eh.c 14 Sep 2004 16:43:10 -0000 *************** tree_could_trap_p (tree expr) *** 1767,1772 **** --- 1767,1774 ---- return !in_array_bounds_p (expr); case INDIRECT_REF: + case ALIGN_INDIRECT_REF: + case MISALIGNED_INDIRECT_REF: return !TREE_THIS_NOTRAP (expr); case ASM_EXPR: Index: tree-gimple.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-gimple.c,v retrieving revision 2.23 diff -c -3 -p -r2.23 tree-gimple.c *** tree-gimple.c 5 Sep 2004 09:25:27 -0000 2.23 --- tree-gimple.c 14 Sep 2004 16:43:10 -0000 *************** is_gimple_addressable (tree t) *** 324,330 **** return (is_gimple_id (t) || handled_component_p (t) || TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR ! || TREE_CODE (t) == INDIRECT_REF); } /* Return true if T is function invariant. Or rather a restricted --- 324,332 ---- return (is_gimple_id (t) || handled_component_p (t) || TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR ! || TREE_CODE (t) == INDIRECT_REF ! || TREE_CODE (t) == ALIGN_INDIRECT_REF ! || TREE_CODE (t) == MISALIGNED_INDIRECT_REF); } /* Return true if T is function invariant. Or rather a restricted *************** get_base_address (tree t) *** 564,569 **** --- 567,574 ---- if (SSA_VAR_P (t) || TREE_CODE (t) == STRING_CST || TREE_CODE (t) == CONSTRUCTOR + || TREE_CODE (t) == MISALIGNED_INDIRECT_REF + || TREE_CODE (t) == ALIGN_INDIRECT_REF || TREE_CODE (t) == INDIRECT_REF) return t; else Index: tree-pretty-print.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-pretty-print.c,v retrieving revision 2.37 diff -c -3 -p -r2.37 tree-pretty-print.c *** tree-pretty-print.c 11 Sep 2004 19:48:54 -0000 2.37 --- tree-pretty-print.c 14 Sep 2004 16:43:10 -0000 *************** dump_generic_node (pretty_printer *buffe *** 1018,1023 **** --- 1018,1025 ---- case ADDR_EXPR: case PREDECREMENT_EXPR: case PREINCREMENT_EXPR: + case ALIGN_INDIRECT_REF: + case MISALIGNED_INDIRECT_REF: case INDIRECT_REF: if (TREE_CODE (node) == ADDR_EXPR && (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST *************** dump_generic_node (pretty_printer *buffe *** 1034,1039 **** --- 1036,1048 ---- } else dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); + + if (TREE_CODE (node) == MISALIGNED_INDIRECT_REF) + { + pp_string (buffer, "{misalignment: "); + dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false); + pp_character (buffer, '}'); + } break; case POSTDECREMENT_EXPR: *************** dump_generic_node (pretty_printer *buffe *** 1453,1458 **** --- 1462,1477 ---- is_stmt = false; break; + case REALIGN_LOAD_EXPR: + pp_string (buffer, "REALIGN_LOAD <"); + dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); + pp_string (buffer, ", "); + dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false); + pp_string (buffer, ", "); + dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false); + pp_string (buffer, ">"); + break; + default: NIY; } *************** op_prio (tree op) *** 1712,1717 **** --- 1731,1738 ---- case PREINCREMENT_EXPR: case PREDECREMENT_EXPR: case NEGATE_EXPR: + case ALIGN_INDIRECT_REF: + case MISALIGNED_INDIRECT_REF: case INDIRECT_REF: case ADDR_EXPR: case FLOAT_EXPR: *************** op_symbol (tree op) *** 1840,1845 **** --- 1861,1872 ---- case INDIRECT_REF: return "*"; + case ALIGN_INDIRECT_REF: + return "A*"; + + case MISALIGNED_INDIRECT_REF: + return "M*"; + case TRUNC_DIV_EXPR: case RDIV_EXPR: return "/"; Index: tree-ssa-alias.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v retrieving revision 2.33 diff -c -3 -p -r2.33 tree-ssa-alias.c *** tree-ssa-alias.c 11 Sep 2004 18:57:03 -0000 2.33 --- tree-ssa-alias.c 14 Sep 2004 16:43:11 -0000 *************** collect_points_to_info_for (struct alias *** 495,508 **** /* Helper for ptr_is_dereferenced_by. Called by walk_tree to look for ! INDIRECT_REF nodes for the pointer passed in DATA. */ static tree find_ptr_dereference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data) { tree ptr = (tree) data; ! if (TREE_CODE (*tp) == INDIRECT_REF && TREE_OPERAND (*tp, 0) == ptr) return *tp; --- 495,510 ---- /* Helper for ptr_is_dereferenced_by. Called by walk_tree to look for ! (ALIGN/MISALIGNED_)INDIRECT_REF nodes for the pointer passed in DATA. */ static tree find_ptr_dereference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data) { tree ptr = (tree) data; ! if ((TREE_CODE (*tp) == INDIRECT_REF ! || TREE_CODE (*tp) == ALIGN_INDIRECT_REF ! || TREE_CODE (*tp) == MISALIGNED_INDIRECT_REF) && TREE_OPERAND (*tp, 0) == ptr) return *tp; *************** find_ptr_dereference (tree *tp, int *wal *** 510,517 **** } ! /* Return true if STMT contains INDIRECT_REF . *IS_STORE is set ! to 'true' if the dereference is on the LHS of an assignment. */ static bool ptr_is_dereferenced_by (tree ptr, tree stmt, bool *is_store) --- 512,520 ---- } ! /* Return true if STMT contains (ALIGN/MISALIGNED_)INDIRECT_REF . ! *IS_STORE is set to 'true' if the dereference is on the LHS of an ! assignment. */ static bool ptr_is_dereferenced_by (tree ptr, tree stmt, bool *is_store) Index: tree-ssa-dce.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dce.c,v retrieving revision 2.17 diff -c -3 -p -r2.17 tree-ssa-dce.c *** tree-ssa-dce.c 10 Sep 2004 08:58:47 -0000 2.17 --- tree-ssa-dce.c 14 Sep 2004 16:43:11 -0000 *************** mark_stmt_if_obviously_necessary (tree s *** 418,424 **** if (is_global_var (lhs)) mark_stmt_necessary (stmt, true); } ! else if (TREE_CODE (lhs) == INDIRECT_REF) { tree ptr = TREE_OPERAND (lhs, 0); struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); --- 418,426 ---- if (is_global_var (lhs)) mark_stmt_necessary (stmt, true); } ! else if (TREE_CODE (lhs) == INDIRECT_REF ! || TREE_CODE (lhs) == ALIGN_INDIRECT_REF ! || TREE_CODE (lhs) == MISALIGNED_INDIRECT_REF) { tree ptr = TREE_OPERAND (lhs, 0); struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); Index: tree-ssa-dom.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dom.c,v retrieving revision 2.37 diff -c -3 -p -r2.37 tree-ssa-dom.c *** tree-ssa-dom.c 9 Sep 2004 07:54:12 -0000 2.37 --- tree-ssa-dom.c 14 Sep 2004 16:43:11 -0000 *************** record_equivalences_from_stmt (tree stmt *** 2523,2529 **** t = TREE_OPERAND (t, 0); /* Now see if this is a pointer dereference. */ ! if (TREE_CODE (t) == INDIRECT_REF) { tree op = TREE_OPERAND (t, 0); --- 2523,2531 ---- t = TREE_OPERAND (t, 0); /* Now see if this is a pointer dereference. */ ! if (TREE_CODE (t) == INDIRECT_REF ! || TREE_CODE (t) == ALIGN_INDIRECT_REF ! || TREE_CODE (t) == MISALIGNED_INDIRECT_REF) { tree op = TREE_OPERAND (t, 0); Index: tree-ssa-loop-im.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-im.c,v retrieving revision 2.12 diff -c -3 -p -r2.12 tree-ssa-loop-im.c *** tree-ssa-loop-im.c 11 Sep 2004 20:42:06 -0000 2.12 --- tree-ssa-loop-im.c 14 Sep 2004 16:43:11 -0000 *************** for_each_index (tree *addr_p, bool (*cbc *** 137,142 **** --- 137,144 ---- case SSA_NAME: return cbck (*addr_p, addr_p, data); + case MISALIGNED_INDIRECT_REF: + case ALIGN_INDIRECT_REF: case INDIRECT_REF: nxt = &TREE_OPERAND (*addr_p, 0); return cbck (*addr_p, nxt, data); *************** is_call_clobbered_ref (tree ref) *** 1101,1107 **** if (DECL_P (base)) return is_call_clobbered (base); ! if (TREE_CODE (base) == INDIRECT_REF) { /* Check whether the alias tags associated with the pointer are call clobbered. */ --- 1103,1111 ---- if (DECL_P (base)) return is_call_clobbered (base); ! if (TREE_CODE (base) == INDIRECT_REF ! || TREE_CODE (base) == ALIGN_INDIRECT_REF ! || TREE_CODE (base) == MISALIGNED_INDIRECT_REF) { /* Check whether the alias tags associated with the pointer are call clobbered. */ Index: tree-ssa-loop-ivopts.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v retrieving revision 2.9 diff -c -3 -p -r2.9 tree-ssa-loop-ivopts.c *** tree-ssa-loop-ivopts.c 10 Sep 2004 08:56:36 -0000 2.9 --- tree-ssa-loop-ivopts.c 14 Sep 2004 16:43:12 -0000 *************** find_interesting_uses_address (struct iv *** 1227,1233 **** || zero_p (step)) goto fail; ! if (TREE_CODE (base) == INDIRECT_REF) base = TREE_OPERAND (base, 0); else base = build_addr (base); --- 1227,1235 ---- || zero_p (step)) goto fail; ! if (TREE_CODE (base) == INDIRECT_REF ! || TREE_CODE (base) == ALIGN_INDIRECT_REF ! || TREE_CODE (base) == MISALIGNED_INDIRECT_REF) base = TREE_OPERAND (base, 0); else base = build_addr (base); *************** add_address_candidates (struct ivopts_da *** 1648,1654 **** if (base != TREE_OPERAND (iv->base, 0)) { ! if (TREE_CODE (base) == INDIRECT_REF) base = TREE_OPERAND (base, 0); else base = build_addr (base); --- 1650,1658 ---- if (base != TREE_OPERAND (iv->base, 0)) { ! if (TREE_CODE (base) == INDIRECT_REF ! || TREE_CODE (base) == ALIGN_INDIRECT_REF ! || TREE_CODE (base) == MISALIGNED_INDIRECT_REF) base = TREE_OPERAND (base, 0); else base = build_addr (base); *************** peel_address (tree addr, unsigned HOST_W *** 2512,2517 **** --- 2516,2523 ---- switch (TREE_CODE (addr)) { case SSA_NAME: + case MISALIGNED_INDIRECT_REF: + case ALIGN_INDIRECT_REF: case INDIRECT_REF: case BIT_FIELD_REF: case VAR_DECL: *************** unshare_and_remove_ssa_names (tree ref) *** 3860,3872 **** static void rewrite_address_base (block_stmt_iterator *bsi, tree *op, tree with) { ! tree var = get_base_address (*op), new_var, new_name, copy, name; tree orig; if (!var || TREE_CODE (with) != SSA_NAME) goto do_rewrite; ! ! if (TREE_CODE (var) == INDIRECT_REF) var = TREE_OPERAND (var, 0); if (TREE_CODE (var) == SSA_NAME) { --- 3866,3881 ---- static void rewrite_address_base (block_stmt_iterator *bsi, tree *op, tree with) { ! tree bvar, var, new_var, new_name, copy, name; tree orig; + var = bvar = get_base_address (*op); + if (!var || TREE_CODE (with) != SSA_NAME) goto do_rewrite; ! if (TREE_CODE (var) == INDIRECT_REF ! || TREE_CODE (var) == ALIGN_INDIRECT_REF ! || TREE_CODE (var) == MISALIGNED_INDIRECT_REF) var = TREE_OPERAND (var, 0); if (TREE_CODE (var) == SSA_NAME) { *************** rewrite_address_base (block_stmt_iterato *** 3903,3914 **** do_rewrite: orig = NULL_TREE; ! if (TREE_CODE (*op) == INDIRECT_REF) orig = REF_ORIGINAL (*op); if (!orig) orig = unshare_and_remove_ssa_names (*op); ! *op = build1 (INDIRECT_REF, TREE_TYPE (*op), with); /* Record the original reference, for purposes of alias analysis. */ REF_ORIGINAL (*op) = orig; } --- 3912,3931 ---- do_rewrite: orig = NULL_TREE; ! if (TREE_CODE (*op) == INDIRECT_REF ! || TREE_CODE (*op) == ALIGN_INDIRECT_REF ! || TREE_CODE (*op) == MISALIGNED_INDIRECT_REF) orig = REF_ORIGINAL (*op); if (!orig) orig = unshare_and_remove_ssa_names (*op); ! if (TREE_CODE (bvar) == ALIGN_INDIRECT_REF) ! *op = build1 (ALIGN_INDIRECT_REF, TREE_TYPE (*op), with); ! else if (TREE_CODE (bvar) == MISALIGNED_INDIRECT_REF) ! *op = build2 (MISALIGNED_INDIRECT_REF, TREE_TYPE (*op), with, TREE_OPERAND (*op, 1)); ! else ! *op = build1 (INDIRECT_REF, TREE_TYPE (*op), with); ! /* Record the original reference, for purposes of alias analysis. */ REF_ORIGINAL (*op) = orig; } Index: tree-ssa-operands.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-operands.c,v retrieving revision 2.39 diff -c -3 -p -r2.39 tree-ssa-operands.c *** tree-ssa-operands.c 10 Sep 2004 10:44:47 -0000 2.39 --- tree-ssa-operands.c 14 Sep 2004 16:43:12 -0000 *************** get_expr_operands (tree stmt, tree *expr *** 1007,1012 **** --- 1007,1017 ---- add_stmt_operand (expr_p, stmt, flags); return; + case MISALIGNED_INDIRECT_REF: + get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags); + /* fall through */ + + case ALIGN_INDIRECT_REF: case INDIRECT_REF: get_indirect_ref_operands (stmt, expr, flags); return; *************** get_expr_operands (tree stmt, tree *expr *** 1159,1164 **** --- 1164,1177 ---- return; } + case REALIGN_LOAD_EXPR: + { + get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags); + get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags); + get_expr_operands (stmt, &TREE_OPERAND (expr, 2), flags); + return; + } + case BLOCK: case FUNCTION_DECL: case EXC_PTR_EXPR: *************** get_asm_expr_operands (tree stmt) *** 1271,1277 **** } } ! /* A subroutine of get_expr_operands to handle INDIRECT_REF. */ static void get_indirect_ref_operands (tree stmt, tree expr, int flags) --- 1284,1291 ---- } } ! /* A subroutine of get_expr_operands to handle INDIRECT_REF, ! ALIGN_INDIRECT_REF and MISALIGNED_INDIRECT_REF. */ static void get_indirect_ref_operands (tree stmt, tree expr, int flags) Index: tree-vectorizer.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.c,v retrieving revision 2.8 diff -c -3 -p -r2.8 tree-vectorizer.c *** tree-vectorizer.c 10 Sep 2004 10:44:47 -0000 2.8 --- tree-vectorizer.c 14 Sep 2004 16:43:13 -0000 *************** static bool vect_analyze_data_ref_access *** 181,192 **** static bool vect_get_first_index (tree, tree *); static bool vect_can_force_dr_alignment_p (tree, unsigned int); static tree vect_get_base_decl_and_bit_offset (tree, tree *); ! static struct data_reference * vect_analyze_pointer_ref_access (tree, tree, bool); /* Utility functions for the code transformation. */ static tree vect_create_destination_var (tree, tree); ! static tree vect_create_data_ref (tree, block_stmt_iterator *); ! static tree vect_create_index_for_array_ref (tree, block_stmt_iterator *); static tree get_vectype_for_scalar_type (tree); static tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *); static tree vect_get_vec_def_for_operand (tree, tree); --- 181,196 ---- static bool vect_get_first_index (tree, tree *); static bool vect_can_force_dr_alignment_p (tree, unsigned int); static tree vect_get_base_decl_and_bit_offset (tree, tree *); ! static struct data_reference * vect_analyze_pointer_ref_access ! (tree, tree, bool); /* Utility functions for the code transformation. */ static tree vect_create_destination_var (tree, tree); ! static tree vect_create_data_ref_ptr ! (tree, block_stmt_iterator *, tree, tree *, bool); ! static tree vect_create_index_for_vector_ref ! (struct loop *, block_stmt_iterator *); ! static tree vect_create_addr_base_for_vector_ref (tree, tree *, tree); static tree get_vectype_for_scalar_type (tree); static tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *); static tree vect_get_vec_def_for_operand (tree, tree); *************** new_stmt_vec_info (tree stmt, struct loo *** 225,230 **** --- 229,244 ---- return res; } + #ifdef HAVE_build_vector_mask_for_load + #define BUILT_IN_build_mask_for_load BUILT_IN_BUILD_VECTOR_MASK_FOR_LOAD + #else + #ifdef HAVE_build_cc_mask_for_load + #define BUILT_IN_build_mask_for_load BUILT_IN_BUILD_CC_MASK_FOR_LOAD + #else + #undef BUILT_IN_build_mask_for_load + #endif /* HAVE_build_cc_mask_for_load */ + #endif /* HAVE_build_vector_mask_for_load */ + /* Function new_loop_vec_info. *************** vect_get_new_vect_var (tree type, enum v *** 507,593 **** } ! /* Function create_index_for_array_ref. ! Create (and return) an index variable, along with it's update chain in the loop. This variable will be used to access a memory location in a vector operation. ! Input: ! STMT: The stmt that contains a memory data-ref. BSI: The block_stmt_iterator where STMT is. Any new stmts created by this function can be added here, or in the loop pre-header. FORNOW: We are only handling array accesses with step 1. */ static tree ! vect_create_index_for_array_ref (tree stmt, block_stmt_iterator *bsi) ! { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); struct loop *loop = STMT_VINFO_LOOP (stmt_info); struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); ! tree expr = DR_REF (dr); tree access_fn; ! tree init, step; ! loop_vec_info loop_info = loop->aux; ! int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_info); ! tree vf; ! tree array_first_index; ! tree indx_before_incr, indx_after_incr; ! int loopnum = loop->num; bool ok; ! #ifdef ENABLE_CHECKING ! varray_type access_fns = DR_ACCESS_FNS (dr); ! /* FORNOW: handling only one dimensional arrays. */ ! gcc_assert (VARRAY_ACTIVE_SIZE (access_fns) == 1); ! gcc_assert (vectorization_factor); ! #endif ! access_fn = DR_ACCESS_FN (dr, 0); ! ok = vect_is_simple_iv_evolution (loopnum, access_fn, &init, &step, true) ! && vect_get_first_index (expr, &array_first_index); ! gcc_assert (ok); ! /* FORNOW: Handling only constant 'init'. */ ! gcc_assert (TREE_CODE (init) == INTEGER_CST); ! vf = build_int_cst (unsigned_type_node, vectorization_factor); ! if (vect_debug_details (NULL)) { ! fprintf (dump_file, "int vf = %d",vectorization_factor); ! fprintf (dump_file, ", vf:"); ! print_generic_expr (dump_file, vf, TDF_SLIM); ! fprintf (dump_file, ", init:"); ! print_generic_expr (dump_file, init, TDF_SLIM); ! fprintf (dump_file, ", array_first_index:"); ! print_generic_expr (dump_file, array_first_index, TDF_SLIM); ! } ! /* Calculate the 'init' of the new index. ! init = (init - array_first_index) / vectorization_factor */ ! init = int_const_binop (TRUNC_DIV_EXPR, ! int_const_binop (MINUS_EXPR, init, array_first_index, 1), ! vf, 1); ! /* Calculate the 'step' of the new index. FORNOW: always 1. */ ! step = size_one_node; ! if (vect_debug_details (NULL)) { ! fprintf (dump_file, "create iv for ("); ! print_generic_expr (dump_file, init, TDF_SLIM); ! fprintf (dump_file, ", + ,"); ! print_generic_expr (dump_file, step, TDF_SLIM); ! fprintf (dump_file, ")"); } ! create_iv (init, step, NULL_TREE, loop, bsi, false, ! &indx_before_incr, &indx_after_incr); ! return indx_before_incr; } --- 521,687 ---- } ! /* Function vect_create_index_for_vector_ref. ! Create (and return) an index variable, along with it's update chain in the loop. This variable will be used to access a memory location in a vector operation. ! Input: ! LOOP: The loop being vectorized. BSI: The block_stmt_iterator where STMT is. Any new stmts created by this function can be added here, or in the loop pre-header. + Output: + Return an index that will be used to index a vector array. It is expected + that a pointer to the first vector will be used as the base address for the + indexed reference. + + FORNOW: we are not trying to be efficient, just creating a new index each + time from scratch. At this time all vector references could use the same + index. + + TODO: create only one index to be used by all vector references. Record + the index in the LOOP_VINFO the first time this procedure is called and + return it on subsequent calls. The increment of this index must be placed + just before the conditional expression that ends the single block loop. */ + + static tree + vect_create_index_for_vector_ref (struct loop *loop, block_stmt_iterator *bsi) + { + tree init, step; + tree indx_before_incr, indx_after_incr; + + /* It is assumed that the base pointer used for vectorized access contains + the address of the first vector. Therefore the index used for vectorized + access must be initialized to zero and incremented by 1. */ + + init = integer_zero_node; + step = integer_one_node; + + /* NOTE: assuming that bsi_insert is used with BSI_NEW_STMT */ + create_iv (init, step, NULL_TREE, loop, bsi, false, + &indx_before_incr, &indx_after_incr); + + return indx_before_incr; + } + + /* Function vect_create_addr_base_for_vector_ref. + + Create an expression that computes the address of the first memory location + that will be accessed for a data reference. + + Input: + STMT: The statement containing the data reference. + NEW_STMT_LIST: Must be initialized to NULL_TREE or a + statement list. + + Output: + 1. Return an SSA_NAME whose value is the address of the memory location of + the first vector of the data reference. + 2. If new_stmt_list is not NULL_TREE after return then the caller must insert + these statement(s) which define the returned SSA_NAME. + FORNOW: We are only handling array accesses with step 1. */ static tree ! vect_create_addr_base_for_vector_ref (tree stmt, tree *new_stmt_list, ! tree offset) ! { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); struct loop *loop = STMT_VINFO_LOOP (stmt_info); struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); ! tree base_name = unshare_expr (DR_BASE_NAME (dr)); ! tree data_ref_base = base_name; ! tree ref = DR_REF (dr); ! tree data_ref_base_type = TREE_TYPE (data_ref_base); ! tree scalar_type = TREE_TYPE (ref); ! tree scalar_ptr_type = build_pointer_type (scalar_type); tree access_fn; ! tree init_val, step; bool ok; ! bool is_ptr_ref, is_array_ref; ! tree array_base; ! tree vec_stmt; ! tree new_temp; ! tree array_ref; ! tree addr_base, addr_expr; ! ! /* Only the access function of the last index is relevant (i_n in ! a[i_1][i_2]...[i_n]), the others correspond to loop invariants. */ ! access_fn = DR_ACCESS_FN (dr, 0); ! ok = vect_is_simple_iv_evolution (loop->num, access_fn, &init_val, &step, ! true); ! gcc_assert (ok); ! /* FORNOW: Handling only constant 'init' that can be held in a ! signed HOST_WIDE_INT. */ ! gcc_assert (init_val); ! gcc_assert (host_integerp (init_val, 0)); ! is_ptr_ref = TREE_CODE (data_ref_base_type) == POINTER_TYPE ! && TREE_CODE (data_ref_base) == SSA_NAME; ! is_array_ref = TREE_CODE (data_ref_base_type) == ARRAY_TYPE ! && (TREE_CODE (data_ref_base) == VAR_DECL ! || TREE_CODE (data_ref_base) == COMPONENT_REF ! || TREE_CODE (data_ref_base) == ARRAY_REF); ! gcc_assert (is_ptr_ref || is_array_ref); ! /** Create: &(base[init_val+offset]) ! if data_ref_base is an ARRAY_TYPE: ! base = data_ref_base ! if data_ref_base is the SSA_NAME of a POINTER_TYPE: ! base = *((scalar_array *) data_ref_base) ! **/ ! ! if (is_array_ref) ! array_base = data_ref_base; ! else /* is_ptr_ref */ { ! /* array_ptr = (scalar_array_ptr_type *) data_ref_base; */ ! tree scalar_array_type = build_array_type (scalar_type, 0); ! tree scalar_array_ptr_type = build_pointer_type (scalar_array_type); ! tree array_ptr = create_tmp_var (scalar_array_ptr_type, "array_ptr"); ! add_referenced_tmp_var (array_ptr); ! vec_stmt = fold_convert (scalar_array_ptr_type, data_ref_base); ! vec_stmt = build2 (MODIFY_EXPR, void_type_node, array_ptr, vec_stmt); ! new_temp = make_ssa_name (array_ptr, vec_stmt); ! TREE_OPERAND (vec_stmt, 0) = new_temp; ! append_to_statement_list_force (vec_stmt, new_stmt_list); ! /* (*array_ptr) */ ! array_base = build_fold_indirect_ref (new_temp); ! } ! if (offset) { ! tree tmp = create_tmp_var (TREE_TYPE (init_val), "offset"); ! add_referenced_tmp_var (tmp); ! vec_stmt = build2 (PLUS_EXPR, TREE_TYPE (init_val), init_val, offset); ! vec_stmt = build2 (MODIFY_EXPR, TREE_TYPE (init_val), tmp, vec_stmt); ! init_val = make_ssa_name (tmp, vec_stmt); ! TREE_OPERAND (vec_stmt, 0) = init_val; ! append_to_statement_list_force (vec_stmt, new_stmt_list); } ! array_ref = build4 (ARRAY_REF, scalar_type, array_base, init_val, ! NULL_TREE, NULL_TREE); ! addr_base = build_fold_addr_expr (array_ref); ! /* addr_expr = addr_base */ ! addr_expr = vect_get_new_vect_var (scalar_ptr_type, vect_pointer_var, ! get_name (base_name)); ! add_referenced_tmp_var (addr_expr); ! vec_stmt = build2 (MODIFY_EXPR, void_type_node, addr_expr, addr_base); ! new_temp = make_ssa_name (addr_expr, vec_stmt); ! TREE_OPERAND (vec_stmt, 0) = new_temp; ! append_to_statement_list_force (vec_stmt, new_stmt_list); ! ! return new_temp; } *************** vect_align_data_ref (tree stmt) *** 633,772 **** } ! /* Function vect_create_data_ref. Create a memory reference expression for vector access, to be used in a ! vector load/store stmt. Input: ! STMT: a stmt that references memory. expected to be of the form ! MODIFY_EXPR or MODIFY_EXPR . ! BSI: block_stmt_iterator where new stmts can be added. Output: ! 1. Declare a new ptr to vector_type, and have it point to the array base. ! For example, for vector of type V8HI: ! v8hi *p0; ! p0 = (v8hi *)&a; ! 2. Create a data-reference based on the new vector pointer p0, and using ! a new index variable 'idx'. Return the expression '(*p0)[idx]'. ! FORNOW: handle only aligned and consecutive accesses. */ static tree ! vect_create_data_ref (tree stmt, block_stmt_iterator *bsi) { ! tree new_base; ! tree data_ref; ! tree idx; ! tree vec_stmt; ! tree new_temp; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); tree vectype = STMT_VINFO_VECTYPE (stmt_info); tree vect_ptr_type; tree vect_ptr; - tree addr_ref; - struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); - tree array_type; - tree base_addr = NULL_TREE; - struct loop *loop = STMT_VINFO_LOOP (stmt_info); - edge pe; tree tag; ! tree addr_expr; ! tree scalar_ptr_type; ! tree use; ! ssa_op_iter iter; ! ! /* FORNOW: make sure the data reference is aligned. */ ! vect_align_data_ref (stmt); ! ! addr_ref = DR_BASE_NAME (dr); ! ! array_type = build_array_type (vectype, 0); ! TYPE_ALIGN (array_type) = TYPE_ALIGN (TREE_TYPE (addr_ref)); ! vect_ptr_type = build_pointer_type (array_type); ! scalar_ptr_type = build_pointer_type (TREE_TYPE (addr_ref)); if (vect_debug_details (NULL)) { fprintf (dump_file, "create array_ref of type: "); print_generic_expr (dump_file, vectype, TDF_SLIM); ! } ! ! /*** create: vectype_array *p; ***/ ! vect_ptr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var, ! get_name (addr_ref)); add_referenced_tmp_var (vect_ptr); ! gcc_assert (TREE_CODE (addr_ref) == VAR_DECL ! || TREE_CODE (addr_ref) == COMPONENT_REF ! || TREE_CODE (addr_ref) == SSA_NAME); ! ! if (vect_debug_details (NULL)) ! { ! if (TREE_CODE (addr_ref) == VAR_DECL) ! fprintf (dump_file, "vectorizing an array ref: "); ! else if (TREE_CODE (addr_ref) == SSA_NAME) ! fprintf (dump_file, "vectorizing a pointer ref: "); ! else if (TREE_CODE (addr_ref) == COMPONENT_REF) ! fprintf (dump_file, "vectorizing a record ref: "); ! print_generic_expr (dump_file, addr_ref, TDF_SLIM); ! } ! ! /* Get base address: */ ! if (TREE_CODE (addr_ref) == SSA_NAME) ! base_addr = addr_ref; ! else ! base_addr = build_fold_addr_expr (addr_ref); ! ! /* Handle aliasing: */ tag = STMT_VINFO_MEMTAG (stmt_info); gcc_assert (tag); get_var_ann (vect_ptr)->type_mem_tag = tag; /* Mark for renaming all aliased variables ! (i.e, the may-aliases of the type-mem-tag) */ ! FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, ! (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)) { if (TREE_CODE (use) == SSA_NAME) bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (use))->uid); } - pe = loop_preheader_edge (loop); ! /*** create: p = (vectype *)&a; ***/ ! /* addr_expr = &a */ ! addr_expr = vect_get_new_vect_var (scalar_ptr_type, vect_pointer_var, ! get_name (addr_ref)); ! add_referenced_tmp_var (addr_expr); ! vec_stmt = build2 (MODIFY_EXPR, void_type_node, addr_expr, base_addr); ! new_temp = make_ssa_name (addr_expr, vec_stmt); ! TREE_OPERAND (vec_stmt, 0) = new_temp; ! bsi_insert_on_edge (pe, vec_stmt); ! /* vect_ptr = (vectype_array *)&a; */ ! vec_stmt = fold_convert (vect_ptr_type, new_temp); vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt); new_temp = make_ssa_name (vect_ptr, vec_stmt); TREE_OPERAND (vec_stmt, 0) = new_temp; ! bsi_insert_on_edge (pe, vec_stmt); ! ! /*** create data ref: '(*p)[idx]' ***/ ! ! idx = vect_create_index_for_array_ref (stmt, bsi); ! ! new_base = build_fold_indirect_ref (new_temp); ! data_ref = build4 (ARRAY_REF, vectype, new_base, idx, NULL_TREE, NULL_TREE); ! if (vect_debug_details (NULL)) ! { ! fprintf (dump_file, "created new data-ref: "); ! print_generic_expr (dump_file, data_ref, TDF_SLIM); ! } ! return data_ref; } --- 727,909 ---- } ! /* Function vect_create_data_ref_ptr. Create a memory reference expression for vector access, to be used in a ! vector load/store stmt. The reference is based on a new pointer to vector ! type (vp). Input: ! 1. STMT: a stmt that references memory. Expected to be of the form ! MODIFY_EXPR or MODIFY_EXPR . ! 2. BSI: block_stmt_iterator where new stmts can be added. ! 3. OFFSET (optional): an offset to be added to the initial address accessed ! by the data-ref in STMT. ! 4. ONLY_INIT: indicate if vp is to be updated in the loop, or remain ! pointing to the initial address. Output: ! 1. Declare a new ptr to vector_type, and have it point to the base of the ! data reference (initial addressed accessed by the data reference). ! For example, for vector of type V8HI, the following code is generated: ! v8hi *vp; ! vp = (v8hi *)initial_address; ! ! if OFFSET is not supplied: ! initial_address = &a[init]; ! if OFFSET is supplied: ! initial_address = &a[init + OFFSET]; ! ! Return the initial_address in INITIAL_ADDRESS. ! ! 2. Create a data-reference in the loop based on the new vector pointer vp, ! and using a new index variable 'idx' as follows: ! ! vp' = vp + update ! ! where if ONLY_INIT is true: ! update = zero ! and otherwise ! update = idx + vector_type_size ! ! Return the pointer vp'. ! + FORNOW: handle only aligned and consecutive accesses. */ + static tree ! vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset, ! tree *initial_address, bool only_init) { ! tree base_name; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); + struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); + struct loop *loop = STMT_VINFO_LOOP (stmt_info); tree vectype = STMT_VINFO_VECTYPE (stmt_info); tree vect_ptr_type; tree vect_ptr; tree tag; ! v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt); ! v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt); ! vuse_optype vuses = STMT_VUSE_OPS (stmt); ! int nvuses, nv_may_defs, nv_must_defs; ! int i; ! tree new_temp; ! tree vec_stmt; ! tree new_stmt_list = NULL_TREE; ! tree idx; ! edge pe = loop_preheader_edge (loop); ! basic_block new_bb; ! tree vect_ptr_init; ! tree vectype_size; ! tree ptr_update; ! tree data_ref_ptr; + base_name = unshare_expr (DR_BASE_NAME (dr)); if (vect_debug_details (NULL)) { + tree data_ref_base = base_name; fprintf (dump_file, "create array_ref of type: "); print_generic_expr (dump_file, vectype, TDF_SLIM); ! if (TREE_CODE (data_ref_base) == VAR_DECL) ! fprintf (dump_file, "vectorizing a one dimensional array ref: "); ! else if (TREE_CODE (data_ref_base) == ARRAY_REF) ! fprintf (dump_file, "vectorizing a multidimensional array ref: "); ! else if (TREE_CODE (data_ref_base) == COMPONENT_REF) ! fprintf (dump_file, "vectorizing a record based array ref: "); ! else if (TREE_CODE (data_ref_base) == SSA_NAME) ! fprintf (dump_file, "vectorizing a pointer ref: "); ! print_generic_expr (dump_file, base_name, TDF_SLIM); ! } ! ! /** (1) Create the new vector-pointer variable: **/ ! ! vect_ptr_type = build_pointer_type (vectype); ! vect_ptr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var, ! get_name (base_name)); add_referenced_tmp_var (vect_ptr); ! ! /** (2) Handle aliasing information of the new vector-pointer: **/ ! tag = STMT_VINFO_MEMTAG (stmt_info); gcc_assert (tag); get_var_ann (vect_ptr)->type_mem_tag = tag; /* Mark for renaming all aliased variables ! (i.e, the may-aliases of the type-mem-tag). */ ! nvuses = NUM_VUSES (vuses); ! nv_may_defs = NUM_V_MAY_DEFS (v_may_defs); ! nv_must_defs = NUM_V_MUST_DEFS (v_must_defs); ! for (i = 0; i < nvuses; i++) { + tree use = VUSE_OP (vuses, i); if (TREE_CODE (use) == SSA_NAME) bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (use))->uid); } + for (i = 0; i < nv_may_defs; i++) + { + tree def = V_MAY_DEF_RESULT (v_may_defs, i); + if (TREE_CODE (def) == SSA_NAME) + bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid); + } + for (i = 0; i < nv_must_defs; i++) + { + tree def = V_MUST_DEF_OP (v_must_defs, i); + if (TREE_CODE (def) == SSA_NAME) + bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid); + } ! /** (3) Calculate the initial address the vector-pointer, and set ! the vector-pointer to point to it before the loop: **/ ! /* Create: (&(base[init_val+offset]) in the loop preheader. */ ! new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list, ! offset); ! pe = loop_preheader_edge (loop); ! new_bb = bsi_insert_on_edge_immediate (pe, new_stmt_list); ! gcc_assert (!new_bb); ! *initial_address = new_temp; ! /* Create: p = (vectype *) initial_base */ ! vec_stmt = fold_convert (vect_ptr_type, new_temp); vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt); new_temp = make_ssa_name (vect_ptr, vec_stmt); TREE_OPERAND (vec_stmt, 0) = new_temp; ! new_bb = bsi_insert_on_edge_immediate (pe, vec_stmt); ! gcc_assert (!new_bb); ! vect_ptr_init = TREE_OPERAND (vec_stmt, 0); ! ! ! /** (4) Handle the updating of the vector-pointer inside the loop: **/ ! ! if (only_init) /* No update in loop is required. */ ! return vect_ptr_init; ! ! idx = vect_create_index_for_vector_ref (loop, bsi); ! ! /* Create: update = idx * vectype_size */ ! ptr_update = create_tmp_var (integer_type_node, "update"); ! add_referenced_tmp_var (ptr_update); ! vectype_size = build_int_cst (integer_type_node, ! GET_MODE_SIZE (TYPE_MODE (vectype))); ! vec_stmt = build2 (MULT_EXPR, integer_type_node, idx, vectype_size); ! vec_stmt = build2 (MODIFY_EXPR, void_type_node, ptr_update, vec_stmt); ! new_temp = make_ssa_name (ptr_update, vec_stmt); ! TREE_OPERAND (vec_stmt, 0) = new_temp; ! bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT); ! /* Create: data_ref_ptr = vect_ptr_init + update */ ! vec_stmt = build2 (PLUS_EXPR, vect_ptr_type, vect_ptr_init, new_temp); ! vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt); ! new_temp = make_ssa_name (vect_ptr, vec_stmt); ! TREE_OPERAND (vec_stmt, 0) = new_temp; ! bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT); ! data_ref_ptr = TREE_OPERAND (vec_stmt, 0); ! return data_ref_ptr; } *************** vect_init_vector (tree stmt, tree vector *** 809,814 **** --- 946,952 ---- tree vec_oprnd; edge pe; tree new_temp; + basic_block new_bb; new_var = vect_get_new_vect_var (vectype, vect_simple_var, "cst_"); add_referenced_tmp_var (new_var); *************** vect_init_vector (tree stmt, tree vector *** 818,824 **** TREE_OPERAND (init_stmt, 0) = new_temp; pe = loop_preheader_edge (loop); ! bsi_insert_on_edge (pe, init_stmt); if (vect_debug_details (NULL)) { --- 956,963 ---- TREE_OPERAND (init_stmt, 0) = new_temp; pe = loop_preheader_edge (loop); ! new_bb = bsi_insert_on_edge_immediate (pe, init_stmt); ! gcc_assert (!new_bb); if (vect_debug_details (NULL)) { *************** vect_finish_stmt_generation (tree stmt, *** 986,993 **** /* Make sure bsi points to the stmt that is being vectorized. */ ! /* Assumption: any stmts created for the vectorization of smtmt S are ! inserted before S. BSI may point to S or some new stmt before it. */ while (stmt != bsi_stmt (*bsi) && !bsi_end_p (*bsi)) bsi_next (bsi); --- 1125,1132 ---- /* Make sure bsi points to the stmt that is being vectorized. */ ! /* Assumption: any stmts created for the vectorization of stmt S were ! inserted before S. BSI is expected to point to S or some new stmt before S. */ while (stmt != bsi_stmt (*bsi) && !bsi_end_p (*bsi)) bsi_next (bsi); *************** vectorizable_store (tree stmt, block_stm *** 1190,1195 **** --- 1329,1335 ---- tree vectype = STMT_VINFO_VECTYPE (stmt_info); struct loop *loop = STMT_VINFO_LOOP (stmt_info); enum machine_mode vec_mode; + tree dummy; /* Is vectorizable store? */ *************** vectorizable_store (tree stmt, block_stm *** 1218,1223 **** --- 1358,1366 ---- if (!STMT_VINFO_DATA_REF (stmt_info)) return false; + if (!aligned_access_p (STMT_VINFO_DATA_REF (stmt_info))) + return false; + if (!vec_stmt) /* transformation not required. */ { STMT_VINFO_TYPE (stmt_info) = store_vec_info_type; *************** vectorizable_store (tree stmt, block_stm *** 1233,1239 **** vec_oprnd1 = vect_get_vec_def_for_operand (op, stmt); /* Handle def. */ ! data_ref = vect_create_data_ref (stmt, bsi); /* Arguments are ready. create the new vector stmt. */ *vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1); --- 1376,1385 ---- vec_oprnd1 = vect_get_vec_def_for_operand (op, stmt); /* Handle def. */ ! /* FORNOW: make sure the data reference is aligned. */ ! vect_align_data_ref (stmt); ! data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy, false); ! data_ref = build_fold_indirect_ref (data_ref); /* Arguments are ready. create the new vector stmt. */ *vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1); *************** vectorizable_load (tree stmt, block_stmt *** 1259,1267 **** tree data_ref = NULL; tree op; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); tree vectype = STMT_VINFO_VECTYPE (stmt_info); tree new_temp; ! enum machine_mode vec_mode; /* Is vectorizable load? */ --- 1405,1421 ---- tree data_ref = NULL; tree op; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); + struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info); tree vectype = STMT_VINFO_VECTYPE (stmt_info); tree new_temp; ! int mode; ! tree init_addr; ! tree new_stmt; ! tree dummy; ! basic_block new_bb; ! struct loop *loop = STMT_VINFO_LOOP (stmt_info); ! edge pe = loop_preheader_edge (loop); ! bool software_pipeline_loads_p = false; /* Is vectorizable load? */ *************** vectorizable_load (tree stmt, block_stmt *** 1279,1289 **** if (!STMT_VINFO_DATA_REF (stmt_info)) return false; ! vec_mode = TYPE_MODE (vectype); ! /* FORNOW. In some cases can vectorize even if data-type not supported ! (e.g. - data copies). */ ! if (mov_optab->handlers[(int)vec_mode].insn_code == CODE_FOR_nothing) ! return false; if (!vec_stmt) /* transformation not required. */ { --- 1433,1465 ---- if (!STMT_VINFO_DATA_REF (stmt_info)) return false; ! mode = (int) TYPE_MODE (vectype); ! ! if (aligned_access_p (dr)) ! { ! /* FORNOW. In some cases can vectorize even if data-type not supported ! (e.g. - data copies). */ ! if (mov_optab->handlers[mode].insn_code == CODE_FOR_nothing) ! { ! if (vect_debug_details (loop)) ! fprintf (dump_file, "Aligned load, but unsupported type."); ! return false; ! } ! } ! else /* possibly unaligned access */ ! { ! if (vec_realign_load_optab->handlers[mode].insn_code != CODE_FOR_nothing ! && addr_floor_optab->handlers[mode].insn_code != CODE_FOR_nothing) ! software_pipeline_loads_p = true; ! else if (addr_misaligned_optab->handlers[mode].insn_code == ! CODE_FOR_nothing) ! { ! /* Possibly unaligned access, and can't sofware pipeline the loads */ ! if (vect_debug_details (loop)) ! fprintf (dump_file, "Arbitrary load not supported."); ! return false; ! } ! } if (!vec_stmt) /* transformation not required. */ { *************** vectorizable_load (tree stmt, block_stmt *** 1296,1314 **** if (vect_debug_details (NULL)) fprintf (dump_file, "transform load."); ! /* Handle def. */ ! vec_dest = vect_create_destination_var (scalar_dest, vectype); ! /* Handle use. */ ! op = TREE_OPERAND (stmt, 1); ! data_ref = vect_create_data_ref (stmt, bsi); ! /* Arguments are ready. create the new vector stmt. */ ! *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref); ! new_temp = make_ssa_name (vec_dest, *vec_stmt); ! TREE_OPERAND (*vec_stmt, 0) = new_temp; ! vect_finish_stmt_generation (stmt, *vec_stmt, bsi); return true; } --- 1472,1594 ---- if (vect_debug_details (NULL)) fprintf (dump_file, "transform load."); ! if (!software_pipeline_loads_p) ! { ! /* Create: ! p = initial_addr; ! indx = 0; ! loop { ! vec_dest = *(p); ! indx = indx + 1; ! } ! */ ! ! vec_dest = vect_create_destination_var (scalar_dest, vectype); ! data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy, false); ! if (aligned_access_p (dr)) ! data_ref = build_fold_indirect_ref (data_ref); ! else ! { ! tree mis = build_int_cst (integer_type_node, DR_MISALIGNMENT (dr)); ! data_ref = build2 (MISALIGNED_INDIRECT_REF, vectype, data_ref, mis); ! } ! new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref); ! new_temp = make_ssa_name (vec_dest, new_stmt); ! TREE_OPERAND (new_stmt, 0) = new_temp; ! vect_finish_stmt_generation (stmt, new_stmt, bsi); ! } ! else /* software-pipeline the loads */ ! { ! /* Create: ! p1 = initial_addr; ! msq_init = *(floor(p1)) ! p2 = initial_addr + VS - 1; ! magic = have_builtin ? builtin_result : initial_address; ! indx = 0; ! loop { ! p2' = p2 + indx * vectype_size ! lsq = *(floor(p2')) ! vec_dest = realign_load (msq, lsq, magic) ! indx = indx + 1; ! msq = lsq; ! } ! */ ! tree offset; ! tree magic; ! tree phi_stmt; ! tree msq_init; ! tree msq, lsq; ! tree dataref_ptr; ! #ifdef BUILT_IN_build_mask_for_load ! tree params; ! #endif ! /* <1> Create msq_init = *(floor(p1)) in the loop preheader */ ! vec_dest = vect_create_destination_var (scalar_dest, vectype); ! data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, ! &init_addr, true); ! data_ref = build1 (ALIGN_INDIRECT_REF, vectype, data_ref); ! new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref); ! new_temp = make_ssa_name (vec_dest, new_stmt); ! TREE_OPERAND (new_stmt, 0) = new_temp; ! new_bb = bsi_insert_on_edge_immediate (pe, new_stmt); ! gcc_assert (!new_bb); ! msq_init = TREE_OPERAND (new_stmt, 0); ! ! ! /* <2> Create lsq = *(floor(p2')) in the loop */ ! offset = build_int_cst (integer_type_node, ! GET_MODE_NUNITS (TYPE_MODE (vectype))); ! offset = int_const_binop (MINUS_EXPR, offset, integer_one_node, 1); ! vec_dest = vect_create_destination_var (scalar_dest, vectype); ! dataref_ptr = vect_create_data_ref_ptr (stmt, bsi, offset, &dummy, false); ! data_ref = build1 (ALIGN_INDIRECT_REF, vectype, dataref_ptr); ! new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref); ! new_temp = make_ssa_name (vec_dest, new_stmt); ! TREE_OPERAND (new_stmt, 0) = new_temp; ! vect_finish_stmt_generation (stmt, new_stmt, bsi); ! lsq = TREE_OPERAND (new_stmt, 0); ! ! ! /* <3> */ ! #ifdef BUILT_IN_build_mask_for_load ! /* Create permutation mask, if required, in loop preheader. */ ! params = build_tree_list (NULL_TREE, init_addr); ! vec_dest = vect_create_destination_var (scalar_dest, vectype); ! new_stmt = build_function_call_expr ( ! built_in_decls[BUILT_IN_build_mask_for_load], params); ! new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, new_stmt); ! new_temp = make_ssa_name (vec_dest, new_stmt); ! TREE_OPERAND (new_stmt, 0) = new_temp; ! new_bb = bsi_insert_on_edge_immediate (pe, new_stmt); ! gcc_assert (!new_bb); ! magic = TREE_OPERAND (new_stmt, 0); ! #else ! /* Use current address instead of init_addr for reduced reg pressure. */ ! magic = dataref_ptr; ! #endif /* BUILT_IN_build_mask_for_load */ ! ! ! /* <4> Create msq = phi in loop */ ! vec_dest = vect_create_destination_var (scalar_dest, vectype); ! msq = make_ssa_name (vec_dest, NULL_TREE); ! phi_stmt = create_phi_node (msq, loop->header); ! SSA_NAME_DEF_STMT (msq) = phi_stmt; ! add_phi_arg (&phi_stmt, msq_init, loop_preheader_edge (loop)); ! add_phi_arg (&phi_stmt, lsq, loop_latch_edge (loop)); ! ! ! /* <5> Create in loop */ ! vec_dest = vect_create_destination_var (scalar_dest, vectype); ! new_stmt = build3 (REALIGN_LOAD_EXPR, vectype, msq, lsq, magic); ! new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, new_stmt); ! new_temp = make_ssa_name (vec_dest, new_stmt); ! TREE_OPERAND (new_stmt, 0) = new_temp; ! vect_finish_stmt_generation (stmt, new_stmt, bsi); ! } + *vec_stmt = new_stmt; return true; } *************** vect_compute_data_ref_alignment (struct *** 2123,2129 **** tree init; tree scalar_type; tree misalign; ! tree array_first_index; tree array_base = DR_BASE_NAME (dr); tree base_decl = NULL_TREE; tree bit_offset = size_zero_node; --- 2403,2409 ---- tree init; tree scalar_type; tree misalign; ! tree array_first_index = NULL_TREE; tree array_base = DR_BASE_NAME (dr); tree base_decl = NULL_TREE; tree bit_offset = size_zero_node; *************** vect_compute_data_refs_alignment (loop_v *** 2321,2327 **** FOR NOW: No transformation is actually performed. TODO. */ static void ! vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo ATTRIBUTE_UNUSED) { /* This pass will require a cost model to guide it whether to apply peeling --- 2601,2607 ---- FOR NOW: No transformation is actually performed. TODO. */ static void ! vect_enhance_data_refs_alignment (loop_vec_info loop_info ATTRIBUTE_UNUSED) { /* This pass will require a cost model to guide it whether to apply peeling *************** static bool *** 2419,2425 **** vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo) { varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo); ! varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo); unsigned int i; if (vect_debug_details (NULL)) --- 2699,2706 ---- vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo) { varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo); ! /*varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);*/ ! unsigned int i; if (vect_debug_details (NULL)) *************** vect_analyze_data_refs_alignment (loop_v *** 2459,2464 **** --- 2740,2750 ---- } } + /* The vectorizer now supports misaligned loads, so we don't fail anymore + in the presence of a misaligned read dataref. For some targets however + it may be preferable not to vectorize in such a case as misaligned + accesses are very costly. This should be considered in the future. */ + /* for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++) { struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i); *************** vect_analyze_data_refs_alignment (loop_v *** 2470,2475 **** --- 2756,2762 ---- return false; } } + */ return true; } *************** vect_analyze_data_ref_access (struct dat *** 2508,2513 **** --- 2795,2810 ---- return false; } + if (!init || !host_integerp (init, 0)) + { + if (vect_debug_details (NULL)) + { + fprintf (dump_file, "non constant init for access function."); + print_generic_expr (dump_file, access_fn, TDF_SLIM); + } + return false; + } + return true; } *************** vectorize_loops (struct loops *loops) *** 3407,3413 **** loop->aux = NULL; } - loop_commit_inserts (); rewrite_into_ssa (false); if (bitmap_first_set_bit (vars_to_rename) >= 0) { --- 3704,3709 ---- Index: tree.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree.c,v retrieving revision 1.426 diff -c -3 -p -r1.426 tree.c *** tree.c 11 Sep 2004 21:14:38 -0000 1.426 --- tree.c 14 Sep 2004 16:43:14 -0000 *************** staticp (tree arg) *** 1463,1468 **** --- 1463,1470 ---- case BIT_FIELD_REF: return NULL; + case MISALIGNED_INDIRECT_REF: + case ALIGN_INDIRECT_REF: case INDIRECT_REF: return TREE_CONSTANT (TREE_OPERAND (arg, 0)) ? arg : NULL; *************** build1_stat (enum tree_code code, tree t *** 2447,2452 **** --- 2449,2456 ---- TREE_READONLY (t) = 0; break; + case MISALIGNED_INDIRECT_REF: + case ALIGN_INDIRECT_REF: case INDIRECT_REF: /* Whether a dereference is readonly has nothing to do with whether its operand is readonly. */ Index: tree.def =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree.def,v retrieving revision 1.98 diff -c -3 -p -r1.98 tree.def *** tree.def 19 Aug 2004 10:35:56 -0000 1.98 --- tree.def 14 Sep 2004 16:43:14 -0000 *************** DEFTREECODE (BIT_FIELD_REF, "bit_field_r *** 376,381 **** --- 376,392 ---- /* C unary `*' or Pascal `^'. One operand, an expression for a pointer. */ DEFTREECODE (INDIRECT_REF, "indirect_ref", 'r', 1) + /* Like above, but aligns the referenced address (i.e, if the address + in P is not aligned on TYPE_ALIGN boundary, then &(*P) != P). */ + DEFTREECODE (ALIGN_INDIRECT_REF, "align_indirect_ref", 'r', 1) + + /* Same as INDIRECT_REF, but also specifies the alignment of the referenced + address: + Operand 0 is the referenced address (a pointer); + Operand 1 is an INTEGER_CST which represents the alignment of the address, + or -1 if the alignment is unknown. */ + DEFTREECODE (MISALIGNED_INDIRECT_REF, "misaligned_indirect_ref", 'r', 2) + /* Array indexing. Operand 0 is the array; operand 1 is a (single) array index. Operand 2, if present, is a copy of TYPE_MIN_VALUE of the index. *************** DEFTREECODE (TREE_BINFO, "tree_binfo", ' *** 884,889 **** --- 895,916 ---- Operand 1 is the size of the type in the expression. */ DEFTREECODE (WITH_SIZE_EXPR, "with_size_expr", 'e', 2) + /* Extract elements from two input vectors Operand 0 and Operand 1 of size VS, + according to an offset OFF as follows: the last VS - OFF elements of + vector Operand0 are concatenated to the first OFF elements of vector + Operand1. If OFF==0, then the returned vector is Opernad1. + OP2 may take different forms; It can be an address, in which case and its + low log2(VS)-1 bits define the offset, or it can be mask of some form. */ + DEFTREECODE (REALIGN_LOAD_EXPR, "realign_load", 'e', 3) + + /* Extract elements from two input vectors Operand 0 and Operand 1 of size VS, + according to an offset OFF as follows: the last OFF elements of + vector Operand0 are concatenated to the first VS - OFF elements of vector + Operand1. If OFF==0, then the returned vector is Opernad1. + OP2 may take different forms; It can be an address, in which case and its + low log2(VS)-1 bits define the offset, or it can be mask of some form. */ + DEFTREECODE (REALIGN_STORE_EXPR, "realign_store", 'e', 3) + /* Local variables: mode:c Index: tree.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree.h,v retrieving revision 1.619 diff -c -3 -p -r1.619 tree.h *** tree.h 11 Sep 2004 21:14:39 -0000 1.619 --- tree.h 14 Sep 2004 16:43:15 -0000 *************** struct tree_common GTY(()) *** 312,318 **** ..._TYPE TREE_THIS_NOTRAP in ! INDIRECT_REF, ARRAY_REF, ARRAY_RANGE_REF deprecated_flag: --- 312,318 ---- ..._TYPE TREE_THIS_NOTRAP in ! (ALIGN/MISALIGNED_)INDIRECT_REF, ARRAY_REF, ARRAY_RANGE_REF deprecated_flag: *************** extern void tree_operand_check_failed (i *** 826,832 **** /* Nonzero means this node will not trap. In an INDIRECT_REF, means accessing the memory pointed to won't generate a trap. However, this only applies to an object when used appropriately: it doesn't ! mean that writing a READONLY mem won't trap. In ARRAY_REF and ARRAY_RANGE_REF means that we know that the index (or slice of the array) always belongs to the range of the array. --- 826,833 ---- /* Nonzero means this node will not trap. In an INDIRECT_REF, means accessing the memory pointed to won't generate a trap. However, this only applies to an object when used appropriately: it doesn't ! mean that writing a READONLY mem won't trap. Similarly for ! ALIGN_INDIRECT_REF and MISALIGNED_INDIRECT_REF. In ARRAY_REF and ARRAY_RANGE_REF means that we know that the index (or slice of the array) always belongs to the range of the array. *************** struct tree_vec GTY(()) *** 1069,1076 **** #define TREE_OPERAND(NODE, I) TREE_OPERAND_CHECK (NODE, I) #define TREE_COMPLEXITY(NODE) (EXPR_CHECK (NODE)->exp.complexity) ! /* In INDIRECT_REF. */ ! #define REF_ORIGINAL(NODE) TREE_CHAIN (TREE_CHECK (NODE, INDIRECT_REF)) /* In a LABELED_BLOCK_EXPR node. */ #define LABELED_BLOCK_LABEL(NODE) \ --- 1070,1078 ---- #define TREE_OPERAND(NODE, I) TREE_OPERAND_CHECK (NODE, I) #define TREE_COMPLEXITY(NODE) (EXPR_CHECK (NODE)->exp.complexity) ! /* In INDIRECT_REF, ALIGN_INDIRECT_REF, MISALIGNED_INDIRECT_REF. */ ! #define REF_ORIGINAL(NODE) TREE_CHAIN (TREE_CHECK3 (NODE, \ ! INDIRECT_REF, ALIGN_INDIRECT_REF, MISALIGNED_INDIRECT_REF)) /* In a LABELED_BLOCK_EXPR node. */ #define LABELED_BLOCK_LABEL(NODE) \ Index: config/i386/i386.md =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v retrieving revision 1.559 diff -c -3 -p -r1.559 i386.md *** config/i386/i386.md 11 Sep 2004 19:54:21 -0000 1.559 --- config/i386/i386.md 14 Sep 2004 16:43:20 -0000 *************** *** 24230,24235 **** --- 24230,24245 ---- [(set_attr "type" "ssecvt") (set_attr "mode" "TI")]) + (define_expand "addr_misaligned_v16qi" + [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m") + (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")] + UNSPEC_MOVU))] + "TARGET_SSE2" + { + emit_insn (gen_sse2_movdqu (operands[0], operands[1])); + DONE; + }) + (define_insn "sse2_movdq2q" [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y") (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x") Index: config/rs6000/altivec.md =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/rs6000/altivec.md,v retrieving revision 1.22 diff -c -3 -p -r1.22 altivec.md *** config/rs6000/altivec.md 18 Aug 2004 16:33:02 -0000 1.22 --- config/rs6000/altivec.md 14 Sep 2004 16:43:21 -0000 *************** *** 1902,1907 **** --- 1902,1928 ---- "lvsr %0,%y1" [(set_attr "type" "vecload")]) + (define_expand "build_vector_mask_for_load" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand 1 "memory_operand" "m")] 195))] + "TARGET_ALTIVEC" + " + { + rtx addr; + rtx temp; + + if (GET_CODE (operands[1]) != MEM) + abort (); + + addr = XEXP (operands[1], 0); + temp = gen_reg_rtx (GET_MODE (addr)); + emit_insn (gen_rtx_SET (VOIDmode, temp, + gen_rtx_NEG (GET_MODE (addr), addr))); + emit_insn (gen_altivec_lvsr (operands[0], + gen_rtx_MEM (GET_MODE (operands[1]), temp))); + DONE; + }") + ;; Parallel some of the LVE* and STV*'s with unspecs because some have ;; identical rtl but different instructions-- and gcc gets confused. *************** *** 2062,2064 **** --- 2083,2146 ---- "vspltisb %2,0\;vsubsws %3,%2,%1\;vmaxsw %0,%1,%3" [(set_attr "type" "vecsimple") (set_attr "length" "12")]) + + (define_expand "addr_floor_v4si" + [(set (match_operand 0 "nonimmediate_operand" "") + (match_operand 1 "any_operand" ""))] + "TARGET_ALTIVEC" + "{ rs6000_emit_move (operands[0], operands[1], GET_MODE (operands[1])); DONE; }") + + (define_expand "addr_floor_v8hi" + [(set (match_operand 0 "nonimmediate_operand" "") + (match_operand 1 "any_operand" ""))] + "TARGET_ALTIVEC" + "{ rs6000_emit_move (operands[0], operands[1], GET_MODE (operands[1])); DONE; }") + + (define_expand "addr_floor_v16qi" + [(set (match_operand 0 "nonimmediate_operand" "") + (match_operand 1 "any_operand" ""))] + "TARGET_ALTIVEC" + "{ rs6000_emit_move (operands[0], operands[1], GET_MODE (operands[1])); DONE; }") + + (define_expand "addr_floor_v4sf" + [(set (match_operand 0 "nonimmediate_operand" "") + (match_operand 1 "any_operand" ""))] + "TARGET_ALTIVEC" + "{ rs6000_emit_move (operands[0], operands[1], GET_MODE (operands[1])); DONE; }") + + (define_insn "vec_realign_load_v4si" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v") + (match_operand:V16QI 3 "register_operand" "v")] 215))] + "TARGET_ALTIVEC" + "vperm %0,%1,%2,%3" + [(set_attr "type" "vecperm")]) + + (define_insn "vec_realign_load_v4sf" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v") + (match_operand:V16QI 3 "register_operand" "v")] 216))] + "TARGET_ALTIVEC" + "vperm %0,%1,%2,%3" + [(set_attr "type" "vecperm")]) + + (define_insn "vec_realign_load_v8hi" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v") + (match_operand:V16QI 3 "register_operand" "v")] 217))] + "TARGET_ALTIVEC" + "vperm %0,%1,%2,%3" + [(set_attr "type" "vecperm")]) + + (define_insn "vec_realign_load_v16qi" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v") + (match_operand:V16QI 3 "register_operand" "v")] 218))] + "TARGET_ALTIVEC" + "vperm %0,%1,%2,%3" + [(set_attr "type" "vecperm")]) + Index: testsuite/ChangeLog =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/ChangeLog,v retrieving revision 1.4269 diff -c -3 -p -r1.4269 ChangeLog *** testsuite/ChangeLog 12 Sep 2004 10:33:00 -0000 1.4269 --- testsuite/ChangeLog 14 Sep 2004 16:43:28 -0000 *************** *** 1,3 **** --- 1,18 ---- + 2004-09-13 Dorit Naishlos + + * gcc.dg/vect/vect-72.c: New test. + * gcc.dg/vect/vect-13.c: Now vectorized on ppc*. + * gcc.dg/vect/vect-27.c: Now vectorized on ppc*. + * gcc.dg/vect/vect-48.c: Now vectorized on ppc*. + * gcc.dg/vect/vect-26.c: Use sse2 instead of sse. + * gcc.dg/vect/vect-27.c: Use sse2 instead of sse. + * gcc.dg/vect/vect-28.c: Use sse2 instead of sse. + * gcc.dg/vect/vect-29.c: Use sse2 instead of sse. + * gcc.dg/vect/vect-4?.c: Use sse2 instead of sse. + * gcc.dg/vect/vect-5?.c: Use sse2 instead of sse. + * gcc.dg/vect/vect-60.c: Use sse2 instead of sse. + * gcc.dg/vect/vect-61.c: Use sse2 instead of sse. + 2004-09-11 Steven Bosscher * g++.dg/parse/break-in-for.C: Fix for -ansi -pedantic-errors. Index: testsuite/gcc.dg/vect/vect-13.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-13.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-13.c *** testsuite/gcc.dg/vect/vect-13.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-13.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,14 **** ! /* { dg-do compile { target powerpc*-*-* i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #define N 16 int a[N]; int results[N] = {0,1,2,3,0,0,0,0,0,0,0,0,12,13,14,15}; ! int main () { int i; int b[N] = {0,1,2,3,-4,-5,-6,-7,-8,-9,-10,-11,12,13,14,15}; --- 1,16 ---- ! /* { dg-do run { target powerpc*-*-* i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ + #include + #include "tree-vect.h" #define N 16 int a[N]; int results[N] = {0,1,2,3,0,0,0,0,0,0,0,0,12,13,14,15}; ! int main1() { int i; int b[N] = {0,1,2,3,-4,-5,-6,-7,-8,-9,-10,-11,12,13,14,15}; *************** int main () *** 19,25 **** a[i] = (b[i] >= 0 ? b[i] : 0); } return 0; } ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ --- 21,41 ---- a[i] = (b[i] >= 0 ? b[i] : 0); } + /* Check results */ + for (i = 0; i < N; i++) + { + if (a[i] != results[i]) + abort (); + } + return 0; } ! int main (void) ! { ! check_vect (); ! ! return main1 (); ! } ! ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail i?86-*-* x86_64-*-* } } } */ Index: testsuite/gcc.dg/vect/vect-26.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-26.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-26.c *** testsuite/gcc.dg/vect/vect-26.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-26.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-27.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-27.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-27.c *** testsuite/gcc.dg/vect/vect-27.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-27.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" *************** int main (void) *** 43,47 **** return main1 (); } ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ --- 43,47 ---- return main1 (); } ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail i?86-*-* x86_64-*-* } } } */ Index: testsuite/gcc.dg/vect/vect-28.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-28.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-28.c *** testsuite/gcc.dg/vect/vect-28.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-28.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-29.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-29.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-29.c *** testsuite/gcc.dg/vect/vect-29.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-29.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-40.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-40.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-40.c *** testsuite/gcc.dg/vect/vect-40.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-40.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-41.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-41.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-41.c *** testsuite/gcc.dg/vect/vect-41.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-41.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-42.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-42.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-42.c *** testsuite/gcc.dg/vect/vect-42.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-42.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-43.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-43.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-43.c *** testsuite/gcc.dg/vect/vect-43.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-43.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-44.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-44.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-44.c *** testsuite/gcc.dg/vect/vect-44.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-44.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,13 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" #define N 256 void bar (float *pa, float *pb, float *pc) { --- 1,14 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" #define N 256 + typedef float afloat __attribute__ ((__aligned__(16))); void bar (float *pa, float *pb, float *pc) { *************** main1 (float * __restrict__ pa, float * *** 42,54 **** int main (void) { int i; ! float a[N]; ! float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; ! float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; check_vect (); main1 (a,b,c); return 0; } --- 43,59 ---- int main (void) { int i; ! afloat a[N+4]; ! afloat b[N+4] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69}; ! afloat c[N+4] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}; check_vect (); main1 (a,b,c); + main1 (&a[1],b,c); + main1 (a,&b[1],c); + main1 (&a[1],&b[1],&c[1]); + return 0; } Index: testsuite/gcc.dg/vect/vect-45.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-45.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-45.c *** testsuite/gcc.dg/vect/vect-45.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-45.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-46.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-46.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-46.c *** testsuite/gcc.dg/vect/vect-46.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-46.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-47.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-47.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-47.c *** testsuite/gcc.dg/vect/vect-47.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-47.c 14 Sep 2004 16:43:31 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-48.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-48.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-48.c *** testsuite/gcc.dg/vect/vect-48.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-48.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" *************** main1 (afloat * __restrict__ pa, float * *** 43,56 **** int main (void) { int i; ! float a[N]; ! float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; ! float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; check_vect (); main1 (a,b,c); return 0; } ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ --- 43,58 ---- int main (void) { int i; ! afloat a[N]; ! afloat b[N+1] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60}; ! afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; check_vect (); main1 (a,b,c); + main1 (a,&b[1],c); + return 0; } ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail i?86-*-* x86_64-*-* } } } */ Index: testsuite/gcc.dg/vect/vect-49.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-49.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-49.c *** testsuite/gcc.dg/vect/vect-49.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-49.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-50.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-50.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-50.c *** testsuite/gcc.dg/vect/vect-50.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-50.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-51.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-51.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-51.c *** testsuite/gcc.dg/vect/vect-51.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-51.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-52.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-52.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-52.c *** testsuite/gcc.dg/vect/vect-52.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-52.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-53.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-53.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-53.c *** testsuite/gcc.dg/vect/vect-53.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-53.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-54.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-54.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-54.c *** testsuite/gcc.dg/vect/vect-54.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-54.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-55.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-55.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-55.c *** testsuite/gcc.dg/vect/vect-55.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-55.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-56.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-56.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-56.c *** testsuite/gcc.dg/vect/vect-56.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-56.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-57.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-57.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-57.c *** testsuite/gcc.dg/vect/vect-57.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-57.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-58.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-58.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-58.c *** testsuite/gcc.dg/vect/vect-58.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-58.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-59.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-59.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-59.c *** testsuite/gcc.dg/vect/vect-59.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-59.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-60.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-60.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-60.c *** testsuite/gcc.dg/vect/vect-60.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-60.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" Index: testsuite/gcc.dg/vect/vect-61.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-61.c,v retrieving revision 1.1 diff -c -3 -p -r1.1 vect-61.c *** testsuite/gcc.dg/vect/vect-61.c 17 Aug 2004 16:17:14 -0000 1.1 --- testsuite/gcc.dg/vect/vect-61.c 14 Sep 2004 16:43:32 -0000 *************** *** 1,7 **** /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h" --- 1,7 ---- /* { dg-do run { target powerpc*-*-* } } */ /* { dg-do run { target i?86-*-* x86_64-*-* } } */ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */ ! /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */ #include #include "tree-vect.h"