This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: IA64 caller-save register patch
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 18 Feb 2004 09:01:15 -0800 (PST)
- Subject: Re: IA64 caller-save register patch
Here is a resubmittal of my earlier IA64 patch with an added testsuite
that fails without the patch and works with it. The fix itself has not
been changed. While the bug is IA64 specific I made the testcase
runnable on all platforms and tested it on IA64 and non-IA64 platforms.
Ok to check in?
Steve Ellcey
sje@cup.hp.com
2004-02-18 Steve Ellcey <sje@cup.hp.com>
* config/ia64/ia64.h (HARD_REGNO_CALLER_SAVE_MODE): New macro.
* testsuite/gcc.dg/20040217-1.c: New test.
*** gcc.orig/gcc/gcc/config/ia64/ia64.h Fri Feb 13 11:08:40 2004
--- gcc/gcc/gcc/config/ia64/ia64.h Fri Feb 13 11:09:13 2004
*************** while (0)
*** 831,836 ****
--- 831,843 ----
(GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2) \
&& (((MODE1) == XFmode) == ((MODE2) == XFmode)) \
&& (((MODE1) == BImode) == ((MODE2) == BImode)))
+
+ /* Specify the modes required to caller save a given hard regno.
+ We need to ensure floating pt regs are not saved as DImode. */
+
+ #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
+ ((FR_REGNO_P (REGNO) && (NREGS) == 1) ? XFmode \
+ : choose_hard_reg_mode ((REGNO), (NREGS), false))
/* Handling Leaf Functions */
*** gcc.orig/gcc/gcc/testsuite/gcc.dg/20040217-1.c Wed Feb 18 08:54:30 2004
--- gcc/gcc/gcc/testsuite/gcc.dg/20040217-1.c Wed Feb 18 08:54:09 2004
***************
*** 0 ****
--- 1,74 ----
+ /* Testing save/restore of floating point caller-save registers, on ia64
+ this resulted in bad code. Not all targets will use caller-save regs. */
+
+ /* { dg-do run } */
+ /* { dg-options "-O2" } */
+ /* { dg-options "-O2 -minline-float-divide-max-throughput" { target ia64-*-* } } */
+
+ /* Testing save/restore of floating point caller-save registers on ia64. */
+
+ extern void abort (void);
+
+ double foo(double a, double b, double c)
+ {
+ return (a+b+c);
+ }
+
+ main ()
+ {
+ double f1, f2, f3, f4, f5, f6, f7, f8, f9,f10;
+ double f11,f12,f13,f14,f15,f16,f17,f18,f19,f20;
+ double f21,f22,f23,f24,f25,f26,f27,f28,f29,f30;
+ double x;
+ int i,j,k;
+
+ f1 = 0.1; f2 = 0.2; f3 = 0.3; f4 = 0.4; f5 = 0.5;
+ f6 = 0.6; f7 = 0.7; f8 = 0.8; f9 = 0.9; f10 = 1.0;
+ f11 = 1.1; f12 = 1.2; f13 = 1.3; f14 = 1.4; f15 = 1.5;
+ f16 = 1.6; f17 = 1.7; f18 = 1.8; f19 = 1.9; f20 = 2.0;
+ f21 = 2.1; f22 = 2.2; f23 = 2.3; f24 = 2.4; f25 = 2.5;
+ f26 = 2.6; f27 = 2.7; f28 = 2.8; f29 = 2.9; f30 = 3.0;
+
+ i = (int) foo(1.0,1.0,1.0);
+ while (i > 0) {
+ f1 = f2 / f3 * f30;
+ f2 = f3 / f4 * f30;
+ f3 = f4 / f5 * f30;
+ f4 = f5 / f6 * f30;
+ f5 = f6 / f7 * f30;
+ f6 = f7 / f8 * f30;
+ f7 = f8 / f9 * f30;
+ f8 = f9 / f10 * f30;
+ f9 = f10 / f11 * f30;
+ f10 = f11 / f12 * f30;
+ f11 = f12 / f13 * f30;
+ f12 = f13 / f14 * f25;
+ f13 = f14 / f15 * f30;
+ f14 = f15 / f16 * f30;
+ f15 = f16 / f17 * f30;
+ f16 = f17 / f18 * f30;
+ f17 = f18 / f19 * f30;
+ f18 = f19 / f20 * f30;
+ f19 = f20 / f21 * f30;
+ f20 = f21 / f22 * f20;
+ f21 = f22 / f23 * f30;
+ f22 = f23 / f24 * f30;
+ f23 = f24 / f25 * f30;
+ f24 = f25 / f26 * f30;
+ f25 = f26 / f27 * f30;
+ f26 = f27 / f28 * f30;
+ f27 = f28 / f29 * f30;
+ f28 = f29 / f30 * f30;
+ f29 = f30 / f1 * f30;
+ f30 = f1 / f2 * f30;
+ x = foo(f1,f2,f3);
+ i = i - 1;
+ }
+ x = (f1+f2+f3+f4+f5+f6+f7+f8+f9+f10) *
+ (f11+f12+f13+f14+f15+f16+f17+f18+f19+f20) *
+ (f21+f22+f23+f24+f25+f26+f27+f28+f29+f30);
+
+ /* Exact value is not needed, on IA64 it is massively off. */
+ if (x < 19503.0 || x > 19504.0) abort();
+ return 0;
+ }