https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110867
Stefan Schulze Frielinghaus <stefansf at linux dot ibm.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |stefansf at linux dot ibm.com
--- Comment #1 from Stefan Schulze Frielinghaus <stefansf at linux dot ibm.com>
---
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 [0xffffffff80000000]))) "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 <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))
{
Does this resolve the problem for you?