diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-01-05 19:13:29 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-01-05 19:13:29 +0100 |
commit | 5de7bf5bc98ec9edc6838a443521204d0eca7605 (patch) | |
tree | 388829cc39978cb2685f30f05b83652575aec353 /gcc/cfgexpand.c | |
parent | 6b577a17b26347e78c8b9167f24fc5c9d9724270 (diff) | |
download | gcc-5de7bf5bc98ec9edc6838a443521204d0eca7605.zip gcc-5de7bf5bc98ec9edc6838a443521204d0eca7605.tar.gz gcc-5de7bf5bc98ec9edc6838a443521204d0eca7605.tar.bz2 |
expand: Fold x - y < 0 to x < y during expansion [PR94802]
My earlier patch to simplify x - y < 0 etc. for signed subtraction
with undefined overflow into x < y in match.pd regressed some tests,
even when it was guarded to be post-IPA, the following patch thus
attempts to optimize that during expansion instead (which is the last
time we can do it, afterwards we lose the information whether it was
x - y < 0 or (int) ((unsigned) x - y) < 0 for which we couldn't
optimize it.
2021-01-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94802
* expr.h (maybe_optimize_sub_cmp_0): Declare.
* expr.c: Include tree-pretty-print.h and flags.h.
(maybe_optimize_sub_cmp_0): New function.
(do_store_flag): Use it.
* cfgexpand.c (expand_gimple_cond): Likewise.
* gcc.target/i386/pr94802.c: New test.
* gcc.dg/Wstrict-overflow-25.c: Remove xfail.
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r-- | gcc/cfgexpand.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 1d3f96f..b73019b 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2621,6 +2621,14 @@ expand_gimple_cond (basic_block bb, gcond *stmt) && TREE_CODE (op1) == INTEGER_CST) code = maybe_optimize_mod_cmp (code, &op0, &op1); + /* Optimize (x - y) < 0 into x < y if x - y has undefined overflow. */ + if (!TYPE_UNSIGNED (TREE_TYPE (op0)) + && (code == LT_EXPR || code == LE_EXPR + || code == GT_EXPR || code == GE_EXPR) + && integer_zerop (op1) + && TREE_CODE (op0) == SSA_NAME) + maybe_optimize_sub_cmp_0 (code, &op0, &op1); + last2 = last = get_last_insn (); extract_true_false_edges_from_block (bb, &true_edge, &false_edge); |