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] Optimize x > 0xNNNNffffffffLL on i386 (PR target/29978)


Hi!

On the attached testcase on i386 gcc produces redundant
        cmpl    $15, 12(%ebp)
        jl      .L2
        jle     .L2
        call    g
.L2:
while only the jle jump is sufficient.  Turns out we already have an
optimization for this in ix86_expand_branch, but only for long long
x < 0xNNNN00000000LL, not for x <= 0xNNNNffffffffLL, both of which can be
optimized into a SImode comparison, (x >> 32) < 0xNNNN in the first case,
(x >> 32) <= 0xNNNN in the latter case.  Bootstrap/regression test on
i686-linux pending, ok if it succeeds?

2007-12-14  Jakub Jelinek  <jakub@redhat.com>

	PR target/29978
	* config/i386/i386.c (ix86_expand_branch): Optimize LE/LEU/GT/GTU
	DImode comparisons against constant with all 1's in the lower word.

	* gcc.target/i386/pr29978.c: New test.

--- gcc/config/i386/i386.c.jj	2007-12-14 00:26:23.000000000 +0100
+++ gcc/config/i386/i386.c	2007-12-14 14:14:51.000000000 +0100
@@ -12093,16 +12093,28 @@ ix86_expand_branch (enum rtx_code code, 
 
 	/* Otherwise, if we are doing less-than or greater-or-equal-than,
 	   op1 is a constant and the low word is zero, then we can just
-	   examine the high word.  */
+	   examine the high word.  Similarly for low word -1 and
+	   less-or-equal-than or greater-than.  */
 
-	if (CONST_INT_P (hi[1]) && lo[1] == const0_rtx)
+	if (CONST_INT_P (hi[1]))
 	  switch (code)
 	    {
 	    case LT: case LTU: case GE: case GEU:
-	      ix86_compare_op0 = hi[0];
-	      ix86_compare_op1 = hi[1];
-	      ix86_expand_branch (code, label);
-	      return;
+	      if (lo[1] == const0_rtx)
+		{
+		  ix86_compare_op0 = hi[0];
+		  ix86_compare_op1 = hi[1];
+		  ix86_expand_branch (code, label);
+		  return;
+		}
+	    case LE: case LEU: case GT: case GTU:
+	      if (lo[1] == constm1_rtx)
+		{
+		  ix86_compare_op0 = hi[0];
+		  ix86_compare_op1 = hi[1];
+		  ix86_expand_branch (code, label);
+		  return;
+		}
 	    default:
 	      break;
 	    }
--- gcc/testsuite/gcc.target/i386/pr29978.c.jj	2007-12-14 14:26:17.000000000 +0100
+++ gcc/testsuite/gcc.target/i386/pr29978.c	2007-12-14 14:26:04.000000000 +0100
@@ -0,0 +1,16 @@
+/* PR target/29978 */
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+void g ();
+
+void
+f (long long v)
+{
+  if (v > 0xfffffffffLL)
+    g ();
+  g ();
+}
+
+/* Verify there are no redundant jumps jl .L2; jle .L2 */
+/* { dg-final { scan-assembler-not "jl\[^e\]*\\.L" { target ilp32 } } } */

	Jakub


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