From b570f48c3dfb9ca3d640467cff67e569904009d4 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Thu, 27 Feb 2025 08:48:18 +0100
Subject: [PATCH] alias: Perform offset arithmetics in poly_offset_int rather
 than poly_int64 [PR118819]

This PR is about ubsan error on the c - cx1 + cy1 evaluation in the first
hunk.

The following patch hopefully fixes that by doing the additions/subtractions
in poly_offset_int rather than poly_int64 and then converting back to poly_int64.
If it doesn't fit, -1 is returned (which means it is unknown if there is a conflict
or not).

2025-02-27  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/118819
	* alias.cc (memrefs_conflict_p): Perform arithmetics on c, xsize and
	ysize in poly_offset_int and return -1 if it is not representable in
	poly_int64.
---
 gcc/alias.cc | 68 +++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 57 insertions(+), 11 deletions(-)

diff --git a/gcc/alias.cc b/gcc/alias.cc
index 497c2ac0e33a..4f17664c15b3 100644
--- a/gcc/alias.cc
+++ b/gcc/alias.cc
@@ -2535,19 +2535,39 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
 	    return memrefs_conflict_p (xsize, x1, ysize, y1, c);
 	  if (poly_int_rtx_p (x1, &cx1))
 	    {
+	      poly_offset_int co = c;
+	      co -= cx1;
 	      if (poly_int_rtx_p (y1, &cy1))
-		return memrefs_conflict_p (xsize, x0, ysize, y0,
-					   c - cx1 + cy1);
+		{
+		  co += cy1;
+		  if (!co.to_shwi (&c))
+		    return -1;
+		  return memrefs_conflict_p (xsize, x0, ysize, y0, c);
+		}
+	      else if (!co.to_shwi (&c))
+		return -1;
 	      else
-		return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
+		return memrefs_conflict_p (xsize, x0, ysize, y, c);
 	    }
 	  else if (poly_int_rtx_p (y1, &cy1))
-	    return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
+	    {
+	      poly_offset_int co = c;
+	      co += cy1;
+	      if (!co.to_shwi (&c))
+		return -1;
+	      return memrefs_conflict_p (xsize, x, ysize, y0, c);
+	    }
 
 	  return -1;
 	}
       else if (poly_int_rtx_p (x1, &cx1))
-	return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1);
+	{
+	  poly_offset_int co = c;
+	  co -= cx1;
+	  if (!co.to_shwi (&c))
+	    return -1;
+	  return memrefs_conflict_p (xsize, x0, ysize, y, c);
+	}
     }
   else if (GET_CODE (y) == PLUS)
     {
@@ -2563,7 +2583,13 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
 
       poly_int64 cy1;
       if (poly_int_rtx_p (y1, &cy1))
-	return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1);
+	{
+	  poly_offset_int co = c;
+	  co += cy1;
+	  if (!co.to_shwi (&c))
+	    return -1;
+	  return memrefs_conflict_p (xsize, x, ysize, y0, c);
+	}
       else
 	return -1;
     }
@@ -2616,8 +2642,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
 	  if (maybe_gt (xsize, 0))
 	    xsize = -xsize;
 	  if (maybe_ne (xsize, 0))
-	    xsize += sc + 1;
-	  c -= sc + 1;
+	    {
+	      poly_offset_int xsizeo = xsize;
+	      xsizeo += sc + 1;
+	      if (!xsizeo.to_shwi (&xsize))
+		return -1;
+	    }
+	  poly_offset_int co = c;
+	  co -= sc + 1;
+	  if (!co.to_shwi (&c))
+	    return -1;
 	  return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
 				     ysize, y, c);
 	}
@@ -2631,8 +2665,16 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
 	  if (maybe_gt (ysize, 0))
 	    ysize = -ysize;
 	  if (maybe_ne (ysize, 0))
-	    ysize += sc + 1;
-	  c += sc + 1;
+	    {
+	      poly_offset_int ysizeo = ysize;
+	      ysizeo += sc + 1;
+	      if (!ysizeo.to_shwi (&ysize))
+		return -1;
+	    }
+	  poly_offset_int co = c;
+	  co += sc + 1;
+	  if (!co.to_shwi (&c))
+	    return -1;
 	  return memrefs_conflict_p (xsize, x,
 				     ysize, canon_rtx (XEXP (y, 0)), c);
 	}
@@ -2643,7 +2685,11 @@ memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y,
       poly_int64 cx, cy;
       if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy))
 	{
-	  c += cy - cx;
+	  poly_offset_int co = c;
+	  co += cy;
+	  co -= cx;
+	  if (!co.to_shwi (&c))
+	    return -1;
 	  return offset_overlap_p (c, xsize, ysize);
 	}
 
-- 
GitLab