aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <oliva@adacore.com>2023-12-19 22:17:42 -0300
committerAlexandre Oliva <oliva@gnu.org>2023-12-20 05:18:15 -0300
commit672db38c6f0723ca57fe8ff4c43422341e7fb857 (patch)
tree154ca1933e75600312873fabd52fc27b500fdb82
parent438bf6ade4b089d592ec481086cde664a1ea1f3d (diff)
downloadgcc-672db38c6f0723ca57fe8ff4c43422341e7fb857.zip
gcc-672db38c6f0723ca57fe8ff4c43422341e7fb857.tar.gz
gcc-672db38c6f0723ca57fe8ff4c43422341e7fb857.tar.bz2
-finline-stringops: allow expansion into edges [PR113002]
Builtin expanders for memset and memcpy may involve conditionals and loops, but their sequences may be end up emitted in edges. Alas, commit_one_edge_insertion rejects sequences that end with a jump, a requirement that makes sense for insertions after expand, but not so much during expand. During expand, jumps may appear in the middle of the insert sequence as much as in the end, and it's only after committing edge insertions out of PHI nodes that we go through the entire function splitting blocks where needed, so relax the assert in commit_one_edge_insertion so that jumps are accepted during expand even at the end of the sequence. for gcc/ChangeLog PR rtl-optimization/113002 * cfgrtl.cc (commit_one_edge_insertion): Tolerate jumps in the inserted sequence during expand. for gcc/testsuite/ChangeLog PR rtl-optimization/113002 * gcc.dg/vect/pr113002.c: New.
-rw-r--r--gcc/cfgrtl.cc8
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr113002.c13
2 files changed, 20 insertions, 1 deletions
diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc
index 2a3f853..437eb3a 100644
--- a/gcc/cfgrtl.cc
+++ b/gcc/cfgrtl.cc
@@ -2092,7 +2092,13 @@ commit_one_edge_insertion (edge e)
delete_insn (before);
}
else
- gcc_assert (!JUMP_P (last));
+ /* Some builtin expanders, such as those for memset and memcpy,
+ may generate loops and conditionals, and those may get emitted
+ into edges. That's ok while expanding to rtl, basic block
+ boundaries will be identified and split afterwards. ??? Need
+ we check whether the destination labels of any inserted jumps
+ are also part of the inserted sequence? */
+ gcc_assert (!JUMP_P (last) || currently_expanding_to_rtl);
}
/* Update the CFG for all queued instructions. */
diff --git a/gcc/testsuite/gcc.dg/vect/pr113002.c b/gcc/testsuite/gcc.dg/vect/pr113002.c
new file mode 100644
index 0000000..186710f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr113002.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-finline-stringops -Os" } */
+
+typedef __int128 v64u128 __attribute__((vector_size(64)));
+int c;
+v64u128 u;
+void foo() {
+ if (c)
+ u = (v64u128){0};
+ else
+ u = (v64u128){1};
+}