Hi!

Double arguments passed on the stack on x86_64 (and float too) where
a function is called with a constant is stored using corresponding integer
mode rather than DFmode, so cselib_lookup doesn't find the preserved value
for this.  Fixed thusly, bootstrapped/regtested on x86_64-linux and
i686-linux, ok for trunk?

2011-07-26  Jakub Jelinek  <ja...@redhat.com>

        PR debug/49846
        * var-tracking.c (prepare_call_arguments): For non-MODE_INT stack
        arguments also check if they aren't initialized with a MODE_INT
        mode of the same size.

--- gcc/var-tracking.c.jj       2011-07-22 22:15:02.000000000 +0200
+++ gcc/var-tracking.c  2011-07-26 15:51:35.000000000 +0200
@@ -5777,6 +5777,22 @@ prepare_call_arguments (basic_block bb, 
            val = cselib_lookup (mem, GET_MODE (mem), 0, VOIDmode);
            if (val && cselib_preserved_value_p (val))
              item = gen_rtx_CONCAT (GET_MODE (x), copy_rtx (x), val->val_rtx);
+           else if (GET_MODE_CLASS (GET_MODE (mem)) != MODE_INT)
+             {
+               /* For non-integer stack argument see also if they weren't
+                  initialized by integers.  */
+               enum machine_mode imode = int_mode_for_mode (GET_MODE (mem));
+               if (imode != GET_MODE (mem) && imode != BLKmode)
+                 {
+                   val = cselib_lookup (adjust_address_nv (mem, imode, 0),
+                                        imode, 0, VOIDmode);
+                   if (val && cselib_preserved_value_p (val))
+                     item = gen_rtx_CONCAT (GET_MODE (x), copy_rtx (x),
+                                            lowpart_subreg (GET_MODE (x),
+                                                            val->val_rtx,
+                                                            imode));
+                 }
+             }
          }
        if (item)
          call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);

        Jakub

Reply via email to