Richard Biener <richard.guent...@gmail.com> writes:
> On Thu, Aug 7, 2025 at 2:14 PM Richard Sandiford
> <richard.sandif...@arm.com> wrote:
>>
>> simplify_gen_subreg rejected subregs of literal constants if
>> MODE_COMPOSITE_P.  This was added by the fix for PR96648 in
>> g:c0f772894b6b3cd8ed5c5dd09d0c7917f51cf70f.  Jakub said:
>>
>>   As for the simplify_gen_subreg change, I think it would be desirable
>>   to just avoid creating SUBREGs of constants on all targets and for all
>>   constants, if simplify_immed_subreg simplified, fine, otherwise punt,
>>   but as we are late in GCC11 development, the patch instead guards this
>>   behavior on MODE_COMPOSITE_P (outermode) - i.e. only conversions to
>>   powerpc{,64,64le} double double long double - and only for the cases where
>>   simplify_immed_subreg was called.
>>
>> I'm not sure about relaxing the codes further, since subregs might
>> be wanted for CONST, SYMBOL_REF and LABEL_REF.  But removing the
>> MODE_COMPOSITE_P is needed to fix PR120718, where we get an ICE
>> from generating a subreg of a V2SI const_vector.
>>
>> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?
>
> OK.

Thanks!  Removing the VOIDmode test exposed a latent issue on powerpc
(PR121501), so I kept that test for the backport.  Pushed to GCC 15
as hopefully an obvious variation.

Richard

------------------------------------------------------------------------

simplify_gen_subreg rejected subregs of literal constants if
MODE_COMPOSITE_P.  This was added by the fix for PR96648 in
g:c0f772894b6b3cd8ed5c5dd09d0c7917f51cf70f.  Jakub said:

  As for the simplify_gen_subreg change, I think it would be desirable
  to just avoid creating SUBREGs of constants on all targets and for all
  constants, if simplify_immed_subreg simplified, fine, otherwise punt,
  but as we are late in GCC11 development, the patch instead guards this
  behavior on MODE_COMPOSITE_P (outermode) - i.e. only conversions to
  powerpc{,64,64le} double double long double - and only for the cases where
  simplify_immed_subreg was called.

I'm not sure about relaxing the codes further, since subregs might
be wanted for CONST, SYMBOL_REF and LABEL_REF.  But removing the
MODE_COMPOSITE_P is needed to fix PR120718, where we get an ICE
from generating a subreg of a V2SI const_vector.

Unlike the trunk version, this backport does not remove the
VOIDmode test; see PR121501.

gcc/
        PR rtl-optimization/120718
        * simplify-rtx.cc (simplify_context::simplify_gen_subreg):
        Remove MODE_COMPOSITE_P condition.

gcc/testsuite/
        PR rtl-optimization/120718
        * gcc.target/aarch64/sve/acle/general/pr120718.c: New test.
---
 gcc/simplify-rtx.cc                                 | 13 +++++--------
 .../gcc.target/aarch64/sve/acle/general/pr120718.c  | 12 ++++++++++++
 2 files changed, 17 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 88d31a71c05..8d4cbf1371a 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -8317,14 +8317,11 @@ simplify_context::simplify_gen_subreg (machine_mode 
outermode, rtx op,
 
   if (GET_CODE (op) == SUBREG
       || GET_CODE (op) == CONCAT
-      || GET_MODE (op) == VOIDmode)
-    return NULL_RTX;
-
-  if (MODE_COMPOSITE_P (outermode)
-      && (CONST_SCALAR_INT_P (op)
-         || CONST_DOUBLE_AS_FLOAT_P (op)
-         || CONST_FIXED_P (op)
-         || GET_CODE (op) == CONST_VECTOR))
+      || GET_MODE (op) == VOIDmode
+      || CONST_SCALAR_INT_P (op)
+      || CONST_DOUBLE_AS_FLOAT_P (op)
+      || CONST_FIXED_P (op)
+      || GET_CODE (op) == CONST_VECTOR)
     return NULL_RTX;
 
   if (validate_subreg (outermode, innermode, op, byte))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c 
b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c
new file mode 100644
index 00000000000..9ca0938e36b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c
@@ -0,0 +1,12 @@
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+typedef int __attribute__((vector_size(8))) v2si;
+typedef struct { int x; int y; } A;
+void bar(A a);
+void foo()
+{
+    A a;
+    *(v2si *)&a = (v2si){0, (int)svcntd_pat(SV_ALL)};
+    bar(a);
+}
-- 
2.43.0

Reply via email to