- /* Determine the address to prefetch. */
- delta = (ahead + ap * ref->prefetch_mod) * ref->group->step;
- addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
- addr_base, size_int (delta));
- addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, NULL,
- true, GSI_SAME_STMT);
-
+ if (cst_and_fits_in_hwi (ref->group->step))
+ {
+ /* Determine the address to prefetch. */
+ delta = (ahead + ap * ref->prefetch_mod) *
+ int_cst_value (ref->group->step);
+ addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
+ addr_base, size_int (delta));
+ addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, NULL,
+ true, GSI_SAME_STMT);
+ }
+ else
+ {
+ /* The step size is non-constant but loop-invariant. We use the
+ heuristic to simply prefetch ahead iterations ahead. */
+ forward = fold_build2 (MULT_EXPR, sizetype,
+ fold_convert (sizetype, ref->group->step),
+ fold_convert (sizetype, size_int (ahead)));
+ addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr_base,
+ forward);
+ addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true,
+ NULL, true, GSI_SAME_STMT);
+ }