This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][combine] PR middle-end/71074 Check that const_op is >= 0 before potentially shifting in simplify_comparison


Hi all,

In this PR we may end up shifting a negative value left in simplify_comparison.
The statement is:
const_op <<= INTVAL (XEXP (op0, 1));

This patch guards the block of that statement by const_op >= 0.
I _think_ that's a correct thing to do for that trasnformation:
"If we have (compare (xshiftrt FOO N) (const_int C)) and
 the low order N bits of FOO are known to be zero, we can do this
 by comparing FOO with C shifted left N bits so long as no
 overflow occurs."

The constant C here is const_op.

Bootstrapped and tested on arm-none-linux-gnueabihf, aarch64-none-linux-gnu.

Ok for trunk?

Thanks,
Kyrill

2016-05-13  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    PR middle-end/71074
    * combine.c (simplify_comparison): Avoid left shift of negative
    const_op in LSHIFTRT case.

2016-05-13  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    PR middle-end/71074
    * gcc.c-torture/compile/pr71074.c: New test.
diff --git a/gcc/combine.c b/gcc/combine.c
index 2a7a9e6e2b597246392ede22552af1bdd7e1a794..7a21d593777ef267942e0ee80e024b147907652f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -12321,6 +12321,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
 	     optimization and for > or <= by setting all the low
 	     order N bits in the comparison constant.  */
 	  if (CONST_INT_P (XEXP (op0, 1))
+	      && const_op >= 0
 	      && INTVAL (XEXP (op0, 1)) > 0
 	      && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
 	      && mode_width <= HOST_BITS_PER_WIDE_INT
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr71074.c b/gcc/testsuite/gcc.c-torture/compile/pr71074.c
new file mode 100644
index 0000000000000000000000000000000000000000..9ad6cbe7c231069c86d3ade22784f338f331b657
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr71074.c
@@ -0,0 +1,13 @@
+int bar (void);
+
+void
+foo (unsigned long long a, int b)
+{
+  int i;
+
+    for (a = -12; a >= 10; a = bar ())
+      break;
+
+    if (i == bar () || bar () >= a)
+      bar ();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]