https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66313

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mpolacek at gcc dot gnu.org

--- Comment #2 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Done in this patch.  I don't claim it's beautiful, but oh well.

diff --git gcc/fold-const.c gcc/fold-const.c
index 61eee4a..ce4e989 100644
--- gcc/fold-const.c
+++ gcc/fold-const.c
@@ -7050,11 +7050,18 @@ fold_plusminus_mult_expr (location_t loc, enum
tree_code code, tree type,
     }

   if (same)
-    return fold_build2_loc (loc, MULT_EXPR, type,
-                       fold_build2_loc (loc, code, type,
-                                    fold_convert_loc (loc, type, alt0),
-                                    fold_convert_loc (loc, type, alt1)),
-                       fold_convert_loc (loc, type, same));
+    {
+      /* Perform the expression in unsigned type to avoid introducing
+        undefined behavior, then convert it back to the original type.  */
+      tree utype = unsigned_type_for (type);
+      utype = utype ? utype : type;
+      tree op0 = fold_build2_loc (loc, code, utype,
+                                 fold_convert_loc (loc, utype, alt0),
+                                 fold_convert_loc (loc, utype, alt1));
+      tree op1 = fold_convert_loc (loc, utype, same);
+      return fold_convert_loc (loc, type, fold_build2_loc (loc, MULT_EXPR,
+                                                          utype, op0, op1));
+    }

   return NULL_TREE;
 }
diff --git gcc/testsuite/gcc.dg/fold-plusmult-2.c
gcc/testsuite/gcc.dg/fold-plusmult-2.c
index 82f9898..c74688b 100644
--- gcc/testsuite/gcc.dg/fold-plusmult-2.c
+++ gcc/testsuite/gcc.dg/fold-plusmult-2.c
@@ -16,4 +16,4 @@ int bar (int i)
 /* But eventually this to be canonicalized to (i + 2) * 2.  */

 /* { dg-final { scan-tree-dump "i \\\* 4 \\\+ 2" "original" } } */
-/* { dg-final { scan-tree-dump "\\\(i \\\+ 2\\\) \\\* 2" "original" } } */
+/* { dg-final { scan-tree-dump "i \\\+ 2\\\) \\\* 2" "original" } } */
diff --git gcc/testsuite/gcc.dg/fold-plusmult.c
gcc/testsuite/gcc.dg/fold-plusmult.c
index 1781552..f30fcbf 100644
--- gcc/testsuite/gcc.dg/fold-plusmult.c
+++ gcc/testsuite/gcc.dg/fold-plusmult.c
@@ -11,4 +11,4 @@ int test2 (int a)
   return (a + a)*2;
 }

-/* { dg-final { scan-tree-dump-times "<a> \\\* 4" 2 "original" } } */
+/* { dg-final { scan-tree-dump-times "a.? \\\* 4" 2 "original" } } */

Reply via email to