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

Collapse All | Expand All

(-)a/gcc/testsuite/gcc.dg/tree-ssa/vrp49.c (+51 lines)
Line 0 Link Here
1
/* { dg-do compile } */
2
/* { dg-options "-O2 -ftree-vrp" } */
3
/* PR28632 was concerned about VRP understanding bitwise OR and AND expressions.
4
 */
5
6
void 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
void u4 (unsigned n)
19
{
20
  if (n > 0x10111) return;
21
  if (n < 0x10101) return;
22
  /* always true.  */
23
  if (!__builtin_constant_p (n & 0x00100))
24
    __asm__("bug.always.true");
25
  /* VRP must not think that this is constant true.  */
26
  if (__builtin_constant_p (n & 0x00001))
27
    __asm__("bug.not.always.true");
28
  /* Out of range, always evaluates to constant false.  */
29
  if (!__builtin_constant_p (n & 0x01000))
30
    __asm__("bug.always.false");
31
}
32
void u5 (unsigned n)
33
{
34
  struct s {unsigned exp:8;} x;
35
  x.exp = n;
36
  if (__builtin_constant_p(((n + 1) & 255) > 1))
37
    __asm__("bug.not.always.true");
38
}
39
void v5 (int a, int b)
40
{
41
  if (a < 0x1000) return;
42
  if (a > 0x1000) return;
43
  if (b < 0x0110) return;
44
  /* constant true.  */
45
  if (!__builtin_constant_p ((a|b) >= 0x01000))
46
    __asm__("bug.always.true");
47
  /* VRP must not think that this is always true.  */
48
  if (__builtin_constant_p ((a|b) >= 0x10000))
49
    __asm__("bug.not.always.true");
50
}
51
/* { dg-final { scan-assembler-not "bug\." } } */
(-)a/gcc/testsuite/gcc.dg/vect/slp-perm-4.c (+1 lines)
Lines 65-70 int main (int argc, const char* argv[]) Link Here
65
65
66
  for (i = 0; i < N; i++)
66
  for (i = 0; i < N; i++)
67
    {
67
    {
68
      __asm__("":"+r"(i)); /* don't vectorize this.. */
68
      input[i] = i%256;
69
      input[i] = i%256;
69
      if (input[i] > 200)
70
      if (input[i] > 200)
70
        abort();
71
        abort();
(-)a/gcc/tree-vrp.c (-19 / +223 lines)
Lines 391-400 set_value_range (value_range_t *vr, enum value_range_type t, tree min, Link Here
391
    }
391
    }
392
392
393
  if (t == VR_UNDEFINED || t == VR_VARYING)
393
  if (t == VR_UNDEFINED || t == VR_VARYING)
394
    gcc_assert (min == NULL_TREE && max == NULL_TREE);
394
    {
395
395
      gcc_assert (min == NULL_TREE && max == NULL_TREE);
396
  if (t == VR_UNDEFINED || t == VR_VARYING)
396
      gcc_assert (equiv == NULL || bitmap_empty_p (equiv));
397
    gcc_assert (equiv == NULL || bitmap_empty_p (equiv));
397
    }
398
#endif
398
#endif
399
399
400
  vr->type = t;
400
  vr->type = t;
Lines 2339-2345 extract_range_from_binary_expr (value_range_t *vr, Link Here
2339
	      || range_includes_zero_p (&vr1)))
2339
	      || range_includes_zero_p (&vr1)))
2340
	{
2340
	{
2341
	  tree zero = build_int_cst (TREE_TYPE (vr0.min), 0);
2341
	  tree zero = build_int_cst (TREE_TYPE (vr0.min), 0);
2342
	  int cmp;
2343
2342
2344
	  sop = false;
2343
	  sop = false;
2345
	  min = NULL_TREE;
2344
	  min = NULL_TREE;
Lines 2493-2522 extract_range_from_binary_expr (value_range_t *vr, Link Here
2493
    }
2492
    }
2494
  else if (code == BIT_AND_EXPR)
2493
  else if (code == BIT_AND_EXPR)
2495
    {
2494
    {
2495
#define DEBUG_STUFF(vr0, vr1, type, str) \
2496
	    { \
2497
	      fprintf (dump_file, "Incoming " str " (%s", \
2498
		  vr0.type == VR_UNDEFINED ? "UNDEFINED " : \
2499
		  vr0.type == VR_RANGE ? "" : \
2500
		  vr0.type == VR_ANTI_RANGE ? "~" : \
2501
		  vr0.type == VR_VARYING ? "VARYING " : "XXX"); \
2502
	      fprintf (dump_file, "["); \
2503
	      print_generic_expr (dump_file, vr0.min, 0); \
2504
	      fprintf (dump_file, ", "); \
2505
	      print_generic_expr (dump_file, vr0.max, 0); \
2506
	      fprintf (dump_file, "] , %s[", \
2507
		  vr1.type == VR_UNDEFINED ? "UNDEFINED " : \
2508
		  vr1.type == VR_RANGE ? "" : \
2509
		  vr1.type == VR_ANTI_RANGE ? "~" : \
2510
		  vr1.type == VR_VARYING ? "VARYING " : "XXX"); \
2511
	      print_generic_expr (dump_file, vr1.min, 0); \
2512
	      fprintf (dump_file, ", "); \
2513
	      print_generic_expr (dump_file, vr1.max, 0); \
2514
	      fprintf (dump_file, "]"); \
2515
	      fprintf (dump_file, ") using %s", \
2516
		  type == VR_UNDEFINED ? "UNDEFINED " : \
2517
		  type == VR_RANGE ? "" : \
2518
		  type == VR_ANTI_RANGE ? "~" : \
2519
		  type == VR_VARYING ? "VARYING " : "XXX"); \
2520
	      fprintf (dump_file, "["); \
2521
	      print_generic_expr (dump_file, min, 0); \
2522
	      fprintf (dump_file, ", "); \
2523
	      print_generic_expr (dump_file, max, 0); \
2524
	      fprintf (dump_file, "]\n"); \
2525
	    }
2526
2527
      double_int vr0_min, vr0_max, vr1_min, vr1_max;
2528
      double_int bits0, bits1, tmp0, tmp1;
2529
      double_int and_min, and_max;
2530
2531
      if ((vr0.type != VR_RANGE
2532
	   && vr0.type != VR_ANTI_RANGE
2533
	   && vr1.type != VR_RANGE
2534
	   && vr1.type != VR_ANTI_RANGE)
2535
	  /* -ENOIDEA */
2536
	  || (vr0.type == VR_VARYING && range_is_nonnull (&vr1))
2537
	  || (vr1.type == VR_VARYING && range_is_nonnull (&vr0)))
2538
	{
2539
	  set_value_range_to_varying (vr);
2540
	  return;
2541
	}
2542
2543
      /* For usual RANGE, RANGE we can just take the normal ranges.
2544
       *
2545
       * If either one of the ranges is an ANTI_RANGE though, then we
2546
       * currently have to use 0 or -1 as the minimum or maximum, respectively.
2547
       *
2548
       * If the non-anti range is, however, VARYING or it's minimum or maximum
2549
       * otherwise NULL_TREE, then give up (by setting the current range
2550
       * to VARYING too).
2551
       */
2496
      if (vr0.type == VR_RANGE
2552
      if (vr0.type == VR_RANGE
2497
	  && vr0.min == vr0.max
2553
	  && vr0.min != NULL_TREE
2498
	  && TREE_CODE (vr0.max) == INTEGER_CST
2554
	  && TREE_CODE (vr0.min) == INTEGER_CST)
2499
	  && !TREE_OVERFLOW (vr0.max)
2555
	  vr0_min = tree_to_double_int (vr0.min);
2500
	  && tree_int_cst_sgn (vr0.max) >= 0)
2556
      else if (vr1.min != NULL_TREE && TREE_CODE (vr1.min) == INTEGER_CST)
2501
	{
2557
	{
2502
	  min = build_int_cst (expr_type, 0);
2558
	  vr0_min.low = 0;
2503
	  max = vr0.max;
2559
	  vr0_min.high = 0;
2504
	}
2560
	}
2505
      else if (vr1.type == VR_RANGE
2561
      else
2506
	       && vr1.min == vr1.max
2507
	       && TREE_CODE (vr1.max) == INTEGER_CST
2508
	       && !TREE_OVERFLOW (vr1.max)
2509
	       && tree_int_cst_sgn (vr1.max) >= 0)
2510
	{
2562
	{
2511
	  type = VR_RANGE;
2563
	  set_value_range_to_varying (vr);
2512
	  min = build_int_cst (expr_type, 0);
2564
	  return;
2513
	  max = vr1.max;
2565
	}
2566
      if (vr1.type == VR_RANGE
2567
	  && vr1.min != NULL_TREE
2568
	  && TREE_CODE (vr1.min) == INTEGER_CST)
2569
	  vr1_min = tree_to_double_int (vr1.min);
2570
      else if (vr0.min != NULL_TREE && TREE_CODE (vr0.min) == INTEGER_CST)
2571
	{
2572
	  vr1_min.low = 0;
2573
	  vr1_min.high = 0;
2574
	}
2575
      else
2576
	{
2577
	  set_value_range_to_varying (vr);
2578
	  return;
2579
	}
2580
      if (vr0.type == VR_RANGE
2581
	  && vr0.max != NULL_TREE
2582
	  && TREE_CODE (vr0.max) == INTEGER_CST)
2583
	  vr0_max = tree_to_double_int (vr0.max);
2584
      else if (vr1.max != NULL_TREE && TREE_CODE (vr1.max) == INTEGER_CST)
2585
	{
2586
	  vr0_max.low = ALL_ONES;
2587
	  vr0_max.high = ALL_ONES;
2514
	}
2588
	}
2515
      else
2589
      else
2516
	{
2590
	{
2517
	  set_value_range_to_varying (vr);
2591
	  set_value_range_to_varying (vr);
2518
	  return;
2592
	  return;
2519
	}
2593
	}
2594
      if (vr1.type == VR_RANGE
2595
	  && vr1.max != NULL_TREE
2596
	  && TREE_CODE (vr1.max) == INTEGER_CST)
2597
	  vr1_max = tree_to_double_int (vr1.max);
2598
      else if (vr0.max != NULL_TREE && TREE_CODE (vr0.max) == INTEGER_CST)
2599
	{
2600
	  vr1_max.low = ALL_ONES;
2601
	  vr1_max.high = ALL_ONES;
2602
	}
2603
      else
2604
	{
2605
	  set_value_range_to_varying (vr);
2606
	  return;
2607
	}
2608
2609
      type = VR_RANGE;
2610
2611
      /* Undo the damage of set_value_range_to_nonnull().  */
2612
      if (range_is_nonnull (&vr0)
2613
	  && vr1.type == VR_RANGE
2614
	  && !integer_zerop (vr1.min))
2615
	{
2616
	  type = VR_RANGE;
2617
	  max = vr1.max;
2618
	  if (compare_values (vr1.min, vr1.max) == 0)
2619
	    min = build_int_cst (expr_type, 0);
2620
	  else
2621
	    min = vr1.min;
2622
2623
	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2624
	    DEBUG_STUFF(vr0, vr1, type, "nonnull0")
2625
	}
2626
      else if (range_is_nonnull (&vr1)
2627
	  && vr0.type == VR_RANGE
2628
	  && !integer_zerop (vr0.min))
2629
	{
2630
	  type = VR_RANGE;
2631
	  max = vr0.max;
2632
	  if (compare_values (vr0.min, vr0.max) == 0)
2633
	    min = build_int_cst (expr_type, 0);
2634
	  else
2635
	    min = vr0.min;
2636
2637
	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2638
	    DEBUG_STUFF(vr0, vr1, type, "nonnull1")
2639
	}
2640
      else
2641
	/* Two ranges, finally!  */
2642
	{
2643
	  bits0.low = vr0_min.low ^ vr0_max.low;
2644
	  bits0.high = vr0_min.high ^ vr0_max.high;
2645
	  bits1.low = vr1_min.low ^ vr1_max.low;
2646
	  bits1.high = vr1_min.high ^ vr1_max.high;
2647
2648
	  /* Handle bits that are always high i.e. set.  */
2649
	  tmp0.high = vr0_min.high & vr0_max.high;
2650
	  if (bits0.high != 0)
2651
	    {
2652
	      tmp0.low = (unsigned HOST_WIDE_INT) 0u;
2653
	      tmp0.high &= ~(((unsigned HOST_WIDE_INT) 1u
2654
				<< floor_log2 (bits0.high)) - 1);
2655
	    }
2656
	  else if (bits0.low != 0)
2657
	    {
2658
	      tmp0.low = (vr0_min.low & vr0_max.low)
2659
			    & ~(((unsigned HOST_WIDE_INT) 1u
2660
				<< floor_log2 (bits0.low)) - 1);
2661
	    }
2662
	  else
2663
	    tmp0.low = vr0_min.low & vr0_max.low;
2664
	  tmp1.high = vr1_min.high & vr1_max.high;
2665
	  if (bits1.high != 0)
2666
	    {
2667
	      tmp1.low = (unsigned HOST_WIDE_INT) 0u;
2668
	      tmp1.high &= ~(((unsigned HOST_WIDE_INT) 1u
2669
				<< floor_log2 (bits1.high)) - 1);
2670
	    }
2671
	  else if (bits1.low != 0)
2672
	    {
2673
	      tmp1.low = (vr1_min.low & vr1_max.low)
2674
			    & ~(((unsigned HOST_WIDE_INT) 1u
2675
				<< floor_log2 (bits1.low)) - 1);
2676
	    }
2677
	  else
2678
	    tmp1.low = vr1_min.low & vr1_max.low;
2679
	  /* Finally BIT_AND_EXPR them together.  */
2680
	  and_min.low = tmp0.low & tmp1.low;
2681
	  and_min.high = tmp0.high & tmp1.high;
2682
2683
	  /* Handle bits that are always low i.e. unset.  */
2684
	  tmp0.high = vr0_min.high | vr0_max.high;
2685
	  if (bits0.high != 0)
2686
	    {
2687
	      tmp0.low = ~(unsigned HOST_WIDE_INT) 0u;
2688
	      tmp0.high |= ((unsigned HOST_WIDE_INT) 1u
2689
				<< floor_log2 (bits0.high)) - 1;
2690
	    }
2691
	  else if (bits0.low & ((~(unsigned HOST_WIDE_INT) 0u) - 1))
2692
	    {
2693
	      tmp0.low = (vr0_min.low | vr0_max.low)
2694
			    | (((unsigned HOST_WIDE_INT) 1u
2695
				<< floor_log2 (bits0.low)) - 1);
2696
	    }
2697
	  else
2698
	    tmp0.low = vr0_min.low | vr0_max.low;
2699
	  tmp1.high = vr1_min.high | vr1_max.high;
2700
	  if (bits1.high != 0)
2701
	    {
2702
	      tmp1.low = ~(unsigned HOST_WIDE_INT) 0u;
2703
	      tmp1.high |= ((unsigned HOST_WIDE_INT) 1u
2704
				<< floor_log2 (bits1.high)) - 1;
2705
	    }
2706
	  else if (bits1.low & ((~(unsigned HOST_WIDE_INT) 0u) - 1))
2707
	    {
2708
	      tmp1.low = (vr1_min.low | vr1_max.low)
2709
			    | (((unsigned HOST_WIDE_INT) 1u
2710
				<< floor_log2 (bits1.low)) - 1);
2711
	    }
2712
	  else
2713
	    tmp1.low = vr1_min.low | vr1_max.low;
2714
	  /* Finally BIT_AND_EXPR them together.  */
2715
	  and_max.low = tmp0.low & tmp1.low;
2716
	  and_max.high = tmp0.high & tmp1.high;
2717
2718
	  min = double_int_to_tree (expr_type, and_min);
2719
	  max = double_int_to_tree (expr_type, and_max);
2720
2721
	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
2722
	    DEBUG_STUFF(vr0, vr1, type, "")
2723
	}
2520
    }
2724
    }
2521
  else if (code == BIT_IOR_EXPR)
2725
  else if (code == BIT_IOR_EXPR)
2522
    {
2726
    {

Return to bug 28632