Bug 68221

Summary: libgomp reduction-11/12 failures
Product: gcc Reporter: Jakub Jelinek <jakub>
Component: middle-endAssignee: Richard Biener <rguenth>
Status: RESOLVED FIXED    
Severity: normal CC: bill.schmidt, pthaugen, rguenth
Priority: P3 Keywords: openmp
Version: 6.0   
Target Milestone: 6.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2015-11-23 00:00:00

Description Jakub Jelinek 2015-11-05 15:41:37 UTC
Without the XFAILs I've added I'm getting:
FAIL: libgomp.c/reduction-11.c execution test
FAIL: libgomp.c/reduction-12.c execution test
FAIL: libgomp.c++/reduction-11.C execution test
FAIL: libgomp.c++/reduction-12.C execution test
on i686-linux (32-bit only, 64-bit x86_64-linux works) when the testcases are compiled with -fopenmp -O2.  At -O0 they work.

These testcases test array reductions with non-zero low-bound, where for stack space reasons the compiler is creating private variable just for the array section and not elements before or after it in the original array.
E.g. for reduction (b[2:3]) the user is allowed to touch in the region
b[2], b[3], b[4], but not b[0], b[1] or b[5].  The current implementation
allocates short int b.23[3]; automatic variable in this case, and needs to replace the original b with &b.23 - 2, so that b + 2 then is in range.  If the low-bound is not constant (or if it is zero), all is fine, but when it is constant, we after IL simplifications end up with
MEM[(short int *)&b.23 + 4294967292B][2]
but apparently on i686-linux -m32 -O2 -fopenmp on reduction-11.c at least
PRE seems to think that stores to
MEM[(short int *)&b.23 + 4294967292B][2]
can't alias reads from it.

On the OpenMP side I guess I could try casting &b.23 to uintptr_t and then back, but I'm afraid it will get folded away anyway.  Another option is to add some optimization barrier like short *p; p = &b.23; asm ("" : "+g" (p));
but then points-to analysis will pessimize code.  If we could get
the above folded into MEM[(short int *)&b.23][0], it would be nice, but can we really rely on that being always done?
Comment 1 Richard Biener 2015-11-06 09:10:54 UTC
We could fold it to MEM[(short int *)&b.23] (without the array-ref).  Does the same problem exist for variable indexed array?

I'll have a look during stage3 - I believe the oracle should be have sanely
here and thus there is likely a bug somewhere.
Comment 2 Jakub Jelinek 2015-11-06 11:34:09 UTC
I don't have any testcase that would exhibit a problem with variable low-bound, but that is not a proof there isn't a problem.

Trying:
typedef __UINTPTR_TYPE__ uintptr_t;
void bar (unsigned short *, unsigned short *);

int
foo (int x, int y, int z)
{
  unsigned short a[10], b[10];
  bar (a, b);
  uintptr_t ai = (uintptr_t) a;
  uintptr_t bi = (uintptr_t) b;
  ai -= 16;
  bi -= x;
  unsigned short *ap = (unsigned short *) ai;
  unsigned short *bp = (unsigned short *) bi;
  return ap[19] + bp[19] + ap[y] + bp[z];
}
reveals that we don't fold this and therefore it isn't a problem.  So perhaps I just should go through that way internally on the omp-low.c side.
Comment 3 Bill Schmidt 2015-11-18 21:36:51 UTC
Just FYI, we are getting XPASSes on these for powerpc64le-linux-gnu.
Comment 4 Jakub Jelinek 2015-11-20 19:51:17 UTC
Author: jakub
Date: Fri Nov 20 19:50:46 2015
New Revision: 230672

URL: https://gcc.gnu.org/viewcvs?rev=230672&root=gcc&view=rev
Log:
	PR middle-end/68221
	* omp-low.c (lower_rec_input_clauses): If C/C++ array reduction
	has non-zero bias, subtract it in integer type instead of
	pointer plus of negated bias.

	* testsuite/libgomp.c/reduction-11.c: Remove xfail.
	* testsuite/libgomp.c/reduction-12.c: Likewise.
	* testsuite/libgomp.c++/reduction-11.C: Likewise.
	* testsuite/libgomp.c++/reduction-12.C: Likewise.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/omp-low.c
    trunk/libgomp/ChangeLog
    trunk/libgomp/testsuite/libgomp.c++/reduction-11.C
    trunk/libgomp/testsuite/libgomp.c++/reduction-12.C
    trunk/libgomp/testsuite/libgomp.c/reduction-11.c
    trunk/libgomp/testsuite/libgomp.c/reduction-12.c
Comment 5 Richard Biener 2015-11-23 13:23:06 UTC
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c        (revision 230671)
+++ gcc/tree-ssa-sccvn.c        (working copy)
@@ -750,8 +750,11 @@ copy_reference_ops_from_ref (tree ref, v
        case MEM_REF:
          /* The base address gets its own vn_reference_op_s structure.  */
          temp.op0 = TREE_OPERAND (ref, 1);
-         if (tree_fits_shwi_p (TREE_OPERAND (ref, 1)))
-           temp.off = tree_to_shwi (TREE_OPERAND (ref, 1));
+           {
+             offset_int off = mem_ref_offset (ref);
+             if (wi::fits_shwi_p (off))
+               temp.off = off.to_shwi ();
+           }
          temp.clique = MR_DEPENDENCE_CLIQUE (ref);
          temp.base = MR_DEPENDENCE_BASE (ref);
          temp.reverse = REF_REVERSE_STORAGE_ORDER (ref);
Comment 6 Richard Biener 2015-11-24 09:18:12 UTC
Author: rguenth
Date: Tue Nov 24 09:17:40 2015
New Revision: 230793

URL: https://gcc.gnu.org/viewcvs?rev=230793&root=gcc&view=rev
Log:
2015-11-24  Richard Biener  <rguenther@suse.de>

	PR middle-end/68221
	* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Properly
	use mem_ref_offset.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/tree-ssa-sccvn.c
Comment 7 Richard Biener 2015-11-24 13:15:30 UTC
Author: rguenth
Date: Tue Nov 24 13:14:58 2015
New Revision: 230806

URL: https://gcc.gnu.org/viewcvs?rev=230806&root=gcc&view=rev
Log:
2015-11-24  Richard Biener  <rguenther@suse.de>

	PR middle-end/68221
	* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Properly
	use mem_ref_offset.

Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/tree-ssa-sccvn.c
Comment 8 Richard Biener 2015-11-24 15:16:20 UTC
Fixed.