This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, rtl-optimization]: Fix PR 37544
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "Uros Bizjak" <ubizjak at gmail dot com>
- Cc: "GCC Patches" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 17 Sep 2008 21:13:21 +0200
- Subject: Re: [PATCH, rtl-optimization]: Fix PR 37544
- References: <48D12C02.4080907@gmail.com>
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;
> +}
>
>