This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Better fix for fix_truncsfdi2 i386 bug in egcs 1.1.2
- To: law at cygnus dot com
- Subject: Re: Better fix for fix_truncsfdi2 i386 bug in egcs 1.1.2
- From: Jim Kingdon <kingdon at redhat dot com>
- Date: Tue, 24 Aug 1999 17:12:35 -0400
- CC: gcc-patches at gcc dot gnu dot org
- References: <14330.935471599@upchuck.cygnus.com>
> So, presumably the output is being written before scratch memory
> locations are used?
Yes.
> It would have helped if you indicated what path through
> output_fix_trunc and output_to_reg was used -- I had to spend a lot
> of time reading that code to see how we might be losing.
Thanks for suggesting this - it isn't that I forgot to mention this,
it is that I didn't know the compiler well enough to easily understand
how output_fix_trunc related to the other pieces and so on. I think
I'm slowly gaining enlightenment.
> output_move_double knows how to handle cases where the destination overlaps
> with the inputs, so there's no possibility of losing in that code.
Right. The egcs 1.1.2 equivalent (output_to_reg) doesn't handle those
cases, but it is a moot point in light of:
> return AS1 (fldc%W2,%2);
> Hmmm. I think this could cause a problem if the address for operands[2] used
> the same register as the output operand (operands[0]).
> Do you concur?
Yes, I concur (after stepping through the code on my test case and
thinking about it and so on). Once I look at it right, it looks like
a straightforward application of the rule "Therefore, this
[earlyclobber] operand may not lie in a register that is used as
. . . part of any memory address" from md.texi.
> Can you please fix all the patterns which call output_fix_trunc such
> that they have an earlyclobber on the "!r" output alternative if you
> agree with my comments?
Patch enclosed. Thanks for your patience/help - and I'm glad you took
the time because I wouldn't have noticed the SImode case without your
suggestions.
Tue Aug 24 15:54:32 1999 Jim Kingdon <http://developer.redhat.com>
with much help from Jeffrey A Law and Richard Henderson
* config/i386/i386.md: In the 6 insns which call output_fix_trunc,
operands[0] needs to be an earlyclobber if it is a register (since
output_fix_trunc may access memory after setting operands[0]).
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/egcs/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.78
diff -c -r1.78 i386.md
*** i386.md 1999/04/25 11:43:46 1.78
--- i386.md 1999/08/24 20:02:45
***************
*** 2711,2717 ****
}")
(define_insn ""
! [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
(clobber (match_operand:HI 3 "memory_operand" "m,m"))
--- 2711,2717 ----
}")
(define_insn ""
! [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
(clobber (match_operand:HI 3 "memory_operand" "m,m"))
***************
*** 2739,2745 ****
}")
(define_insn ""
! [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
(clobber (match_dup 1))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
--- 2739,2745 ----
}")
(define_insn ""
! [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
(clobber (match_dup 1))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
***************
*** 2766,2772 ****
}")
(define_insn ""
! [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
(clobber (match_operand:HI 3 "memory_operand" "m,m"))
--- 2766,2772 ----
}")
(define_insn ""
! [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
(clobber (match_operand:HI 3 "memory_operand" "m,m"))
***************
*** 2794,2800 ****
}")
(define_insn ""
! [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
(clobber (match_dup 1))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
--- 2794,2800 ----
}")
(define_insn ""
! [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
(clobber (match_dup 1))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
***************
*** 2821,2827 ****
}")
(define_insn ""
! [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
(fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
(clobber (match_operand:HI 3 "memory_operand" "m,m"))
--- 2821,2827 ----
}")
(define_insn ""
! [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r")
(fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
(clobber (match_operand:HI 3 "memory_operand" "m,m"))
***************
*** 2849,2855 ****
}")
(define_insn ""
! [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
(fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
(clobber (match_dup 1))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))
--- 2849,2855 ----
}")
(define_insn ""
! [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r")
(fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
(clobber (match_dup 1))
(clobber (match_operand:HI 2 "memory_operand" "m,m"))