https://gcc.gnu.org/g:f35d49f0eb8ffc614cf233ad05b2fe86791c6719
commit f35d49f0eb8ffc614cf233ad05b2fe86791c6719 Author: Jeff Law <j...@ventanamicro.com> Date: Sun Sep 1 22:16:04 2024 -0600 [committed][PR rtl-optimization/116544] Fix test for promoted subregs This is a small bug in the ext-dce code's handling of promoted subregs. Essentially when we see a promoted subreg we need to make additional bit groups live as various parts of the RTL path know that an extension of a suitably promoted subreg can be trivially eliminated. When I added support for dealing with this quirk I failed to account for the larger modes properly and it ignored the case when the size of the inner object was > 32 bits. Opps. This does _not_ fix the outstanding x86 issue. That's caused by something completely different and more concerning ;( Bootstrapped and regression tested on x86. Obviously fixes the testcase on riscv as well. Pushing to the trunk. PR rtl-optimization/116544 gcc/ * ext-dce.cc (ext_dce_process_uses): Fix thinko in promoted subreg handling. gcc/testsuite/ * gcc.dg/torture/pr116544.c: New test. (cherry picked from commit 0562976d62e095f3a00c799288dee4e5b20114e2) Diff: --- gcc/ext-dce.cc | 2 +- gcc/testsuite/gcc.dg/torture/pr116544.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc index fbe9719a8d5..dcd55cf1183 100644 --- a/gcc/ext-dce.cc +++ b/gcc/ext-dce.cc @@ -846,7 +846,7 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj, bitmap_set_bit (livenow, rn + 1); if (size > 16) bitmap_set_bit (livenow, rn + 2); - if (size == 32) + if (size >= 32) bitmap_set_bit (livenow, rn + 3); iter.skip_subrtxes (); } diff --git a/gcc/testsuite/gcc.dg/torture/pr116544.c b/gcc/testsuite/gcc.dg/torture/pr116544.c new file mode 100644 index 00000000000..15f52fecb3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr116544.c @@ -0,0 +1,22 @@ +/* { dg-options "-fno-strict-aliasing -fwrapv" } +/* { dg-do run { target longlong64 } } */ + +extern void abort (void); +long long a; +signed char b[60]; +signed char c; +long long d[60]; +int e[30]; +long long *f = d; +static void g(long long *j, long k) { *j = k; } +int main() { + d[5] = 0x100000000; + for (int h = 2; h < 7; h += 3) + for (int i = 0; i < (c || b[h]) + 10; i += 11) + e[2] = f[h]; + g(&a, e[2]); + if (a != 0) + abort (); + return 0; +} +