Patch: bug in regmove

Dale Johannesen dalej@apple.com
Sun Sep 14 01:28:00 GMT 2003


This is best illustrated by example.  My failing case for this one is 
on darwin/x86, not a common target
(even here), but I expect it fails on other x86s as well.

#include <stdio.h>
double foo(void) {
         return 12345678.0;
}
int
main(int argc, char *argv[]) {
         double now = foo();
         double then = (double)argc;  /* 1 expected */

         double d = (double)((now - then) / 60.0L);
         printf("d = %g\n", d);
         if (d > 205760. && d < 205762.)
           return 0;
         abort();
}

When compiled with -O2, regmove attempts to propagate reg 68 backward 
here:

(insn 15 13 16 0 0x3c6ad4 (set (reg:DF 64)
         (minus:DF (reg/v:DF 61)
             (float:DF (reg/v:SI 59)))) 421 {*fop_df_3}

(insn 19 18 20 0 0x3c6ad4 (set (reg:XF 68)
         (div:XF (float_extend:XF (reg:DF 64))
             (float_extend:XF (mem/u/f:SF (plus:SI (reg:SI 3 ebx)
                         (const:SI (minus:SI (symbol_ref/u:SI ("*LC1"))
                                 (symbol_ref:SI 
("*"L00000000002$pb""))))) [0 S4 A32])))) 437 {*fop_xf_7}

So it tries this,  where the divide is valid but the minus is not:

(insn 15 13 16 0 0x3c6ad4 (set (reg:XF 68)
         (minus:DF (reg/v:DF 61)
             (float:DF (reg/v:SI 59)))) 421 {*fop_df_3}

(insn:HI 19 18 20 0 0x3c6ad4 (set (reg:XF 68)
         (div:XF (float_extend:XF (reg:XF 68))
             (float_extend:XF (mem/u/f:SF (plus:SI (reg:SI 3 ebx)
                         (const:SI (minus:SI (symbol_ref/u:SI ("*LC1"))
                                 (symbol_ref:SI 
("*"L00000000002$pb""))))) [0 S4 A32])))) 437 {*fop_xf_7}

and figures out that it is invalid, and tries to back off to the 
original.  That's where the bug is.
In backing off the divide, it first substitutes R64 for R68 throughout 
and rerecognizes the insn, then substitutes
R68 for the destination only.  In this case, the intermediate form with 
R64 throughout is not valid,
so the intermediate recognition fails and the backing off doesn't get 
done.The following patch redoes
the backing-off in a way that doesn't attempt to recognize an 
intermediate form.  (Should be minutely
faster, too.)  Bootstrapped and tested on Darwin, to the extent 
currently possible.

Index: regmove.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regmove.c,v
retrieving revision 1.149
diff -u -d -b -w -c -3 -p -r1.149 regmove.c
*** regmove.c   22 Aug 2003 06:45:14 -0000      1.149
--- regmove.c   11 Sep 2003 19:48:24 -0000
*************** regmove_optimize (rtx f, int nregs, FILE
*** 1406,1416 ****
                             {
                               /* Change all source operands back.
                                  This modifies the dst as a 
side-effect.  */
!                             validate_replace_rtx (dst, src, insn);
                               /* Now make sure the dst is right.  */
                               validate_change (insn,
                                                
recog_data.operand_loc[match_no],
!                                              dst, 0);
                             }
                         }
                       break;
--- 1406,1420 ----
                             {
                               /* Change all source operands back.
                                  This modifies the dst as a 
side-effect. */
!                             validate_replace_rtx_group (dst, src, 
insn);
!                             /* It is possible for the intermediate 
step
!                                to be an invalid insn, so don't try to
!                                validate it. */
                               /* Now make sure the dst is right.  */
                               validate_change (insn,
                                                
recog_data.operand_loc[match_no],
!                                              dst, 1);
!                             apply_change_group ();
                             }
                         }
                       break;

2003-09-13   Dale Johannesen  <dalej@apple.com>

         * regmove.c (regmove_optimize):  Don't try to recognize 
possibly invalid
         intermediate form when backing off unsuccessful change attempt.



More information about the Gcc-patches mailing list