https://gcc.gnu.org/g:16ec69161c3a3537076cea467e3622bb4a2550d0

commit 16ec69161c3a3537076cea467e3622bb4a2550d0
Author: Jeff Law <j...@ventanamicro.com>
Date:   Sun Jul 21 07:36:37 2024 -0600

    [PR rtl-optimization/115877] Fix livein computation for ext-dce
    
    So I'm not yet sure how I'm going to break everything down, but this is easy
    enough to break out as 1/N of ext-dce fixes/improvements.
    
    When handling uses in an insn, we first determine what bits are set in the
    destination which is represented in DST_MASK.  Then we use that to refine 
what
    bits are live in the source operands.
    
    In the source operand handling section we *modify* DST_MASK if the source
    operand is a SUBREG (ugh!).  So if the first operand is a SUBREG, then we 
can
    incorrectly compute which bit groups are live in the second operand, 
especially
    if it is a SUBREG as well.
    
    This was seen when testing a larger set of patches on the rl78 port
    (builtin-arith-overflow-p-7 & pr71631 execution failures), so no new test 
for
    this bugfix.
    
    Run through my tester (in conjunction with other ext-dce changes) on the
    various cross targets.  Run individually through a bootstrap and regression
    test cycle on x86_64 as well.
    
    Pushing to the trunk.
    
            PR rtl-optimization/115877
    gcc/
            * ext-dce.cc (ext_dce_process_uses): Restore the value of DST_MASK
            for reach operand.
    
    (cherry picked from commit 91e468b72dafc9dcd5dcf7915f1d0ef172264d53)

Diff:
---
 gcc/ext-dce.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc
index 7270de2a3bf..d431f8ac12d 100644
--- a/gcc/ext-dce.cc
+++ b/gcc/ext-dce.cc
@@ -591,8 +591,10 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj, bitmap 
live_tmp)
                 making things live.  Breaking from this loop will cause
                 the iterator to work on sub-rtxs, so it is safe to break
                 if we see something we don't know how to handle.  */
+             unsigned HOST_WIDE_INT save_mask = dst_mask;
              for (;;)
                {
+                 dst_mask = save_mask;
                  /* Strip an outer paradoxical subreg.  The bits outside
                     the inner mode are don't cares.  So we can just strip
                     and process the inner object.  */

Reply via email to