aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-03-08 13:27:12 +0100
committerRichard Biener <rguenther@suse.de>2024-03-08 14:40:57 +0100
commit018ddc86b928514d7dfee024dcdeb204d5dcdd61 (patch)
tree84e03953ae9dee92598d740269a1bfd5573c625a
parent3cdaa6491fe805ffc1dc545722b97660f31572fa (diff)
downloadgcc-018ddc86b928514d7dfee024dcdeb204d5dcdd61.zip
gcc-018ddc86b928514d7dfee024dcdeb204d5dcdd61.tar.gz
gcc-018ddc86b928514d7dfee024dcdeb204d5dcdd61.tar.bz2
tree-optimization/114269 - 434.zeusmp regression after SCEV analysis fix
The following addresses a performance regression caused by the recent SCEV analysis fix with regard to folding multiplications and undefined behavior on overflow. We do not handle (T) { a, +, b } * c but can treat sign-conversions from unsigned by performing the multiplication in the unsigned type. That's what we already do for additions (but that misses one case that turns out important). This fixes the 434.zeusmp regression for me. PR tree-optimization/114269 PR tree-optimization/114074 * tree-chrec.cc (chrec_fold_plus_1): Handle sign-conversions in the third CASE_CONVERT case as well. (chrec_fold_multiply): Handle sign-conversions from unsigned by performing the operation in the unsigned type.
-rw-r--r--gcc/tree-chrec.cc48
1 files changed, 48 insertions, 0 deletions
diff --git a/gcc/tree-chrec.cc b/gcc/tree-chrec.cc
index 2e6c735..7cd0ebc 100644
--- a/gcc/tree-chrec.cc
+++ b/gcc/tree-chrec.cc
@@ -325,6 +325,22 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
: build_int_cst_type (type, -1)));
CASE_CONVERT:
+ {
+ /* We can strip sign-conversions to signed by performing the
+ operation in unsigned. */
+ tree optype = TREE_TYPE (TREE_OPERAND (op1, 0));
+ if (INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (optype)
+ && tree_nop_conversion_p (type, optype)
+ && TYPE_UNSIGNED (optype))
+ return chrec_convert (type,
+ chrec_fold_plus_1 (code, optype,
+ chrec_convert (optype,
+ op0, NULL),
+ TREE_OPERAND (op1, 0)),
+ NULL);
+ }
+
if (tree_contains_chrecs (op1, NULL))
return chrec_dont_know;
/* FALLTHRU */
@@ -424,6 +440,22 @@ chrec_fold_multiply (tree type,
return chrec_fold_multiply_poly_poly (type, op0, op1);
CASE_CONVERT:
+ {
+ /* We can strip sign-conversions to signed by performing the
+ operation in unsigned. */
+ tree optype = TREE_TYPE (TREE_OPERAND (op1, 0));
+ if (INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (optype)
+ && tree_nop_conversion_p (type, optype)
+ && TYPE_UNSIGNED (optype))
+ return chrec_convert (type,
+ chrec_fold_multiply (optype,
+ chrec_convert (optype,
+ op0, NULL),
+ TREE_OPERAND (op1, 0)),
+ NULL);
+ }
+
if (tree_contains_chrecs (op1, NULL))
return chrec_dont_know;
/* FALLTHRU */
@@ -474,6 +506,22 @@ chrec_fold_multiply (tree type,
}
CASE_CONVERT:
+ {
+ /* We can strip sign-conversions to signed by performing the
+ operation in unsigned. */
+ tree optype = TREE_TYPE (TREE_OPERAND (op0, 0));
+ if (INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (optype)
+ && tree_nop_conversion_p (type, optype)
+ && TYPE_UNSIGNED (optype))
+ return chrec_convert (type,
+ chrec_fold_multiply (optype,
+ TREE_OPERAND (op0, 0),
+ chrec_convert (optype,
+ op1, NULL)),
+ NULL);
+ }
+
if (tree_contains_chrecs (op0, NULL))
return chrec_dont_know;
/* FALLTHRU */