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]

[Patch, omp] Patch to omp-low.c to fix failures on IA64 HP-UX


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 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?


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);


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