public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-8408] arm: correctly handle inequality comparisons against max constants [PR100563]
@ 2021-05-13 14:17 Richard Earnshaw
  0 siblings, 0 replies; only message in thread
From: Richard Earnshaw @ 2021-05-13 14:17 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ecfb8658c04114d87e1000f9924d6c373df0e7fd

commit r11-8408-gecfb8658c04114d87e1000f9924d6c373df0e7fd
Author: Richard Earnshaw <rearnsha@arm.com>
Date:   Thu May 13 11:42:58 2021 +0100

    arm: correctly handle inequality comparisons against max constants [PR100563]
    
    Normally we expect the gimple optimizers to fold away comparisons that
    are always true, but at some lower optimization levels this is not
    always the case, so the back-end has to be able to generate correct
    code in these cases.
    
    In this example, we have a comparison of the form
    
      (unsigned long long) op <= ~0ULL
    
    which, of course is always true.
    
    Normally, in the arm back-end we handle these expansions where the
    immediate cannot be handled directly by adding 1 to the constant and
    then adjusting the comparison operator:
    
      (unsigned long long) op < CONST + 1
    
    but we cannot do that when the constant is already the largest value.
    
    Fortunately, we observe that the comparisons we need to handle this
    way are either always true or always false, so instead of forming a
    comparison against the maximum value, we can replace it with a
    comparison against the minimum value (which just happens to also be a
    constant we can handle.  So
    
      op1 <= ~0ULL -> op1 >= 0U
      op1 > ~0ULL -> op1 < 0U
    
      op1 <= LONG_LONG_INT_MAX -> op1 >= (-LONG_LONG_INT_MAX - 1)
      op1 > LONG_LONG_INT_MAX -> op1 < (-LONG_LONG_INT_MAX - 1)
    
    gcc:
            PR target/100563
            * config/arm/arm.c (arm_canonicalize_comparison): Correctly
            canonicalize DImode inequality comparisons against the
            maximum integral value.
    
    gcc/testsuite:
            * gcc.dg/pr100563.c: New test.

Diff:
---
 gcc/config/arm/arm.c            | 29 +++++++++++++++++++++++++----
 gcc/testsuite/gcc.dg/pr100563.c |  9 +++++++++
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a201088a6fd..a488f56d913 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -5563,9 +5563,20 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
 			return;
 		      *op1 = GEN_INT (i + 1);
 		      *code = *code == GT ? GE : LT;
-		      return;
 		    }
-		  break;
+		  else
+		    {
+		      /* GT maxval is always false, LE maxval is always true.
+			 We can't fold that away here as we must make a
+			 comparison, but we can fold them to comparisons
+			 with the same result that can be handled:
+			   op0 GT maxval -> op0 LT minval
+			   op0 LE maxval -> op0 GE minval
+			 where minval = (-maxval - 1).  */
+		      *op1 = GEN_INT (-maxval - 1);
+		      *code = *code == GT ? LT : GE;
+		    }
+		  return;
 
 		case GTU:
 		case LEU:
@@ -5578,9 +5589,19 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
 			return;
 		      *op1 = GEN_INT (i + 1);
 		      *code = *code == GTU ? GEU : LTU;
-		      return;
 		    }
-		  break;
+		  else
+		    {
+		      /* GTU ~0 is always false, LEU ~0 is always true.
+			 We can't fold that away here as we must make a
+			 comparison, but we can fold them to comparisons
+			 with the same result that can be handled:
+			   op0 GTU ~0 -> op0 LTU 0
+			   op0 LEU ~0 -> op0 GEU 0.  */
+		      *op1 = const0_rtx;
+		      *code = *code == GTU ? LTU : GEU;
+		    }
+		  return;
 
 		default:
 		  gcc_unreachable ();
diff --git a/gcc/testsuite/gcc.dg/pr100563.c b/gcc/testsuite/gcc.dg/pr100563.c
new file mode 100644
index 00000000000..f6a5fcd3a47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr100563.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-Og -Wno-pointer-to-int-cast" } */
+unsigned long long e(void);
+void f(int);
+void a() {
+  short b = -1, c = (int)&b;
+  unsigned long long d = e();
+  f(b >= d);
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-05-13 14:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-13 14:17 [gcc r11-8408] arm: correctly handle inequality comparisons against max constants [PR100563] Richard Earnshaw

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).