View | Details | Return to bug 28632 | Differences between
and this patch

Collapse All | Expand All

(-)gcc/tree-vrp.c.jj (-95 / +108 lines)
Lines 2064-2069 vrp_int_const_binop (enum tree_code code Link Here
2064
}
2064
}
2065
2065
2066
2066
2067
/* For range VR compute two double_int bitmasks.  In *MAY_BE_NONZERO
2068
   bitmask if some bit is unset, it means for all numbers in the range
2069
   the bit is 0, otherwise it might be 0 or 1.  In *MUST_BE_NONZERO
2070
   bitmask if some bit is set, it means for all numbers in the range
2071
   the bit is 1, otherwise it might be 0 or 1.  */
2072
2073
static bool
2074
zero_nonzero_bits_from_vr (value_range_t *vr, double_int *may_be_nonzero,
2075
			   double_int *must_be_nonzero)
2076
{
2077
  if (range_int_cst_p (vr))
2078
    {
2079
      if (range_int_cst_singleton_p (vr))
2080
	{
2081
	  *may_be_nonzero = tree_to_double_int (vr->min);
2082
	  *must_be_nonzero = *may_be_nonzero;
2083
	  return true;
2084
	}
2085
      if (tree_int_cst_sgn (vr->min) >= 0)
2086
	{
2087
	  double_int dmin = tree_to_double_int (vr->min);
2088
	  double_int dmax = tree_to_double_int (vr->max);
2089
	  double_int xor_mask = double_int_xor (dmin, dmax);
2090
	  *may_be_nonzero = double_int_ior (dmin, dmax);
2091
	  *must_be_nonzero = double_int_and (dmin, dmax);
2092
	  if (xor_mask.high != 0)
2093
	    {
2094
	      unsigned HOST_WIDE_INT mask
2095
		= ((unsigned HOST_WIDE_INT) 1
2096
		   << floor_log2 (xor_mask.high)) - 1;
2097
	      may_be_nonzero->low = ALL_ONES;
2098
	      may_be_nonzero->high |= mask;
2099
	      must_be_nonzero->low = 0;
2100
	      must_be_nonzero->high &= ~mask;
2101
	    }
2102
	  else if (xor_mask.low != 0)
2103
	    {
2104
	      unsigned HOST_WIDE_INT mask
2105
		= ((unsigned HOST_WIDE_INT) 1
2106
		   << floor_log2 (xor_mask.low)) - 1;
2107
	      may_be_nonzero->low |= mask;
2108
	      must_be_nonzero->low &= ~mask;
2109
	    }
2110
	  return true;
2111
	}
2112
    }
2113
  may_be_nonzero->low = ALL_ONES;
2114
  may_be_nonzero->high = ALL_ONES;
2115
  must_be_nonzero->low = 0;
2116
  must_be_nonzero->high = 0;
2117
  return false;
2118
}
2119
2120
2067
/* Extract range information from a binary expression EXPR based on
2121
/* Extract range information from a binary expression EXPR based on
2068
   the ranges of each of its operands and the expression code.  */
2122
   the ranges of each of its operands and the expression code.  */
2069
2123
Lines 2569-2687 extract_range_from_binary_expr (value_ra Link Here
2569
      min = vrp_int_const_binop (code, vr0.min, vr1.max);
2623
      min = vrp_int_const_binop (code, vr0.min, vr1.max);
2570
      max = vrp_int_const_binop (code, vr0.max, vr1.min);
2624
      max = vrp_int_const_binop (code, vr0.max, vr1.min);
2571
    }
2625
    }
2572
  else if (code == BIT_AND_EXPR)
2626
  else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR)
2573
    {
2627
    {
2574
      bool vr0_int_cst_singleton_p, vr1_int_cst_singleton_p;
2628
      bool vr0_int_cst_singleton_p, vr1_int_cst_singleton_p;
2629
      bool int_cst_range0, int_cst_range1;
2630
      double_int may_be_nonzero0, may_be_nonzero1;
2631
      double_int must_be_nonzero0, must_be_nonzero1;
2575
2632
2576
      vr0_int_cst_singleton_p = range_int_cst_singleton_p (&vr0);
2633
      vr0_int_cst_singleton_p = range_int_cst_singleton_p (&vr0);
2577
      vr1_int_cst_singleton_p = range_int_cst_singleton_p (&vr1);
2634
      vr1_int_cst_singleton_p = range_int_cst_singleton_p (&vr1);
2635
      int_cst_range0 = zero_nonzero_bits_from_vr (&vr0, &may_be_nonzero0,
2636
						  &must_be_nonzero0);
2637
      int_cst_range1 = zero_nonzero_bits_from_vr (&vr1, &may_be_nonzero1,
2638
						  &must_be_nonzero1);
2578
2639
2640
      type = VR_RANGE;
2579
      if (vr0_int_cst_singleton_p && vr1_int_cst_singleton_p)
2641
      if (vr0_int_cst_singleton_p && vr1_int_cst_singleton_p)
2580
	min = max = int_const_binop (code, vr0.max, vr1.max, 0);
2642
	min = max = int_const_binop (code, vr0.max, vr1.max, 0);
2581
      else if (range_int_cst_p (&vr0)
2643
      else if (!int_cst_range0 && !int_cst_range1)
2582
	       && range_int_cst_p (&vr1)
2583
	       && tree_int_cst_sgn (vr0.min) >= 0
2584
	       && tree_int_cst_sgn (vr1.min) >= 0)
2585
	{
2586
	  double_int vr0_mask = tree_to_double_int (vr0.min);
2587
	  double_int vr1_mask = tree_to_double_int (vr1.min);
2588
	  double_int maxd, diff;
2589
	  tree mask;
2590
2591
	  min = build_int_cst (expr_type, 0);
2592
	  /* Compute non-zero bits mask from both ranges.  */
2593
	  if (!vr0_int_cst_singleton_p)
2594
	    {
2595
	      maxd = tree_to_double_int (vr0.max);
2596
	      diff = double_int_sub (maxd, vr0_mask);
2597
	      if (diff.high)
2598
		{
2599
		  diff.low = ~(unsigned HOST_WIDE_INT)0;
2600
		  diff.high = ((HOST_WIDE_INT) 2
2601
			       << floor_log2 (diff.high)) - 1;
2602
		}
2603
	      else
2604
		diff.low = ((HOST_WIDE_INT) 2 << floor_log2 (diff.low)) - 1;
2605
	      vr0_mask = double_int_ior (vr0_mask,
2606
					 double_int_ior (maxd, diff));
2607
	    }
2608
	  if (!vr1_int_cst_singleton_p)
2609
	    {
2610
	      maxd = tree_to_double_int (vr1.max);
2611
	      diff = double_int_sub (maxd, vr1_mask);
2612
	      if (diff.high)
2613
		{
2614
		  diff.low = ~(unsigned HOST_WIDE_INT)0;
2615
		  diff.high = ((HOST_WIDE_INT) 2
2616
			       << floor_log2 (diff.high)) - 1;
2617
		}
2618
	      else
2619
		diff.low = ((HOST_WIDE_INT) 2 << floor_log2 (diff.low)) - 1;
2620
	      vr1_mask = double_int_ior (vr1_mask,
2621
					 double_int_ior (maxd, diff));
2622
	    }
2623
	  mask = double_int_to_tree (expr_type,
2624
				     double_int_and (vr0_mask, vr1_mask));
2625
	  max = vr0.max;
2626
	  if (tree_int_cst_lt (vr1.max, max))
2627
	    max = vr1.max;
2628
	  if (!TREE_OVERFLOW (mask)
2629
	      && tree_int_cst_lt (mask, max)
2630
	      && tree_int_cst_sgn (mask) >= 0)
2631
	    max = mask;
2632
	}
2633
      else if (vr0_int_cst_singleton_p
2634
	       && tree_int_cst_sgn (vr0.max) >= 0)
2635
	{
2644
	{
2636
	  min = build_int_cst (expr_type, 0);
2645
	  set_value_range_to_varying (vr);
2637
	  max = vr0.max;
2646
	  return;
2638
	}
2647
	}
2639
      else if (vr1_int_cst_singleton_p
2648
      else if (code == BIT_AND_EXPR)
2640
	       && tree_int_cst_sgn (vr1.max) >= 0)
2641
	{
2649
	{
2642
	  type = VR_RANGE;
2650
	  min = double_int_to_tree (expr_type,
2643
	  min = build_int_cst (expr_type, 0);
2651
				    double_int_and (must_be_nonzero0,
2644
	  max = vr1.max;
2652
						    must_be_nonzero1));
2653
	  max = double_int_to_tree (expr_type,
2654
				    double_int_and (may_be_nonzero0,
2655
						    may_be_nonzero1));
2656
	  if (TREE_OVERFLOW (min) || tree_int_cst_sgn (min) < 0)
2657
	    min = NULL_TREE;
2658
	  if (TREE_OVERFLOW (max) || tree_int_cst_sgn (max) < 0)
2659
	    max = NULL_TREE;
2660
	  if (int_cst_range0 && tree_int_cst_sgn (vr0.min) >= 0)
2661
	    {
2662
	      if (min == NULL_TREE)
2663
		min = build_int_cst (expr_type, 0);
2664
	      if (max == NULL_TREE || tree_int_cst_lt (vr0.max, max))
2665
		max = vr0.max;
2666
	    }
2667
	  if (int_cst_range1 && tree_int_cst_sgn (vr1.min) >= 0)
2668
	    {
2669
	      if (min == NULL_TREE)
2670
		min = build_int_cst (expr_type, 0);
2671
	      if (max == NULL_TREE || tree_int_cst_lt (vr1.max, max))
2672
		max = vr1.max;
2673
	    }
2645
	}
2674
	}
2646
      else
2675
      else if (!int_cst_range0
2676
	       || !int_cst_range1
2677
	       || tree_int_cst_sgn (vr0.min) < 0
2678
	       || tree_int_cst_sgn (vr1.min) < 0)
2647
	{
2679
	{
2648
	  set_value_range_to_varying (vr);
2680
	  set_value_range_to_varying (vr);
2649
	  return;
2681
	  return;
2650
	}
2682
	}
2651
    }
2652
  else if (code == BIT_IOR_EXPR)
2653
    {
2654
      if (range_int_cst_p (&vr0)
2655
	  && range_int_cst_p (&vr1)
2656
	  && tree_int_cst_sgn (vr0.min) >= 0
2657
	  && tree_int_cst_sgn (vr1.min) >= 0)
2658
	{
2659
	  double_int vr0_max = tree_to_double_int (vr0.max);
2660
	  double_int vr1_max = tree_to_double_int (vr1.max);
2661
	  double_int ior_max;
2662
2663
	  /* Set all bits to the right of the most significant one to 1.
2664
	     For example, [0, 4] | [4, 4] = [4, 7]. */
2665
	  ior_max.low = vr0_max.low | vr1_max.low;
2666
	  ior_max.high = vr0_max.high | vr1_max.high;
2667
	  if (ior_max.high != 0)
2668
	    {
2669
	      ior_max.low = ~(unsigned HOST_WIDE_INT)0u;
2670
	      ior_max.high |= ((HOST_WIDE_INT) 1
2671
			       << floor_log2 (ior_max.high)) - 1;
2672
	    }
2673
	  else if (ior_max.low != 0)
2674
	    ior_max.low |= ((unsigned HOST_WIDE_INT) 1u
2675
			    << floor_log2 (ior_max.low)) - 1;
2676
2677
	  /* Both of these endpoints are conservative.  */
2678
          min = vrp_int_const_binop (MAX_EXPR, vr0.min, vr1.min);
2679
          max = double_int_to_tree (expr_type, ior_max);
2680
	}
2681
      else
2683
      else
2682
	{
2684
	{
2683
	  set_value_range_to_varying (vr);
2685
	  min = double_int_to_tree (expr_type,
2684
	  return;
2686
				    double_int_ior (must_be_nonzero0,
2687
						    must_be_nonzero1));
2688
	  max = double_int_to_tree (expr_type,
2689
				    double_int_ior (may_be_nonzero0,
2690
						    may_be_nonzero1));
2691
	  if (TREE_OVERFLOW (min) || tree_int_cst_sgn (min) < 0)
2692
	    min = vr0.min;
2693
	  else
2694
	    min = vrp_int_const_binop (MAX_EXPR, min, vr0.min);
2695
	  if (TREE_OVERFLOW (max) || tree_int_cst_sgn (max) < 0)
2696
	    max = NULL_TREE;
2697
	  min = vrp_int_const_binop (MAX_EXPR, min, vr1.min);
2685
	}
2698
	}
2686
    }
2699
    }
2687
  else
2700
  else
(-)gcc/testsuite/gcc.dg/tree-ssa/vrp51.c.jj (+58 lines)
Line 0 Link Here
1
/* PR tree-optimization/28632 */
2
/* { dg-do compile } */
3
/* { dg-options "-O2 -ftree-vrp" } */
4
5
void
6
v4 (unsigned a, unsigned b)
7
{
8
  if (a < 0x1000) return;
9
  if (a > 0x1000) return;
10
  if (b < 0x0110) return;
11
  /* constant true.  */
12
  if (!__builtin_constant_p ((a|b) >= 0x01000))
13
    __asm__("bug.always.true");
14
  /* VRP must not think that this is constant.  */
15
  if (__builtin_constant_p ((a|b) >= 0x10000))
16
    __asm__("bug.not.always.true");
17
}
18
19
void
20
u4 (unsigned n)
21
{
22
  if (n > 0x10111) return;
23
  if (n < 0x10101) return;
24
  /* always true.  */
25
  if (!__builtin_constant_p (n & 0x00100))
26
    __asm__("bug.always.true");
27
  /* VRP must not think that this is constant true.  */
28
  if (__builtin_constant_p (n & 0x00001))
29
    __asm__("bug.not.always.true");
30
  /* Out of range, always evaluates to constant false.  */
31
  if (!__builtin_constant_p (n & 0x01000))
32
    __asm__("bug.always.false");
33
}
34
35
void
36
u5 (unsigned n)
37
{
38
  struct s {unsigned exp:8;} x;
39
  x.exp = n;
40
  if (__builtin_constant_p(((n + 1) & 255) > 1))
41
    __asm__("bug.not.always.true");
42
}
43
44
void
45
v5 (int a, int b)
46
{
47
  if (a < 0x1000) return;
48
  if (a > 0x1000) return;
49
  if (b < 0x0110) return;
50
  /* constant true.  */
51
  if (!__builtin_constant_p ((a|b) >= 0x01000))
52
    __asm__("bug.always.true");
53
  /* VRP must not think that this is always true.  */
54
  if (__builtin_constant_p ((a|b) >= 0x10000))
55
    __asm__("bug.not.always.true");
56
}
57
58
/* { dg-final { scan-assembler-not "bug\." } } */
(-)gcc/testsuite/gcc.dg/tree-ssa/vrp52.c.jj (+16 lines)
Line 0 Link Here
1
/* { dg-do compile } */
2
/* { dg-options "-O2 -fdump-tree-vrp1" } */
3
4
int
5
foo (unsigned int i, unsigned int j)
6
{
7
  i &= 15;
8
  j &= 15;
9
  i += 1024;
10
  j += 2048;
11
  i |= j;
12
  return i >= 1024 + 2048;
13
}
14
15
/* { dg-final { scan-tree-dump "Folding predicate i_\[^\n\r\]* to 1" "vrp1" } } */
16
/* { dg-final { cleanup-tree-dump "vrp1" } } */

Return to bug 28632