------- 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