public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFA] Reimplement canonicalization of comparison arguments in match.pd
@ 2015-05-30  5:02 Jeff Law
  2015-05-30 15:10 ` Marc Glisse
  2015-06-01 11:16 ` Richard Biener
  0 siblings, 2 replies; 7+ messages in thread
From: Jeff Law @ 2015-05-30  5:02 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1049 bytes --]


c-common.c::shorten_compare has code to canonicalize the arguments of a 
comparison so that the constant is the second argument.  This patch 
removes the implementation from c-common.c and instead implements it in 
match.pd.

Note the match.pd tries to match the prior behavior of shorten_compare, 
hence the strange handling of zero.  No justification exists AFAIK for 
that strange handling in shorten_compare.

The match.pd pattern is primarily Kai's -- I just took the 4 patterns he 
wrote and squashed them into a single pattern to avoid the test duplication.

The xfailed testcase is only case I saw across my comparison tests where 
this change regressed.  Basically shorten-compare had something 
non-canonical when called.  It was able to canonicalize, then optimize 
the result.  I just wanted a record of that test in the testsuite. 
Obviously if we hit our goal of implementing everything from 
shorten_compare, that test will no longer need to be xfailed :-)

Bootstrapped and regression tested on x86-linux-gnu.  OK for the trunk?




[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 3356 bytes --]

	* c-common.c (shorten_compare): Remove code to swap arguments
	if the first is a constant and the second is not zero.
	* match.md: Add patterns to canonicalize comparisons so that the
	constant argument is second.

	* short-compare-3.c: New test, currently xfailed.

kkk
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 36c984c..8ba4f13 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -4364,41 +4364,6 @@ shorten_compare (location_t loc, tree *op0_ptr, tree *op1_ptr,
   real1 = TREE_CODE (TREE_TYPE (primop0)) == REAL_TYPE;
   real2 = TREE_CODE (TREE_TYPE (primop1)) == REAL_TYPE;
 
-  /* If first arg is constant, swap the args (changing operation
-     so value is preserved), for canonicalization.  Don't do this if
-     the second arg is 0.  */
-
-  if (TREE_CONSTANT (primop0)
-      && !integer_zerop (primop1) && !real_zerop (primop1)
-      && !fixed_zerop (primop1))
-    {
-      std::swap (primop0, primop1);
-      std::swap (op0, op1);
-      *op0_ptr = op0;
-      *op1_ptr = op1;
-      std::swap (unsignedp0, unsignedp1);
-      std::swap (real1, real2);
-
-      switch (code)
-	{
-	case LT_EXPR:
-	  code = GT_EXPR;
-	  break;
-	case GT_EXPR:
-	  code = LT_EXPR;
-	  break;
-	case LE_EXPR:
-	  code = GE_EXPR;
-	  break;
-	case GE_EXPR:
-	  code = LE_EXPR;
-	  break;
-	default:
-	  break;
-	}
-      *rescode_ptr = code;
-    }
-
   /* If comparing an integer against a constant more bits wide,
      maybe we can deduce a value of 1 or 0 independent of the data.
      Or else truncate the constant now
diff --git a/gcc/match.pd b/gcc/match.pd
index bf4da61..1f6dbfe 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1182,6 +1182,25 @@ along with GCC; see the file COPYING3.  If not see
 	(convert (bit_and (op (convert:utype @0) (convert:utype @1))
 			  (convert:utype @4)))))))
 
+/* This pattern canonicalizes comparisons so the constant operand
+   is second, unless the constant operand is zero.
+
+   This mirrors the prior behaviour of shorten_comparison.  There wasn't
+   any justification for the special handling of zero in
+   shorten_comparison.  */
+(for op (lt gt le ge)
+  (simplify
+    (op CONSTANT_CLASS_P@0 @1)
+    (if (!integer_zerop (@1) && !real_zerop (@1) && !fixed_zerop (@1)
+         && (TREE_CODE (TREE_TYPE (@0)) != REAL_TYPE
+             || !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (@0))))
+         && (TREE_CODE (TREE_TYPE (@1)) != REAL_TYPE
+            || !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (@1)))))
+      (if (op == LT_EXPR) (gt @1 @0))
+      (if (op == GT_EXPR) (lt @1 @0))
+      (if (op == LE_EXPR) (ge @1 @0))
+      (if (op == GE_EXPR) (le @1 @0)))))
+
 /* fold-const has a rich set of optimizations for expressions of the
    form A op B ? A : B.   However, those optimizations can be easily
    confused by typecasting, particularly in the true/false arms of the
--- /dev/null	2015-05-20 16:48:49.438489869 -0600
+++ testsuite/gcc.dg/short-compare-3.c	2015-05-29 22:28:50.931836673 -0600
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+
+extern unsigned short mode_size[];
+void oof (void);
+void
+fu ()
+{
+  if (64 >= mode_size[42])
+    oof ();
+}
+
+/* { dg-final { scan-tree-dump-times "\(int\)" 0 "original" {xfail *-*-*}} } */
+/* { dg-final { cleanup-tree-dump "original" } } */
+

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-06-04  4:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-30  5:02 [RFA] Reimplement canonicalization of comparison arguments in match.pd Jeff Law
2015-05-30 15:10 ` Marc Glisse
2015-06-02 22:07   ` Jeff Law
2015-06-04  5:47   ` Jeff Law
2015-06-01 11:16 ` Richard Biener
2015-06-02 22:54   ` Jeff Law
2015-06-04  4:53   ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).