return;
}
+ // Check for constant and try to fold.
+ if (lh_lb == lh_ub && rh_lb == rh_ub)
+ {
+ wi::overflow_type ov = wi::OVF_NONE;
+ tmp = wi::mod_trunc (lh_lb, rh_lb, sign, &ov);
+ if (ov == wi::OVF_NONE)
+ {
+ r = int_range<2> (type, tmp, tmp);
+ return;
+ }
+ }
+
// ABS (A % B) < ABS (B) and either 0 <= A % B <= A or A <= A % B <= 0.
new_ub = rh_ub - 1;
if (sign == SIGNED)
return 0;
}
-/* Dont optimize 972195717 / 0 in function foo. */
+/* Ensure we are folding modulus sub-ranges properly. */
+__attribute__ ((noinline))
+int mod (int a, int b)
+{
+ int v1, v2;
+ v1 = (a < 10) ? 12 : 24;
+ v2 = (b > 20) ? 3 : 6;
+
+ if (a > 20)
+ v1 = v1 * 2;
+ if (b > 20)
+ v2 = v2 * 2;
+
+ if (a == b)
+ v2 = 0;
+
+ /* v1 == 12, 24, or 48. v2 == 0, 3, 6, or 12. */
+ int c = v1 % v2;
+ if (c == 0)
+ ;
+ else
+ __builtin_abort ();
+ return 0;
+}
+
+/* EVRP now makes transformations in all functions, leaving a single
+ * builtin_abort call in bar2. */
+/* { dg-final { scan-tree-dump-times "__builtin_abort" 1 "evrp" } } */
+
+/* Make sure to optimize 972195717 / 0 in function foo. */
/* { dg-final { scan-tree-dump-times "972195717 / " 0 "evrp" } } */
-/* Dont optimize 972195717 % 0 in function bar. */
-/* { dg-final { scan-tree-dump-times "972195717 % " 1 "evrp" } } */
-/* May optimize in function bar2, but EVRP doesn't perform this yet. */
+/* Make sure to optimize 972195717 % 0 in function bar. */
+/* { dg-final { scan-tree-dump-times "972195717 % " 0 "evrp" } } */
+/* Make sure to optimize 972195717 % [1,2] function bar2. */
/* { dg-final { scan-tree-dump-times "972195715 % " 0 "evrp" } } */
+/* [12,12][24,24][48,48] % [0,0][3,3][6,6][12,12] == [0,0] */
+/* { dg-final { scan-tree-dump-times "%" 0 "evrp" } } */