https://gcc.gnu.org/g:0476f5316e781a1ea0d7ef91ed654358f4bccd80

commit 0476f5316e781a1ea0d7ef91ed654358f4bccd80
Author: Jeff Law <j...@ventanamicro.com>
Date:   Wed Jul 31 10:15:01 2024 -0600

    [PR rtl-optimization/116136] Fix previously latent SUBREG simplification bug
    
    This fixes a testsuite regression seen on m68k after some of the recent 
ext-dce
    changes.  Ultimately Richard S and I have concluded the bug was a latent 
issue
    in subreg simplification.
    
    Essentially when simplifying something like
    
    (set (target:M1) (subreg:M1 (subreg:M2 (reg:M1) 0) 0))
    
    Where M1 > M2.  We'd simplify to:
    
    (set (target:M1) (reg:M1))
    
    The problem is on a big endian target that's wrong.   Consider if M1 is DI 
and
    M2 is SI.    The original should extract bits 32..63 from the source 
register
    and store them into bits 0..31 of the target register. In the simplified 
form
    it's just a copy, so bits 0..63 of the source end up bits 0..63 of the 
target.
    
    This shows up as the following regressions on the m68k:
    
    > Tests that now fail, but worked before (3 tests):
    >
    > gcc: gcc.c-torture/execute/960416-1.c   -O2  execution test
    > gcc: gcc.c-torture/execute/960416-1.c   -O2 -flto -fno-use-linker-plugin 
-flto-partition=none  execution test
    > gcc: gcc.c-torture/execute/960416-1.c   -Os  execution test
    
    The fix is pretty trivial, instead of hardcoding "0" as the byte offset in 
the
    test for the simplification, instead we need to use the 
subreg_lowpart_offset.
    
    Anyway, bootstrapped and regression tested on m68k and x86_64 and tested on 
the
    other embedded targets as well without regressions.  Naturally it fixes the
    regression noted above.  I haven't see other testsuite improvements when I 
spot
    checked some of the big endian crosses.
    
            PR rtl-optimization/116136
    gcc/
            * simplify-rtx.cc (simplify_context::simplify_subreg): Check
            that we're working with the lowpart offset rather than byte 0.
    
    (cherry picked from commit 89ed5ab210b5e30c325b92e9e40c50e337be1b44)

Diff:
---
 gcc/simplify-rtx.cc | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 898ad8c2221..260c77584de 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -7672,8 +7672,9 @@ simplify_context::simplify_subreg (machine_mode 
outermode, rtx op,
        return NULL_RTX;
 
       if (outermode == innermostmode
-         && known_eq (byte, 0U)
-         && known_eq (SUBREG_BYTE (op), 0))
+         && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
+         && known_eq (SUBREG_BYTE (op),
+                      subreg_lowpart_offset (innermode, innermostmode)))
        return SUBREG_REG (op);
 
       /* Work out the memory offset of the final OUTERMODE value relative

Reply via email to