@@ -1910,8 +1910,20 @@ operator_mult::wi_fold (irange &r, tree type,
// diff = max - min
prod2 = prod3 - prod0;
if (wi::geu_p (prod2, sizem1))
- // The range covers all values.
- r.set_varying (type);
+ {
+ // Multiplying by X, where X is a power of 2 is [0,0][X,+INF].
+ if (TYPE_UNSIGNED (type) && rh_lb == rh_ub
+ && wi::exact_log2 (rh_lb) != -1 && prec > 1)
+ {
+ r.set (type, rh_lb, wi::max_value (prec, sign));
+ int_range<2> zero;
+ zero.set_zero (type);
+ r.union_ (zero);
+ }
+ else
+ // The range covers all values.
+ r.set_varying (type);
+ }
else
{
wide_int new_lb = wide_int::from (prod0, prec, sign);
new file mode 100644
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-evrp" }
+
+void gg(void);
+int f(unsigned t)
+{
+ unsigned g = t*16;
+ if (g==0) return 1;
+ gg();
+ gg();
+ gg();
+ gg();
+ gg();
+ gg();
+ if (g<=4) return 1;
+ return 0;
+}
+
+// { dg-final { scan-tree-dump-times " if " 1 "evrp" } }