--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8.3-a+sve2 -fdump-tree-vect-details" } */
+
+#include <stdint.h>
+
+int
+foo (char *buf, uint8_t len)
+{
+ int x = 0;
+
+ for (int16_t i = 0, y = 0; i < len; i++, y = i * 10)
+ x += (int) y * (buf[i] - '0');
+
+ return x;
+}
+
+int
+masked_len_foo (unsigned char *buf, uint16_t len)
+{
+ uint16_t n = len & 255;
+ int x = 0;
+
+ for (int16_t i = 0, y = 0; i < n; i++, y = i * 10)
+ x += (int) y * (buf[i] - '0');
+
+ return x;
+}
+
+int
+guarded_len_foo (char *buf, uint16_t len)
+{
+ if (len > 255)
+ return 0;
+
+ int x = 0;
+
+ for (int16_t i = 0, y = 0; i < len; i++, y = i * 10)
+ x += (int) y * (buf[i] - '0');
+
+ return x;
+}
+
+int
+non_value_preserving (unsigned char *buf, uint8_t len)
+{
+ int x = 0;
+
+ for (int16_t i = 0, y = 0; i < (int) (int8_t) len; i++, y = i * 10)
+ x += (int) y * (buf[i] - '0');
+
+ return x;
+}
+
+unsigned
+niter_convert_range_wrap (unsigned char *buf, uint8_t len)
+{
+ unsigned x = 0;
+
+ for (unsigned i = 0, y = 0; i < (unsigned) len - 1; i++, y = i * 10)
+ x += y * (buf[i] - '0');
+
+ return x;
+}
+
+/* { dg-final { scan-tree-dump-times {bounds on difference of bases: 0 [.][.][.] 126} 3 "vect" } } */
+/* { dg-final { scan-tree-dump-times {bounds on difference of bases: 0 [.][.][.] 254} 9 "vect" } } */
+/* { dg-final { scan-tree-dump-times {bounds on difference of bases: -1 [.][.][.] 4294967294} 3 "vect" } } */
+/* { dg-final { scan-tree-dump-times "loop vectorized using variable length vectors" 5 "vect" } } */
mpz_clear (offc1);
}
-/* Stores estimate on the minimum/maximum value of the expression VAR + OFF
- in TYPE to MIN and MAX. */
+/* Stores estimates of the minimum and maximum values of the expression
+ VAR + OFF in TYPE to MIN and MAX. The estimates are valid on entry
+ to LOOP, i.e. on the loop preheader edge. */
static void
determine_value_range (class loop *loop, tree type, tree var, mpz_t off,
get_type_static_bounds (type, min, max);
/* See if we have some range info from VRP. */
- if (TREE_CODE (var) == SSA_NAME && INTEGRAL_TYPE_P (type))
+ if (INTEGRAL_TYPE_P (type))
{
edge e = loop_preheader_edge (loop);
signop sgn = TYPE_SIGN (type);
/* Either for VAR itself... */
int_range_max var_range (TREE_TYPE (var));
- get_range_query (cfun)->range_of_expr (var_range, var);
+ get_range_query (cfun)->range_on_edge (var_range, e, var);
if (var_range.varying_p () || var_range.undefined_p ())
rtype = VR_VARYING;
else
{
gphi *phi = gsi.phi ();
if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var
- && get_range_query (cfun)->range_of_expr (phi_range,
- gimple_phi_result (phi))
+ && get_range_query (cfun)->range_on_edge (phi_range,
+ e, gimple_phi_result (phi))
&& !phi_range.varying_p ()
&& !phi_range.undefined_p ())
{
if (wi::gt_p (minv, maxv, sgn))
{
int_range_max vr (TREE_TYPE (var));
- get_range_query (cfun)->range_of_expr (vr, var);
+ get_range_query (cfun)->range_on_edge (vr, e, var);
if (vr.varying_p () || vr.undefined_p ())
rtype = VR_VARYING;
else