[Bug rtl-optimization/110867] ICE in combine after 7cdd0860949c6c3232e6cff1d7ca37bb5234074c

2023-08-01 Thread prathamesh3492 at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110867

--- Comment #2 from prathamesh3492 at gcc dot gnu.org ---
(In reply to Stefan Schulze Frielinghaus from comment #1)
> The optimization introduced by r14-2879-g7cdd0860949c6c hits during
> combination of insn
> 
> (insn 31 3 32 2 (set (reg:SI 118 [ _1 ])
> (mem:SI (reg/v/f:SI 115 [ a ]) [1 *a_4(D)+0 S4 A64])) "t.c":15:7 758
> {*arm_movsi_vfp}
>  (nil))
> 
> and
> 
> (insn 9 32 10 2 (set (reg:CC 100 cc)
> (compare:CC (reg:SI 118 [ _1 ])
> (const_int -2147483648 [0x8000]))) "t.c":15:6 272
> {*arm_cmpsi_insn}
>  (nil))
> 
> The idea of r14-2879-g7cdd0860949c6c is to get rid of large constants while
> performing an unsigned comparison.  In this case it looks like a 32-bit
> constant is sign-extended into a 64-bit constant and then a 32-bit
> comparison is done.  While writing the optimization I always assumed that
> the constant does fit into int_mode which is apparently not the case here. 
> Thus one possible solution would be to simply bail out in those cases:
> 
> diff --git a/gcc/combine.cc b/gcc/combine.cc
> index 0d99fa541c5..e46d202d0a7 100644
> --- a/gcc/combine.cc
> +++ b/gcc/combine.cc
> @@ -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  (GET_MODE (op0), _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))
>  {
> 
> Does this resolve the problem for you?

Yes, it worked thanks! I will do a full bootstrap+test with your fix and let
you know the results.

Thanks,
Prathamesh

[Bug rtl-optimization/110867] ICE in combine after 7cdd0860949c6c3232e6cff1d7ca37bb5234074c

2023-08-01 Thread stefansf at linux dot ibm.com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110867

Stefan Schulze Frielinghaus  changed:

   What|Removed |Added

 CC||stefansf at linux dot ibm.com

--- Comment #1 from Stefan Schulze Frielinghaus  
---
The optimization introduced by r14-2879-g7cdd0860949c6c hits during combination
of insn

(insn 31 3 32 2 (set (reg:SI 118 [ _1 ])
(mem:SI (reg/v/f:SI 115 [ a ]) [1 *a_4(D)+0 S4 A64])) "t.c":15:7 758
{*arm_movsi_vfp}
 (nil))

and

(insn 9 32 10 2 (set (reg:CC 100 cc)
(compare:CC (reg:SI 118 [ _1 ])
(const_int -2147483648 [0x8000]))) "t.c":15:6 272
{*arm_cmpsi_insn}
 (nil))

The idea of r14-2879-g7cdd0860949c6c is to get rid of large constants while
performing an unsigned comparison.  In this case it looks like a 32-bit
constant is sign-extended into a 64-bit constant and then a 32-bit comparison
is done.  While writing the optimization I always assumed that the constant
does fit into int_mode which is apparently not the case here.  Thus one
possible solution would be to simply bail out in those cases:

diff --git a/gcc/combine.cc b/gcc/combine.cc
index 0d99fa541c5..e46d202d0a7 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -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  (GET_MODE (op0), _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))
 {

Does this resolve the problem for you?