]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rtl-optimization/110867 Fix narrow comparison of memory and constant
authorStefan Schulze Frielinghaus <stefansf@linux.ibm.com>
Wed, 2 Aug 2023 19:43:22 +0000 (21:43 +0200)
committerStefan Schulze Frielinghaus <stefansf@linux.ibm.com>
Wed, 2 Aug 2023 19:43:22 +0000 (21:43 +0200)
In certain cases a constant may not fit into the mode used to perform a
comparison.  This may be the case for sign-extended constants which are
used during an unsigned comparison as e.g. in

(set (reg:CC 100 cc)
    (compare:CC (mem:SI (reg/v/f:SI 115 [ a ]) [1 *a_4(D)+0 S4 A64])
        (const_int -2147483648 [0xffffffff80000000])))

Fixed by ensuring that the constant fits into comparison mode.

Furthermore, on some targets as e.g. sparc the constant used in a
comparison is chopped off before combine which leads to failing test
cases (see PR 110869).  Fixed by not requiring that the source mode has
to be DImode, and excluding sparc from the last two test cases entirely
since there the constant cannot be further reduced.

gcc/ChangeLog:

PR rtl-optimization/110867
* combine.cc (simplify_compare_const): Try the optimization only
in case the constant fits into the comparison mode.

gcc/testsuite/ChangeLog:

PR rtl-optimization/110869
* gcc.dg/cmp-mem-const-1.c: Relax mode for constant.
* gcc.dg/cmp-mem-const-2.c: Relax mode for constant.
* gcc.dg/cmp-mem-const-3.c: Relax mode for constant.
* gcc.dg/cmp-mem-const-4.c: Relax mode for constant.
* gcc.dg/cmp-mem-const-5.c: Exclude sparc since here the
constant is already reduced.
* gcc.dg/cmp-mem-const-6.c: Exclude sparc since here the
constant is already reduced.

gcc/combine.cc
gcc/testsuite/gcc.dg/cmp-mem-const-1.c
gcc/testsuite/gcc.dg/cmp-mem-const-2.c
gcc/testsuite/gcc.dg/cmp-mem-const-3.c
gcc/testsuite/gcc.dg/cmp-mem-const-4.c
gcc/testsuite/gcc.dg/cmp-mem-const-5.c
gcc/testsuite/gcc.dg/cmp-mem-const-6.c

index 0d99fa541c5ab2efdb196be54a95cbe8fcba7cb1..e46d202d0a7e04585b62bb5935d78203ecef06e5 100644 (file)
@@ -11998,11 +11998,15 @@ simplify_compare_const (enum rtx_code code, machine_mode mode,
      x0 >= 0x40.  */
   if ((code == LEU || code == LTU || code == GEU || code == GTU)
       && is_a <scalar_int_mode> (GET_MODE (op0), &int_mode)
+      && HWI_COMPUTABLE_MODE_P (int_mode)
       && MEM_P (op0)
       && !MEM_VOLATILE_P (op0)
       /* The optimization makes only sense for constants which are big enough
         so that we have a chance to chop off something at all.  */
       && (unsigned HOST_WIDE_INT) const_op > 0xff
+      /* Bail out, if the constant does not fit into INT_MODE.  */
+      && (unsigned HOST_WIDE_INT) const_op
+        < ((HOST_WIDE_INT_1U << (GET_MODE_PRECISION (int_mode) - 1) << 1) - 1)
       /* Ensure that we do not overflow during normalization.  */
       && (code != GTU || (unsigned HOST_WIDE_INT) const_op < HOST_WIDE_INT_M1U))
     {
index 263ad98af79d3e071e10aa2e1d50befdceb8a50f..4f21a1ade4a314304b4b8e210c9b945c4b62cad4 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { lp64 } } } */
 /* { dg-options "-O1 -fdump-rtl-combine-details" } */
-/* { dg-final { scan-rtl-dump "narrow comparison from mode DI to QI" "combine" } } */
+/* { dg-final { scan-rtl-dump "narrow comparison from mode .I to QI" "combine" } } */
 
 typedef __UINT64_TYPE__ uint64_t;
 
index a7cc5348295cabf5bfcec35fd53f0e347f514c9e..7b722951594c89f004d341e0c48f394516353471 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { lp64 } } } */
 /* { dg-options "-O1 -fdump-rtl-combine-details" } */
-/* { dg-final { scan-rtl-dump "narrow comparison from mode DI to QI" "combine" } } */
+/* { dg-final { scan-rtl-dump "narrow comparison from mode .I to QI" "combine" } } */
 
 typedef __UINT64_TYPE__ uint64_t;
 
index 06f80bf72d8e5c6b117595b3c62f5d8b32df89de..ed5059d380741963b5f95beb9351426dde34d6d7 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { lp64 } } } */
 /* { dg-options "-O1 -fdump-rtl-combine-details" } */
-/* { dg-final { scan-rtl-dump "narrow comparison from mode DI to HI" "combine" } } */
+/* { dg-final { scan-rtl-dump "narrow comparison from mode .I to HI" "combine" } } */
 
 typedef __UINT64_TYPE__ uint64_t;
 
index 407999abf7e9c93990a6ffc1b1e820af0277cb4e..23e83372beedb2a59bce30e1e2ef3ea29b8e0a8b 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { lp64 } } } */
 /* { dg-options "-O1 -fdump-rtl-combine-details" } */
-/* { dg-final { scan-rtl-dump "narrow comparison from mode DI to HI" "combine" } } */
+/* { dg-final { scan-rtl-dump "narrow comparison from mode .I to HI" "combine" } } */
 
 typedef __UINT64_TYPE__ uint64_t;
 
index e16773f5bcf1f5cc672700c4d9988c55d7dbb10a..d266896a25e0be8782b9b3ef065f9e28b92cc1b7 100644 (file)
@@ -1,6 +1,6 @@
-/* { dg-do compile { target { lp64 } } } */
+/* { dg-do compile { target { lp64 } && ! target { sparc*-*-* } } } */
 /* { dg-options "-O1 -fdump-rtl-combine-details" } */
-/* { dg-final { scan-rtl-dump "narrow comparison from mode DI to SI" "combine" } } */
+/* { dg-final { scan-rtl-dump "narrow comparison from mode .I to SI" "combine" } } */
 
 typedef __UINT64_TYPE__ uint64_t;
 
index 8f53b5678bd8b4a0eaf62ec61c784188f3a9c8fd..68d7a9d026587cf9e305b0f9c0fb37836a00214a 100644 (file)
@@ -1,6 +1,6 @@
-/* { dg-do compile { target { lp64 } } } */
+/* { dg-do compile { target { lp64 } && ! target { sparc*-*-* } } } */
 /* { dg-options "-O1 -fdump-rtl-combine-details" } */
-/* { dg-final { scan-rtl-dump "narrow comparison from mode DI to SI" "combine" } } */
+/* { dg-final { scan-rtl-dump "narrow comparison from mode .I to SI" "combine" } } */
 
 typedef __UINT64_TYPE__ uint64_t;