]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix extra_off mis-computation during aggregate copy VN
authorRichard Biener <rguenther@suse.de>
Mon, 12 Jan 2026 09:36:44 +0000 (10:36 +0100)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 12 Jan 2026 11:40:12 +0000 (12:40 +0100)
With the rewrite of aggregate copy handling in r16-2729-g0d276cd378e7a4
there's an error introduced which accumulates extra_off even if we
throw away some of the tentative component consumption.  The following
fixes this.

* tree-ssa-sccvn.cc (vn_reference_lookup_3): Only tentatively
accumulate extra_off when tentatively consuming components
during aggregate copy handling.

gcc/tree-ssa-sccvn.cc

index 16343d2a407f6a8635a661b0de697479ff2f491a..ed87ffc22862b2d590eaafd51e32ecda58334d4e 100644 (file)
@@ -3615,7 +3615,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
          if (i > 0)
            {
              int temi = i - 1;
-             extra_off = vr->operands[i].off;
+             poly_int64 tem_extra_off = extra_off + vr->operands[i].off;
              while (temi >= 0
                     && known_ne (vr->operands[temi].off, -1))
                {
@@ -3627,20 +3627,21 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
                      i = temi;
                      /* Strip the component that was type matched to
                         the MEM_REF.  */
-                     extra_off += vr->operands[i].off - lhs_ops[j].off;
+                     extra_off = (tem_extra_off
+                                  + vr->operands[i].off - lhs_ops[j].off);
                      i--, j--;
                      /* Strip further equal components.  */
                      found = true;
                      break;
                    }
-                 extra_off += vr->operands[temi].off;
+                 tem_extra_off += vr->operands[temi].off;
                  temi--;
                }
            }
          if (!found && j > 0)
            {
              int temj = j - 1;
-             extra_off = -lhs_ops[j].off;
+             poly_int64 tem_extra_off = extra_off - lhs_ops[j].off;
              while (temj >= 0
                     && known_ne (lhs_ops[temj].off, -1))
                {
@@ -3652,13 +3653,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
                      j = temj;
                      /* Strip the component that was type matched to
                         the MEM_REF.  */
-                     extra_off += vr->operands[i].off - lhs_ops[j].off;
+                     extra_off = (tem_extra_off
+                                  + vr->operands[i].off - lhs_ops[j].off);
                      i--, j--;
                      /* Strip further equal components.  */
                      found = true;
                      break;
                    }
-                 extra_off += -lhs_ops[temj].off;
+                 tem_extra_off += -lhs_ops[temj].off;
                  temj--;
                }
            }