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.
jeff
PR rtl-optimization/115877
gcc/
* ext-dce.cc (ext_dce_process_uses): Restore the value of DST_MASK
for reach operand.
diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc
index 6d4b8858ec6..c4c38659701 100644
--- a/gcc/ext-dce.cc
+++ b/gcc/ext-dce.cc
@@ -591,8 +678,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. */