Skip extension on stack pointer since we can't turn

(insn 27 26 139 2 (parallel [
            (set (reg/f:SI 7 sp)
                (plus:SI (reg/f:SI 7 sp)
                    (const_int 16 [0x10])))
            (clobber (reg:CC 17 flags))
        ]) "x.ii":14:17 discrim 1 283 {*addsi_1}
     (expr_list:REG_ARGS_SIZE (const_int 0 [0])
        (nil)))
...
(insn 43 125 74 2 (set (reg/f:DI 6 bp [145])
        (zero_extend:DI (reg/f:SI 7 sp))) "x.ii":15:9 175 {*zero_extendsidi2}
     (nil))

into

(insn 27 26 155 2 (parallel [
            (set (reg:DI 6 bp)
                (zero_extend:DI (plus:SI (reg/f:SI 7 sp)
                        (const_int 16 [0x10]))))
            (clobber (reg:CC 17 flags))
        ]) "x.ii":14:17 discrim 1 296 {addsi_1_zext}
     (expr_list:REG_ARGS_SIZE (const_int 0 [0])
        (nil)))
(insn 155 27 139 2 (set (reg:DI 7 sp)
        (reg:DI 6 bp)) "x.ii":14:17 discrim 1 -1
     (nil))

without updating stack frame info.

gcc/

        PR rtl-optimization/118266
        * ree.cc (add_removable_extension): Skip extension on stack
        pointer.

gcc/testsuite/

        PR rtl-optimization/118266
        * gcc.target/i386/pr118266.c: New test.

Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
---
 gcc/ree.cc                               | 12 +++++++++++
 gcc/testsuite/gcc.target/i386/pr118266.c | 27 ++++++++++++++++++++++++
 2 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr118266.c

diff --git a/gcc/ree.cc b/gcc/ree.cc
index a44e8e5625b..653ee990b00 100644
--- a/gcc/ree.cc
+++ b/gcc/ree.cc
@@ -1113,6 +1113,18 @@ add_removable_extension (const_rtx expr, rtx_insn *insn,
       struct df_link *defs, *def;
       ext_cand *cand;
 
+      if (reg == stack_pointer_rtx)
+       {
+         if (dump_file)
+           {
+             fprintf (dump_file, "Cannot eliminate extension:\n");
+             print_rtl_single (dump_file, insn);
+             fprintf (dump_file, " because extension on stack pointer"
+                                 " isn't supported.\n");
+           }
+         return;
+       }
+
       /* Zero-extension of an undefined value is partly defined (it's
         completely undefined for sign-extension, though).  So if there exists
         a path from the entry to this zero-extension that leaves this register
diff --git a/gcc/testsuite/gcc.target/i386/pr118266.c 
b/gcc/testsuite/gcc.target/i386/pr118266.c
new file mode 100644
index 00000000000..4c83cd1a561
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr118266.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-require-effective-target maybe_x32 } */
+/* { dg-require-effective-target fopenacc } */
+/* { dg-options "-O2 -mx32 -fopenacc" } */
+
+typedef struct {
+  int a;
+  int b;
+  int c;
+} mystruct;
+int main_j;
+int
+main()
+{
+  mystruct *m = (mystruct *)__builtin_malloc (2*sizeof (mystruct)), *mref = m;
+#pragma acc enter data copyin(m[1])
+  for (int i; i < 9; i++) {
+#pragma acc parallel
+    for (; main_j;)
+      ;
+#pragma acc parallel loop copy(mref->b, m->c)
+    for (main_j = 0; main_j < 4; main_j++)
+      ;
+  }
+#pragma acc data copyout(m[ : 1])
+  __builtin_free(m);
+}
-- 
2.47.1

Reply via email to