const wide_int &rh_lb,
const wide_int &rh_ub) const
{
+ // The AND algorithm does not handle complex signed operations well.
+ // If a signed range crosses the boundry between signed and unsigned
+ // proces sit as 2 ranges and union the results.
+ if (TYPE_SIGN (type) == SIGNED
+ && wi::neg_p (lh_lb, SIGNED) != wi::neg_p (lh_ub, SIGNED))
+ {
+ int prec = TYPE_PRECISION (type);
+ int_range_max tmp;
+ // Process [lh_lb, -1]
+ wi_fold (tmp, type, lh_lb, wi::minus_one (prec), rh_lb, rh_ub);
+ // Now Process [0, rh_ub]
+ wi_fold (r, type, wi::zero (prec), lh_ub, rh_lb, rh_ub);
+ r.union_ (tmp);
+ return;
+ }
+
if (wi_optimize_and_or (r, BIT_AND_EXPR, type, lh_lb, lh_ub, rh_lb, rh_ub))
return;
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+//* This should fold to return 0
+bool
+src(int offset)
+{
+ if (offset > 128)
+ return 0;
+ else
+ return (offset & -9) == 258;
+}
+
+/* { dg-final { scan-tree-dump "return 0" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "PHI" "optimized" } } */