re PR target/77881 (Non-optimal signed comparison on x86_64 since r146817)
authorMichael Matz <matz@suse.de>
Tue, 15 Nov 2016 14:02:28 +0000 (14:02 +0000)
committerMichael Matz <matz@gcc.gnu.org>
Tue, 15 Nov 2016 14:02:28 +0000 (14:02 +0000)
PR missed-optimization/77881
* combine.c (simplify_comparison): Remove useless subregs
also inside the loop, not just after it.
(make_compound_operation): Recognize some subregs as being
masking as well.

testsuite/
* gcc.target/i386/pr77881.c: New test.

From-SVN: r242414

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr77881.c [new file with mode: 0644]

index 1e422d2a844c6016bf9d04f7fafc8793d6fcfe0d..c4a660f0cff6ab62099983fb0730ccaf8526ae29 100644 (file)
@@ -1,3 +1,11 @@
+2016-11-15  Michael Matz  <matz@suse.de>
+
+       PR missed-optimization/77881
+       * combine.c (simplify_comparison): Remove useless subregs
+       also inside the loop, not just after it.
+       (make_compound_operation): Recognize some subregs as being
+       masking as well.
+
 2016-11-15  Richard Sandiford  <richard.sandiford@arm.com>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 6b7bdd0f687d0d0d79f2bcdfccbe757a88ff7a7e..2de2a3ef8a273bbb819f2f2f17d6372db27a7fb9 100644 (file)
@@ -8102,6 +8102,18 @@ make_compound_operation (rtx x, enum rtx_code in_code)
        rtx inner = SUBREG_REG (x), simplified;
        enum rtx_code subreg_code = in_code;
 
+       /* If the SUBREG is masking of a logical right shift,
+          make an extraction.  */
+       if (GET_CODE (inner) == LSHIFTRT
+           && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner))
+           && subreg_lowpart_p (x))
+         {
+           new_rtx = make_compound_operation (XEXP (inner, 0), next_code);
+           new_rtx = make_extraction (mode, new_rtx, 0, XEXP (inner, 1),
+                                      mode_width, 1, 0, in_code == COMPARE);
+           break;
+         }
+
        /* If in_code is COMPARE, it isn't always safe to pass it through
           to the recursive make_compound_operation call.  */
        if (subreg_code == COMPARE
@@ -11994,6 +12006,29 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
          if (subreg_lowpart_p (op0)
              && GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op0))) < mode_width)
            ;
+         else if (subreg_lowpart_p (op0)
+                  && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
+                  && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
+                  && (code == NE || code == EQ)
+                  && (GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op0)))
+                      <= HOST_BITS_PER_WIDE_INT)
+                  && !paradoxical_subreg_p (op0)
+                  && (nonzero_bits (SUBREG_REG (op0),
+                                    GET_MODE (SUBREG_REG (op0)))
+                      & ~GET_MODE_MASK (GET_MODE (op0))) == 0)
+           {
+             /* Remove outer subregs that don't do anything.  */
+             tem = gen_lowpart (GET_MODE (SUBREG_REG (op0)), op1);
+
+             if ((nonzero_bits (tem, GET_MODE (SUBREG_REG (op0)))
+                  & ~GET_MODE_MASK (GET_MODE (op0))) == 0)
+               {
+                 op0 = SUBREG_REG (op0);
+                 op1 = tem;
+                 continue;
+               }
+             break;
+           }
          else
            break;
 
index fce6f8d1b8f04c845fb855bece868571ea3bd865..dcb220d036ab69c40f0a72a21c710d83b42f859c 100644 (file)
@@ -1,3 +1,8 @@
+2016-11-15  Michael Matz  <matz@suse.de>
+
+       PR missed-optimization/77881
+       * gcc.target/i386/pr77881.c: New test.
+
 2016-11-15  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/78295
diff --git a/gcc/testsuite/gcc.target/i386/pr77881.c b/gcc/testsuite/gcc.target/i386/pr77881.c
new file mode 100644 (file)
index 0000000..80d143f
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target pie } */
+/* { dg-options "-O2" } */
+extern void baz(void);
+int
+foo (long long int a, long long int a2, int b)
+{
+    if (a < 0 || b)
+          baz ();
+}
+/* { dg-final { scan-assembler "js\[ \t\]\.L" } } */
+/* { dg-final { scan-assembler "jne\[ \t\]\.L" } } */