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" } } */