------- Comment #10 from jh at suse dot cz  2005-10-18 18:17 -------
Subject: Re:  ix86 prologue clobbers memory when it shouldn't

> 
> 
> ------- Comment #9 from hjl at lucon dot org  2005-10-18 17:50 -------
> We only run into the problem with red zone enabled, which is x86-64. We have
> 2 issues:
> 
> 1. When prologue uses mov, memory shouldn't be clobbered. But
> ix86_expand_prologue calls pro_epilogue_adjust_stack which clobbers
> memory.
> 2. We convert stack pointer subtractions to push even when memory isn't
> clobbered with patterns like
> 
> ;; Convert esp subtractions to push.
> (define_peephole2
>   [(match_scratch:SI 0 "r")
>    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int
> -4)))
>               (clobber (reg:CC FLAGS_REG))])]
>   "optimize_size || !TARGET_SUB_ESP_4"
>   [(clobber (match_dup 0))
>    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
> 
> I don't think we can do that since push will clobber memory.
Without red zone this is safe, but I see we do the conversion on 64bit
too that definitly is unsafe.  What about this patch?

Index: i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.655
diff -c -3 -p -r1.655 i386.md
*** i386.md     24 Sep 2005 15:47:57 -0000      1.655
--- i386.md     18 Oct 2005 18:16:00 -0000
***************
*** 19306,19316 ****
              (clobber (mem:BLK (scratch)))])])

  ;; Convert esp subtractions to push.
  (define_peephole2
    [(match_scratch:SI 0 "r")
     (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
              (clobber (reg:CC FLAGS_REG))])]
!   "optimize_size || !TARGET_SUB_ESP_4"
    [(clobber (match_dup 0))
     (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])

--- 19306,19320 ----
              (clobber (mem:BLK (scratch)))])])

  ;; Convert esp subtractions to push.
+ ;; This conversion is safe only under assumption that unallocated stack is
+ ;; implicitly clobbered as specified by 32bit ABI (for signal handlers and
such).
+ ;; This is not valid with red zone, but we can work harder and enable the
+ ;; optimization for functions that are not using it.
  (define_peephole2
    [(match_scratch:SI 0 "r")
     (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
              (clobber (reg:CC FLAGS_REG))])]
!   "(optimize_size || !TARGET_SUB_ESP_4) && !TARGET_RED_ZONE"
    [(clobber (match_dup 0))
     (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])

***************
*** 19318,19324 ****
    [(match_scratch:SI 0 "r")
     (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
              (clobber (reg:CC FLAGS_REG))])]
!   "optimize_size || !TARGET_SUB_ESP_8"
    [(clobber (match_dup 0))
     (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
     (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
--- 19322,19328 ----
    [(match_scratch:SI 0 "r")
     (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
              (clobber (reg:CC FLAGS_REG))])]
!   "(optimize_size || !TARGET_SUB_ESP_8) && !TARGET_RED_ZONE"
    [(clobber (match_dup 0))
     (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
     (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
***************
*** 19438,19448 ****
              (clobber (mem:BLK (scratch)))])])

  ;; Convert esp subtractions to push.
  (define_peephole2
    [(match_scratch:DI 0 "r")
     (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
              (clobber (reg:CC FLAGS_REG))])]
!   "optimize_size || !TARGET_SUB_ESP_4"
    [(clobber (match_dup 0))
     (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])

--- 19442,19456 ----
              (clobber (mem:BLK (scratch)))])])

  ;; Convert esp subtractions to push.
+ ;; This conversion is safe only under assumption that unallocated stack is
+ ;; implicitly clobbered as specified by 32bit ABI (for signal handlers and
such).
+ ;; This is not valid with red zone, but we can work harder and enable the
+ ;; optimization for functions that are not using it.
  (define_peephole2
    [(match_scratch:DI 0 "r")
     (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
              (clobber (reg:CC FLAGS_REG))])]
!   "(optimize_size || !TARGET_SUB_ESP_4) && !TARGET_RED_ZONE"
    [(clobber (match_dup 0))
     (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])

***************
*** 19450,19456 ****
    [(match_scratch:DI 0 "r")
     (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
              (clobber (reg:CC FLAGS_REG))])]
!   "optimize_size || !TARGET_SUB_ESP_8"
    [(clobber (match_dup 0))
     (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
     (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
--- 19458,19464 ----
    [(match_scratch:DI 0 "r")
     (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
              (clobber (reg:CC FLAGS_REG))])]
!   "(optimize_size || !TARGET_SUB_ESP_8) && !TARGET_RED_ZONE"
    [(clobber (match_dup 0))
     (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
     (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24419

Reply via email to