Re: Fix some x86 peepholes vs. the red-zone

2016-04-15 Thread Bernd Schmidt

On 04/15/2016 10:32 AM, Uros Bizjak wrote:

This fixes possible wrong code with a tricky failure mode, so OK now.


Thanks.

[...]


While changing this part, it can be rewritten using dg-additional options, e.g.:

/* { dg-options "-Os -fomit-frame-pointer -fasynchronous-unwind-tables
-mno-red-zone" } */
/* { dg-additional-options "-mpreferred-stack-boundary=3" { target ia32 } } */


Since Jakub mentioned branching today, and I wasn't sure I'd have time 
for a retest, I've committed it as-is.



Bernd


Re: Fix some x86 peepholes vs. the red-zone

2016-04-14 Thread Jeff Law

On 04/12/2016 05:57 AM, Bernd Schmidt wrote:

With some changes I was working on, I produced a situation where one of
the x86 peepholes made an incorrect transformation. In the prologue
expansion code, we have

/* When using red zone we may start register saving before allocating
the stack frame saving one cycle of the prologue.  However, avoid
doing this if we have to probe the stack; at least on x86_64 the
stack probe can turn into a call that clobbers a red zone location.

So, we can in some situations produce something like:

mov %ebx, -8(%rsp)
mov %edi, -16(%rsp)
subl $16, %rsp

which is fine if using a redzone. The problem is that there are
peepholes which convert sp subtractions into pushes, clobbering the
saved registers.

I've made these peepholes conditional on !x86_using_red_zone.
Bootstrapped and tested on x86_64-linux, ok (now or later)?

OK for stage1.  Uros's call whether or not to OK for the trunk right now.

jeff


Fix some x86 peepholes vs. the red-zone

2016-04-12 Thread Bernd Schmidt
With some changes I was working on, I produced a situation where one of 
the x86 peepholes made an incorrect transformation. In the prologue 
expansion code, we have


/* When using red zone we may start register saving before allocating
   the stack frame saving one cycle of the prologue.  However, avoid
   doing this if we have to probe the stack; at least on x86_64 the
   stack probe can turn into a call that clobbers a red zone location.

So, we can in some situations produce something like:

mov %ebx, -8(%rsp)
mov %edi, -16(%rsp)
subl $16, %rsp

which is fine if using a redzone. The problem is that there are 
peepholes which convert sp subtractions into pushes, clobbering the 
saved registers.


I've made these peepholes conditional on !x86_using_red_zone. 
Bootstrapped and tested on x86_64-linux, ok (now or later)?



Bernd
	* config/i386/i386-protos.h (ix86_using_red_zone): Declare.
	* config/i386/i386.c (ix86_using_red_zone): No longer static.
	* config/i386/i386.md (stack decrement to push peepholes): Guard
	with !x86_using_red_zone ().

testsuite/
	* gcc.target/i386/pr46470.c: Add -mno-red-zone to dg-optios for
	x86_64.

Index: gcc/config/i386/i386-protos.h
===
--- gcc/config/i386/i386-protos.h	(revision 234831)
+++ gcc/config/i386/i386-protos.h	(working copy)
@@ -44,6 +44,8 @@ extern bool ix86_use_pseudo_pic_reg (voi
 
 extern void ix86_reset_previous_fndecl (void);
 
+extern bool ix86_using_red_zone (void);
+
 #ifdef RTX_CODE
 extern int standard_80387_constant_p (rtx);
 extern const char *standard_80387_constant_opcode (rtx);
Index: gcc/config/i386/i386.c
===
--- gcc/config/i386/i386.c	(revision 234831)
+++ gcc/config/i386/i386.c	(working copy)
@@ -3709,7 +3709,7 @@ make_pass_stv (gcc::context *ctxt)
 
 /* Return true if a red-zone is in use.  */
 
-static inline bool
+bool
 ix86_using_red_zone (void)
 {
   return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI;
Index: gcc/config/i386/i386.md
===
--- gcc/config/i386/i386.md	(revision 234831)
+++ gcc/config/i386/i386.md	(working copy)
@@ -18240,7 +18240,8 @@ (define_peephole2
 	  (clobber (reg:CC FLAGS_REG))
 	  (clobber (mem:BLK (scratch)))])]
   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
-   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
+   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
+   && !ix86_using_red_zone ()"
   [(clobber (match_dup 1))
(parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
 	  (clobber (mem:BLK (scratch)))])])
@@ -18253,7 +18254,8 @@ (define_peephole2
 	  (clobber (reg:CC FLAGS_REG))
 	  (clobber (mem:BLK (scratch)))])]
   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
-   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
+   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
+   && !ix86_using_red_zone ()"
   [(clobber (match_dup 1))
(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
@@ -18267,7 +18269,8 @@ (define_peephole2
 			   (match_operand:P 0 "const_int_operand")))
 	  (clobber (reg:CC FLAGS_REG))])]
   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
-   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
+   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
+   && !ix86_using_red_zone ()"
   [(clobber (match_dup 1))
(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
 
@@ -18278,7 +18281,8 @@ (define_peephole2
 			   (match_operand:P 0 "const_int_operand")))
 	  (clobber (reg:CC FLAGS_REG))])]
   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
-   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
+   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
+   && !ix86_using_red_zone ()"
   [(clobber (match_dup 1))
(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
Index: gcc/testsuite/gcc.target/i386/pr46470.c
===
--- gcc/testsuite/gcc.target/i386/pr46470.c	(revision 234831)
+++ gcc/testsuite/gcc.target/i386/pr46470.c	(working copy)
@@ -4,7 +4,7 @@
 /* These options are selected to ensure 1 word needs to be allocated
on the stack to maintain alignment for the call.  This should be
transformed to push+pop.  We also want to force unwind info updates.  */
-/* { dg-options "-Os -fomit-frame-pointer -fasynchronous-unwind-tables" } */
+/* { dg-options "-Os -fomit-frame-pointer -fasynchronous-unwind-tables -mno-red-zone" } */
 /* { dg-options "-Os -fomit-frame-pointer -mpreferred-stack-boundary=3 -fasynchronous-unwind-tables" { target ia32 } } */
 /* ms_abi has reserved stack-region.  */
 /* { dg-skip-if "" { x86_64-*-mingw* } { "*" } { "" } } */