diff mbox

[committed] Fix reassoc bit test optimization (PR tree-optimization/63641)

Message ID 20141025202416.GU10376@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Oct. 25, 2014, 8:24 p.m. UTC
Hi!

Ian reported a bug in optimize_range_tests_to_bit_test, high used to be
off-by-one.  E.g. if the topmost bit in mask is set (wi::clz (mask) is
0), then the highest number covered by the mask is lowi (which corresponds
to bit 0) + prec - 1, rather than lowi + prec.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk as obvious.

2014-10-25  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/63641
	* tree-ssa-reassoc.c (optimize_range_tests_to_bit_test): Set high
	to low + prec - 1 - clz (mask) instead of low + prec - clz (mask).

	* gcc.c-torture/execute/pr63641.c: New test.


	Jakub
diff mbox

Patch

--- gcc/tree-ssa-reassoc.c.jj	2014-10-17 12:53:59.000000000 +0200
+++ gcc/tree-ssa-reassoc.c	2014-10-24 22:38:55.762859480 +0200
@@ -2513,7 +2513,7 @@  optimize_range_tests_to_bit_test (enum t
 	{
 	  tree high = wide_int_to_tree (TREE_TYPE (lowi),
 					wi::to_widest (lowi)
-					+ prec - wi::clz (mask));
+					+ prec - 1 - wi::clz (mask));
 	  operand_entry_t oe = (*ops)[ranges[i].idx];
 	  tree op = oe->op;
 	  gimple stmt = op ? SSA_NAME_DEF_STMT (op)
--- gcc/testsuite/gcc.c-torture/execute/pr63641.c.jj	2014-10-25 18:54:15.338191911 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr63641.c	2014-10-25 18:53:21.000000000 +0200
@@ -0,0 +1,54 @@ 
+/* PR tree-optimization/63641 */
+
+__attribute__ ((noinline, noclone)) int
+foo (unsigned char b)
+{
+  if (0x0 <= b && b <= 0x8)
+    goto lab;
+  if (b == 0x0b)
+    goto lab;
+  if (0x0e <= b && b <= 0x1a)
+    goto lab;
+  if (0x1c <= b && b <= 0x1f)
+    goto lab;
+  return 0;
+lab:
+  return 1;
+}
+
+__attribute__ ((noinline, noclone)) int
+bar (unsigned char b)
+{
+  if (0x0 <= b && b <= 0x8)
+    goto lab;
+  if (b == 0x0b)
+    goto lab;
+  if (0x0e <= b && b <= 0x1a)
+    goto lab;
+  if (0x3c <= b && b <= 0x3f)
+    goto lab;
+  return 0;
+lab:
+  return 1;
+}
+
+char tab1[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,
+		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 };
+char tab2[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,
+		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 };
+
+int
+main ()
+{
+  int i;
+  asm volatile ("" : : : "memory");
+  for (i = 0; i < 256; i++)
+    if (foo (i) != (i < 32 ? tab1[i] : 0))
+      __builtin_abort ();
+  for (i = 0; i < 256; i++)
+    if (bar (i) != (i < 64 ? tab2[i] : 0))
+      __builtin_abort ();
+  return 0;
+}