re PR middle-end/78468 (libgomp.c/reduction-10.c and many more FAIL)
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 13 Dec 2017 23:16:56 +0000 (23:16 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 13 Dec 2017 23:16:56 +0000 (23:16 +0000)
PR middle-end/78468
* emit-rtl.c (init_emit): Remove ??? comment.
* explow.c (get_dynamic_stack_size): Take known alignment of stack
pointer + STACK_DYNAMIC_OFFSET into account in lieu of STACK_BOUNDARY.
* config/sparc/sparc.h (INIT_EXPANDERS): In 32-bit mode, lower the
alignment of 3 virtual registers to BITS_PER_WORD.

* config/sparc/sparc.c (sparc_compute_frame_size): Simplify.

Co-Authored-By: Dominik Vogt <vogt@linux.vnet.ibm.com>
From-SVN: r255616

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/emit-rtl.c
gcc/explow.c

index c47696cd8a03661006f77ead9e81da9136a060b1..272bb7696f2f28654437bd29d33c756073dcb495 100644 (file)
@@ -1,3 +1,15 @@
+2017-12-13  Eric Botcazou  <ebotcazou@adacore.com>
+            Dominik Vogt  <vogt@linux.vnet.ibm.com>
+
+       PR middle-end/78468
+       * emit-rtl.c (init_emit): Remove ??? comment.
+       * explow.c (get_dynamic_stack_size): Take known alignment of stack
+       pointer + STACK_DYNAMIC_OFFSET into account in lieu of STACK_BOUNDARY.
+       * config/sparc/sparc.h (INIT_EXPANDERS): In 32-bit mode, lower the
+       alignment of 3 virtual registers to BITS_PER_WORD.
+
+       * config/sparc/sparc.c (sparc_compute_frame_size): Simplify.
+
 2017-12-13  Peter Bergner  <bergner@vnet.ibm.com>
 
        * config/rs6000/ppc-auxv.h (PPC_FEATURE2_HTM_NO_SUSPEND): New define.
index a8d363ce571dc7cf5d7beb09556d8d77044d394b..890bde9fc0add5a04b9d4e9b5ac6c35a7c6ad392 100644 (file)
@@ -5483,10 +5483,8 @@ sparc_compute_frame_size (HOST_WIDE_INT size, int leaf_function)
     frame_size = apparent_frame_size = 0;
   else
     {
-      /* We subtract TARGET_STARTING_FRAME_OFFSET, remember it's negative.  */
-      apparent_frame_size
-       = ROUND_UP (size - targetm.starting_frame_offset (), 8);
-      apparent_frame_size += n_global_fp_regs * 4;
+      /* Start from the apparent frame size.  */
+      apparent_frame_size = ROUND_UP (size, 8) + n_global_fp_regs * 4;
 
       /* We need to add the size of the outgoing argument area.  */
       frame_size = apparent_frame_size + ROUND_UP (args_size, 8);
index a0b56126fd51fe4eedd6677cbac744fb0d443340..3d8e198b30781078369e2a6b579adbf03d62b1cf 100644 (file)
@@ -771,13 +771,29 @@ extern enum cmodel sparc_cmodel;
 /* The soft frame pointer does not have the stack bias applied.  */
 #define FRAME_POINTER_REGNUM 101
 
-/* Given the stack bias, the stack pointer isn't actually aligned.  */
 #define INIT_EXPANDERS                                                  \
   do {                                                                  \
-    if (crtl->emit.regno_pointer_align && SPARC_STACK_BIAS)     \
+    if (crtl->emit.regno_pointer_align)                                         \
       {                                                                         \
-       REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = BITS_PER_UNIT;      \
-       REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT; \
+       /* The biased stack pointer is only aligned on BITS_PER_UNIT.  */\
+       if (SPARC_STACK_BIAS)                                            \
+         {                                                              \
+           REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM)                   \
+             = BITS_PER_UNIT;                                           \
+           REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM)              \
+             = BITS_PER_UNIT;                                           \
+         }                                                              \
+                                                                        \
+       /* In 32-bit mode, not everything is double-word aligned.  */    \
+       if (TARGET_ARCH32)                                               \
+         {                                                              \
+           REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM)           \
+             = BITS_PER_WORD;                                           \
+           REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM)           \
+             = BITS_PER_WORD;                                           \
+           REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM)           \
+             = BITS_PER_WORD;                                           \
+         }                                                              \
       }                                                                         \
   } while (0)
 
index 42de598067f46de8d456727520e1a698aacb588c..5ab1fb79085b42de3b82102a9fbf24855c899ea3 100644 (file)
@@ -5764,8 +5764,6 @@ init_emit (void)
   REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
   REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY;
 
-  /* ??? These are problematic (for example, 3 out of 4 are wrong on
-     32-bit SPARC and cannot be all fixed because of the ABI).  */
   REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM) = STACK_BOUNDARY;
   REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM) = STACK_BOUNDARY;
   REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) = STACK_BOUNDARY;
index e2c8e459a43d6ec2fb3dc965a991146730401d32..696f06673eb71f3033d00fac2b529bbfee45cc54 100644 (file)
@@ -1206,7 +1206,6 @@ get_dynamic_stack_size (rtx *psize, unsigned size_align,
                        unsigned required_align,
                        HOST_WIDE_INT *pstack_usage_size)
 {
-  unsigned extra = 0;
   rtx size = *psize;
 
   /* Ensure the size is in the proper mode.  */
@@ -1242,16 +1241,16 @@ get_dynamic_stack_size (rtx *psize, unsigned size_align,
      example), so we must preventively align the value.  We leave space
      in SIZE for the hole that might result from the alignment operation.  */
 
-  /* Since the stack is presumed to be aligned before this allocation,
-     we only need to increase the size of the allocation if the required
-     alignment is more than the stack alignment.  */
-  if (required_align > STACK_BOUNDARY)
+  unsigned known_align = REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM);
+  if (known_align == 0)
+    known_align = BITS_PER_UNIT;
+  if (required_align > known_align)
     {
-      extra = (required_align - STACK_BOUNDARY) / BITS_PER_UNIT;
+      unsigned extra = (required_align - known_align) / BITS_PER_UNIT;
       size = plus_constant (Pmode, size, extra);
       size = force_operand (size, NULL_RTX);
-      if (size_align > STACK_BOUNDARY)
-       size_align = STACK_BOUNDARY;
+      if (size_align > known_align)
+       size_align = known_align;
 
       if (flag_stack_usage_info && pstack_usage_size)
        *pstack_usage_size += extra;