Hi!

THis bug has been introduced 16.5 years ago.  If simplify_binary_operation_1
is called with op1 (MEM) on which avoid_constant_pool_reference returns
something simpler, for UMOD simplification we check that trueop1 is
CONST_INT and power of 2, but then we use INTVAL of the op1 (MEM).

Fixed by using INTVAL on what we've tested.  Additionally, if the value
has msb set and all other bits clear, exact_log2 will return > 0, but
INTVAL (trueop1) - 1 will invoke UB.  Bootstrapped/regtested on x86_64-linux
and i686-linux, ok for trunk?

2018-01-19  Jakub Jelinek  <ja...@redhat.com>

        PR target/83930
        * simplify-rtx.c (simplify_binary_operation_1) <case UMOD>: Use
        UINTVAL (trueop1) instead of INTVAL (op1).

        * gcc.dg/pr83930.c: New test.

--- gcc/simplify-rtx.c.jj       2018-01-14 17:16:55.657836138 +0100
+++ gcc/simplify-rtx.c  2018-01-19 10:24:03.389017997 +0100
@@ -3411,7 +3411,8 @@ simplify_binary_operation_1 (enum rtx_co
       if (CONST_INT_P (trueop1)
          && exact_log2 (UINTVAL (trueop1)) > 0)
        return simplify_gen_binary (AND, mode, op0,
-                                   gen_int_mode (INTVAL (op1) - 1, mode));
+                                   gen_int_mode (UINTVAL (trueop1) - 1,
+                                                 mode));
       break;
 
     case MOD:
--- gcc/testsuite/gcc.dg/pr83930.c.jj   2018-01-19 10:33:16.657831745 +0100
+++ gcc/testsuite/gcc.dg/pr83930.c      2018-01-19 10:31:55.383859102 +0100
@@ -0,0 +1,17 @@
+/* PR target/83930 */
+/* { dg-do compile } */
+/* { dg-options "-Og -fno-tree-ccp -w" } */
+
+unsigned __attribute__ ((__vector_size__ (16))) v;
+
+static inline void
+bar (unsigned char d)
+{
+  v /= d;
+}
+
+__attribute__ ((always_inline)) void
+foo (void)
+{
+  bar (4);
+}

        Jakub

Reply via email to