This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch, omp] Patch to omp-low.c to fix failures on IA64 HP-UX
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "Steve Ellcey" <sje at cup dot hp dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 30 Oct 2008 23:40:23 +0100
- Subject: Re: [Patch, omp] Patch to omp-low.c to fix failures on IA64 HP-UX
- References: <1225404158.173162.31524.nullmailer@hpsje.cup.hp.com>
On Thu, Oct 30, 2008 at 11:02 PM, Steve Ellcey <sje@cup.hp.com> wrote:
> I have two libgomp tests, libgomp.c/loop-5.c and libgomp.c++/loop-8.C
> that fail on IA64 HP-UX in 32 bit mode. In this mode pointers are 32
> bits but need to be extended to 64 bits before being dereferenced. IA64
> has a special instruction, addp4 to do that. In omp-low.c
> (expand_omp_for_generic) we have these two instructions:
>
> t1 = fold_convert (fd->iter_type, fd->loop.n2);
> t0 = fold_convert (fd->iter_type, fd->loop.n1);
>
> Where fd->loop.n1 (and n2) are 32 bit pointer types and fd->iter_type is
> a 64 bit 'unsigned long long' type. There are two ways of getting from
> a 32 bit pointer to a 64 bit unsigned long, one could use addp4 or one
> could convert the pointer to a 32 bit unsigned long and then zero extend
> that.
It turns out that the middle-end type checker would error on a conversion
from a pointer to an integer type of different precision. Just it is never
executed after gimplification ... (and we specifically allow conversion
to/from sizetype to make ports with mismatching pointer/sizetype precision
happy).
For 4.5 I plan to enable this checking code after all passes which will
catch this errorneous situation.
> It turns out that using either method works as long as you use the same
> method for both of these statements but in the two failing tests one
> convert gets done one way and the other the other way and then the test
> fails. They get done differently because one of the expressions being
> converted is a simple address and the other is an expression and this
> results in different choices in how to extend the expression.
>
> This patch fixes the problem by explicitly converting the pointer to
> 'unsigned long' first and then extending that to type 'unsigned long
> long'. This forces a consistent conversion path for both expressions
> and fixes the bug.
>
> Tested on IA64 HP-UX and Linux with no regressions.
>
> OK for checkin?
I'll leave that to OMP maintainers. It at least looks ugly ;)
Richard.
>
> 2008-10-30 Steve Ellcey <sje@cup.hp.com>
>
> * omp-low.c (expand_omp_for_generic): Change conversion code.
>
>
> Index: omp-low.c
> ===================================================================
> --- omp-low.c (revision 141457)
> +++ omp-low.c (working copy)
> @@ -3681,8 +3681,20 @@ expand_omp_for_generic (struct omp_regio
> t4 = build_fold_addr_expr (iend0);
> t3 = build_fold_addr_expr (istart0);
> t2 = fold_convert (fd->iter_type, fd->loop.step);
> - t1 = fold_convert (fd->iter_type, fd->loop.n2);
> - t0 = fold_convert (fd->iter_type, fd->loop.n1);
> + if (POINTER_TYPE_P (TREE_TYPE (fd->loop.n2))
> + && (TYPE_PRECISION (fd->iter_type) >
> + TYPE_PRECISION (long_unsigned_type_node)))
> + t1 = fold_convert (fd->iter_type,
> + fold_convert (long_unsigned_type_node, fd->loop.n2));
> + else
> + t1 = fold_convert (fd->iter_type, fd->loop.n2);
> + if (POINTER_TYPE_P (TREE_TYPE (fd->loop.n1))
> + && (TYPE_PRECISION (fd->iter_type) >
> + TYPE_PRECISION (long_unsigned_type_node)))
> + t0 = fold_convert (fd->iter_type,
> + fold_convert (long_unsigned_type_node, fd->loop.n1));
> + else
> + t0 = fold_convert (fd->iter_type, fd->loop.n1);
> if (bias)
> {
> t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
>