re PR rtl-optimization/80501 (Wrong code w/ a signed char, a shift, and a conversion...
authorJakub Jelinek <jakub@redhat.com>
Tue, 25 Apr 2017 07:28:43 +0000 (09:28 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 25 Apr 2017 07:28:43 +0000 (09:28 +0200)
PR rtl-optimization/80501
* combine.c (make_compound_operation_int): Set subreg_code to SET
even for AND with mask of the sign bit of mode.

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

From-SVN: r247128

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr80501.c [new file with mode: 0644]

index 1138786b99672c80833df8ec34a819c89e614141..91e67b78d801ce5eac2d3330c58f94039c305fb6 100644 (file)
@@ -1,5 +1,9 @@
 2017-04-25  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/80501
+       * combine.c (make_compound_operation_int): Set subreg_code to SET
+       even for AND with mask of the sign bit of mode.
+
        PR rtl-optimization/80500
        * loop-unroll.c (combine_var_copies_in_loop_exit): Call copy_rtx on
        sum's initial value.
index 87daa28bc8eff311ffd5228307967ac7debaffed..39ef3c6ecb82e364ca41e12877559252d67b4fe9 100644 (file)
@@ -8170,12 +8170,15 @@ make_compound_operation_int (machine_mode mode, rtx *x_ptr,
                || GET_CODE (inner) == SUBREG
                /* (subreg:SI (and:DI (reg:DI) (const_int 0x800000000)) 0)
                   is (const_int 0), rather than
-                  (subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0).  */
+                  (subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0).
+                  Similarly (subreg:QI (and:SI (reg:SI) (const_int 0x80)) 0)
+                  for non-equality comparisons against 0 is not equivalent
+                  to (subreg:QI (lshiftrt:SI (reg:SI) (const_int 7)) 0).  */
                || (GET_CODE (inner) == AND
                    && CONST_INT_P (XEXP (inner, 1))
                    && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner))
                    && exact_log2 (UINTVAL (XEXP (inner, 1)))
-                      >= GET_MODE_BITSIZE (mode))))
+                      >= GET_MODE_BITSIZE (mode) - 1)))
          subreg_code = SET;
 
        tem = make_compound_operation (inner, subreg_code);
index 96f33f0475539f972a825b527b7add6ef0baad7e..f4bede06eb8b94e196b0227881e4485b1aec672b 100644 (file)
@@ -1,5 +1,8 @@
 2017-04-25  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/80501
+       * gcc.c-torture/execute/pr80501.c: New test.
+
        PR rtl-optimization/80500
        * gcc.dg/pr80500.c: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr80501.c b/gcc/testsuite/gcc.c-torture/execute/pr80501.c
new file mode 100644 (file)
index 0000000..0a33e1f
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/80501 */
+
+signed char v = 0;
+
+static signed char
+foo (int x, int y)
+{
+  return x << y;
+}
+
+__attribute__((noinline, noclone)) int
+bar (void)
+{
+  return foo (v >= 0, __CHAR_BIT__ - 1) >= 1;
+}
+
+int
+main ()
+{
+  if (sizeof (int) > sizeof (char) && bar () != 0)
+    __builtin_abort ();
+  return 0;
+}