/* Induction variable optimizations.
- Copyright (C) 2003-2020 Free Software Foundation, Inc.
+ Copyright (C) 2003-2021 Free Software Foundation, Inc.
This file is part of GCC.
#include "tree-vectorizer.h"
#include "dbgcnt.h"
+/* For lang_hooks.types.type_for_mode. */
+#include "langhooks.h"
+
/* FIXME: Expressions are expanded to RTL in this pass to determine the
cost of different addressing modes. This should be moved to a TBD
interface between the GIMPLE and RTL worlds. */
if (!bb
|| !flow_bb_inside_loop_p (data->current_loop, bb))
- set_iv (data, var, var, build_int_cst (type, 0), true);
+ {
+ if (POINTER_TYPE_P (type))
+ type = sizetype;
+ set_iv (data, var, var, build_int_cst (type, 0), true);
+ }
}
return name_info (data, var)->iv;
{
case IFN_MASK_LOAD:
case IFN_MASK_LOAD_LANES:
+ case IFN_LEN_LOAD:
if (op_p == gimple_call_arg_ptr (call, 0))
return TREE_TYPE (gimple_call_lhs (call));
return NULL_TREE;
case IFN_MASK_STORE:
case IFN_MASK_STORE_LANES:
+ case IFN_LEN_STORE:
if (op_p == gimple_call_arg_ptr (call, 0))
return TREE_TYPE (gimple_call_arg (call, 3));
return NULL_TREE;
list_index = (unsigned) as * MAX_MACHINE_MODE + (unsigned) mem_mode;
if (list_index >= vec_safe_length (addr_list))
- vec_safe_grow_cleared (addr_list, list_index + MAX_MACHINE_MODE);
+ vec_safe_grow_cleared (addr_list, list_index + MAX_MACHINE_MODE, true);
addr = (*addr_list)[list_index];
if (!addr)
if (!bb || !flow_bb_inside_loop_p (idata->current_loop, bb))
{
- set_iv (idata, op, op, build_int_cst (TREE_TYPE (op), 0), true);
+ tree steptype = TREE_TYPE (op);
+ if (POINTER_TYPE_P (steptype))
+ steptype = sizetype;
+ set_iv (idata, op, op, build_int_cst (steptype, 0), true);
record_invariant (idata, op, false);
}
}
{
poly_uint64 offset;
tree base;
- tree basetype;
struct iv *iv = use->iv;
+ tree basetype = TREE_TYPE (iv->base);
+
+ /* Don't add candidate for iv_use with non integer, pointer or non-mode
+ precision types, instead, add candidate for the corresponding scev in
+ unsigned type with the same precision. See PR93674 for more info. */
+ if ((TREE_CODE (basetype) != INTEGER_TYPE && !POINTER_TYPE_P (basetype))
+ || !type_has_mode_precision_p (basetype))
+ {
+ basetype = lang_hooks.types.type_for_mode (TYPE_MODE (basetype),
+ TYPE_UNSIGNED (basetype));
+ add_candidate (data, fold_convert (basetype, iv->base),
+ fold_convert (basetype, iv->step), false, NULL);
+ return;
+ }
add_candidate (data, iv->base, iv->step, false, use);
unsigned nsize = ((unsigned) as + 1) *MAX_MACHINE_MODE;
gcc_assert (nsize > idx);
- ainc_cost_data_list.safe_grow_cleared (nsize);
+ ainc_cost_data_list.safe_grow_cleared (nsize, true);
}
ainc_cost_data *data = ainc_cost_data_list[idx];
case IFN_MASK_STORE:
case IFN_MASK_LOAD_LANES:
case IFN_MASK_STORE_LANES:
+ case IFN_LEN_LOAD:
+ case IFN_LEN_STORE:
/* The second argument contains the correct alias type. */
gcc_assert (use->op_p = gimple_call_arg_ptr (call, 0));
return TREE_TYPE (gimple_call_arg (call, 1));
count++;
if (count > 1)
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
if (!count)
if (!flag_branch_on_count_reg)
return;
+ if (data->current_loop->unroll == USHRT_MAX)
+ return;
+
if (!generic_predict_doloop_p (data))
return;