From: Kyrylo Tkachov <[email protected]>
create_tmp_var_raw marks a replacement declaration as ignored. At -O0,
this can change use_register_for_decl from memory for the original user
declaration to a pseudo for the replacement. A partition can already own
memory from a parameter default definition, which then makes set_rtl reject
that memory for another name in the partition.
If the replacement would use a register, copy DECL_IGNORED_P so it keeps the
storage choice made during coalescing. Keep declarations that already use
memory unchanged. Add a checking assertion for the memory invariant.
Bootstrapped and tested on aarch64-none-linux-gnu and x86_64-linux.
Pushed as per Richard's approval.
gcc/ChangeLog:
PR middle-end/126341
* tree-outof-ssa.cc (split_overlapping_partition_decls): Preserve
DECL_IGNORED_P. Check that the replacement uses memory.
gcc/testsuite/ChangeLog:
PR middle-end/126341
* gcc.dg/pr126341.c: New test.
Signed-off-by: Kyrylo Tkachov <[email protected]>
---
gcc/testsuite/gcc.dg/pr126341.c | 53 +++++++++++++++++++++++++++++++++
gcc/tree-outof-ssa.cc | 5 ++++
2 files changed, 58 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/pr126341.c
diff --git a/gcc/testsuite/gcc.dg/pr126341.c b/gcc/testsuite/gcc.dg/pr126341.c
new file mode 100644
index 00000000000..76ed1d889e4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr126341.c
@@ -0,0 +1,53 @@
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-fnon-call-exceptions -ftree-coalesce-vars" } */
+/* { dg-prune-output "division by zero" } */
+
+/* PR middle-end/126341 */
+
+#define N 0x200000000uwb
+#define DIV0 (1 / 0)
+
+struct {
+ char j[8];
+} k;
+char l;
+int m, p, q, r;
+long n;
+_Complex o;
+int s;
+_BitInt (256) aa;
+
+void
+foo (_BitInt (8) t)
+{
+ int ah, ai, aj = 1, ak, al = 1, am = 1, an = 1, ao = 1, ap = 1, aq = DIV0;
+ int ar = 1, as = 1, at, au = DIV0;
+ int av = 1;
+ _BitInt (7) c = ak--;
+ char aw = 1, ax = 1, ay = 1, az = 1, a = 1, d = 1, e = 1;
+ int bfbg = 1, bh = 1, bi = p += ai -= __sync_add_and_fetch (&s, 1);
+ int bj;
+ int bk, blbm = 1, bt = 1, bu = 1, bv = __atomic_or_fetch (&aa, 1, 1);
+ int bn = 1, bobp = 1, br = 1, bs = 1;
+ unsigned b, cc;
+ char cf, ce;
+
+ if (bj)
+ goto ca;
+ b = 1, cc = 1;
+ for (;;);
+ ce = q;
+ cf = o ? 1
+ :
+ __builtin_stdc_rotate_left (__builtin_stdc_rotate_left
+ (c - 0x3bfuwb, br), n & 1) ? 3 : 3;
+ 1 +
+ az & 1 | N << -az & m | ((az & 1 | N) << -az & 1 ? 0 : 7u) & 1 |
+ ((az & 1 | N) - az & m | az & 1 | N) < 7 > -c & 1;
+ca:
+ s %= __builtin_stdc_rotate_left (cc, ah);
+ at /= r ^= ({ __auto_type cg = 0; __auto_type ch = 0; 0; });
+
+ long ci = bk % cf;
+ _BitInt (8) cj = l ? t : k.j[3];
+}
diff --git a/gcc/tree-outof-ssa.cc b/gcc/tree-outof-ssa.cc
index 918dbbedde3..17d5e70e71d 100644
--- a/gcc/tree-outof-ssa.cc
+++ b/gcc/tree-outof-ssa.cc
@@ -1101,6 +1101,11 @@ split_overlapping_partition_decls (var_map map)
continue;
tree nvar = create_tmp_var_raw (TREE_TYPE (var));
+ /* Avoid a register-only NVAR when the partition already has a MEM,
+ since set_rtl cannot assign that MEM to NVAR. */
+ if (use_register_for_decl (nvar))
+ DECL_IGNORED_P (nvar) = DECL_IGNORED_P (var);
+ gcc_checking_assert (!use_register_for_decl (nvar));
DECL_CONTEXT (nvar) = DECL_CONTEXT (var);
DECL_SOURCE_LOCATION (nvar) = DECL_SOURCE_LOCATION (var);
SET_DECL_ALIGN (nvar, DECL_ALIGN (var));
--
2.50.1 (Apple Git-155)