This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, rtl-optimization]: Fix PR 37544


On Wed, Sep 17, 2008 at 6:10 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> Hello!
>
> As described in the PR audit trail, the problem lies in cprop_hardreg pass
> that shortcuts through the sequence of DImode->SImode->DImode conversions by
> omitting SImode intermediate result.
>
> The core of the problem is in maybe_mode_change function in regrename.c that
> permits mode change for
> orig_mode = DImode
> copy_mode = SImode
> new_mode = DImode.
>
> Attached patch simply prevents mode change when copy mode is narrower than
> new_mode.

Shouldn't it be when orig_mode is wider than copy_mode in addition?
QImode -> SImode ->DImode
should be ok, as would SImode -> DImode -> QImode or QImode ->SImode -> HImode.

Ok with that change.

Thanks,
Richard.

> 2008-09-17  Uros Bizjak  <ubizjak@gmail.com>
>
>   PR rtl-optimization/37544
>   * regrename.c (maybe_mode_change): Exit early when copy_mode
>   is narrower than new_mode.
>
> testsuite/ChangeLog:
>
> 2008-09-17  Uros Bizjak  <ubizjak@gmail.com>
>
>   PR rtl-optimization/37544
>   * gcc.dg/pr37544.c: New test.
>
>
> Patch was bootstrapped and regression tested on i686-pc-linux-gnu and
> x86_64-pc-linux-gnu {,-m32}.
>
> OK for mainline and branches?
>
> Uros.
>
>
> Index: regrename.c
> ===================================================================
> --- regrename.c (revision 140418)
> +++ regrename.c (working copy)
> @@ -1314,6 +1314,9 @@ maybe_mode_change (enum machine_mode ori
>                   enum machine_mode new_mode, unsigned int regno,
>                   unsigned int copy_regno ATTRIBUTE_UNUSED)
>  {
> +  if (GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (new_mode))
> +    return NULL_RTX;
> +
>   if (orig_mode == new_mode)
>     return gen_rtx_raw_REG (new_mode, regno);
>   else if (mode_change_ok (orig_mode, new_mode, regno))
> Index: testsuite/gcc.dg/pr37544.c
> ===================================================================
> --- testsuite/gcc.dg/pr37544.c  (revision 0)
> +++ testsuite/gcc.dg/pr37544.c  (revision 0)
> @@ -0,0 +1,39 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +/* { dg-options "-O2 -msse2 -mtune=core2" { target { { i?86-*-* x86_64-*-*
> } && ilp32 } } } */
> +
> +#ifdef __i386__
> +#include "cpuid.h"
> +#endif
> +
> +extern void abort (void);
> +
> +int main(void)
> +{
> +  double arr[1000];
> +  double a, b;
> +
> +  int i;
> +
> +#ifdef __i386__
> +  unsigned int eax, ebx, ecx, edx;
> +
> +  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
> +    return 0;
> +
> +  /* Run SSE2 test only if host has SSE2 support.  */
> +  if (!(edx & bit_SSE2))
> +    return 0;
> +#endif
> +
> +  for (i = 0; i < 1000; i++)
> +    arr[i] = 4294967296.0 + (double)i;
> +
> +  a = arr[0];
> +  b = (unsigned int)((unsigned long long int)a % 4294967296ULL);
> +
> +  if (b >= 4294967296.0)
> +    abort ();
> +
> +  return 0;
> +}
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]