new_ub = wi::min (new_ub, tmp, sign);
value_range_with_overflow (r, type, new_lb, new_ub);
+
+ // When all positive and all X/Y combinations produce the same quotient
+ // we can refine the result with X % Y == X - Q * Y.
+ // Ensure that division by 0 is not an option.
+ if (wi::gt_p (rh_lb, 0, sign) && wi::ge_p (lh_lb, 0, sign))
+ {
+ wide_int q_lb = wi::div_trunc (lh_lb, rh_ub, sign);
+ wide_int q_ub = wi::div_trunc (lh_ub, rh_lb, sign);
+
+ if (q_lb == q_ub)
+ {
+ new_lb = lh_lb - q_lb * rh_ub;
+ new_ub = lh_ub - q_lb * rh_lb;
+
+ int_range<2> refined (type, new_lb, new_ub);
+ r.intersect (refined);
+ }
+ }
}
bool
--- /dev/null
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-evrp" }
+
+#include <stdint.h>
+
+int8_t src(uint8_t v2_u8, int8_t v4_i8, int8_t v5_i8) {
+ if (!(((uint8_t)6 <= v2_u8) && (v2_u8 <= (uint8_t)7))) __builtin_unreachable();
+ if (!(((int8_t)65 <= v4_i8) && (v4_i8 <= (int8_t)80))) __builtin_unreachable();
+ if (!(((int8_t)100 <= v5_i8) && (v5_i8 <= (int8_t)101))) __builtin_unreachable();
+ int8_t i0_i8 = (int8_t)(v5_i8 % v4_i8);
+ int8_t i1_i8 = (int8_t)((int8_t)i0_i8 >> (uint8_t)v2_u8);
+ return i1_i8;
+}
+// { dg-final { scan-tree-dump "20, 36" "evrp" } }