As the test case shows, the outer mode may have a higher alignment
requirement than the inner mode here.

2021-04-22  Bernd Edlinger  <bernd.edlin...@hotmail.de>

        PR target/100106
        * gimplify-rtx.c (simplify_context::simplify_subreg): Check the
        memory alignment for the outer mode.

        * gcc.c-torture/compile/pr100106.c: New testcase.
---
 gcc/simplify-rtx.c                             |  1 +
 gcc/testsuite/gcc.c-torture/compile/pr100106.c | 11 +++++++++++
 2 files changed, 12 insertions(+)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr100106.c

diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index d13c390..ad3b7b2 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -7217,6 +7217,7 @@ simplify_context::simplify_subreg (machine_mode 
outermode, rtx op,
          have instruction to move the whole thing.  */
       && (! MEM_VOLATILE_P (op)
          || ! have_insn_for (SET, innermode))
+      && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
       && known_le (outersize, innersize))
     return adjust_address_nv (op, outermode, byte);
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr100106.c 
b/gcc/testsuite/gcc.c-torture/compile/pr100106.c
new file mode 100644
index 0000000..7f98b4f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr100106.c
@@ -0,0 +1,11 @@
+union a {
+  float _Complex b;
+  long long c;
+};
+
+void g(union a);
+
+void e() {
+  union a f = {1.0f};
+  g(f);
+}
-- 
1.9.1

Reply via email to