[PATCH] Fix transfer_intrinsic_3.f90 miscompilation on ppc*/s390* (PR tree-optimization/88044)

Jakub Jelinek jakub@redhat.com
Fri Jan 18 22:52:00 GMT 2019


Hi!

As mentioned in the PR, on the transfer_intrinsic_3.f90 testcase at -O3
on a few targets we have in number_of_iterations_cond:
code LE_EXPR
iv0->base 0
iv0->step 0
iv1->base -1
iv1->step 1
every_iteration false

The loop starts with:
  <bb 7> [local count: 8656061039]:
  # n_63 = PHI <0(6), _28(23)>
  _19 = n_63 + -1;
and ends with
  _28 = n_63 + 1;
  if (_28 == 4)
    goto <bb 21>; [12.36%]
  else
    goto <bb 23>; [87.64%]

  <bb 23> [local count: 7582748748]:
  goto <bb 7>; [100.00%]
and besides the exit at the end has also:
  <bb 16> [local count: 3548985018]:
  if (_19 > 0)
    goto <bb 17>; [0.04%]
  else
    goto <bb 28>; [99.96%]
  
  <bb 17> [local count: 1419591]:
  _gfortran_stop_numeric (1, 0);
  
  <bb 18> [local count: 5106238449]:
  if (_19 < 0)
    goto <bb 19>; [0.04%]
  else
    goto <bb 29>; [99.96%]
  
  <bb 29> [local count: 5104195957]:
  goto <bb 20>; [100.00%]
  
  <bb 19> [local count: 2042498]:
  _gfortran_stop_numeric (2, 0);

in the middle, so two other loop exits.  But, neither bb16, nor bb18 are
executed every iteration, if they were, then because _19 is -1 in the first
iteration would always stop 2 and not iterate further.

We have:

  /* If the test is not executed every iteration, wrapping may make the test
     to pass again.
     TODO: the overflow case can be still used as unreliable estimate of upper
     bound.  But we have no API to pass it down to number of iterations code
     and, at present, it will not use it anyway.  */
  if (!every_iteration
      && (!iv0->no_overflow || !iv1->no_overflow
          || code == NE_EXPR || code == EQ_EXPR))
    return false;

at the start, but that doesn't trigger here, because code is not equality
comparison and no_overflow is set on both IVs.  If there would be an
overflow, then maybe it would be right to derive number of iterations from
that.  But the condition that returns true is that iv0->base code iv1->base
is false, if that isn't done in every iteration, it means nothing for the
number of iteration analysis.

Fixed thusly, bootstrapped/regtested on x86_64-linux, i686-linux,
powerpc64{,le}-linux, ok for trunk?

2019-01-18  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/88044
	* tree-ssa-loop-niter.c (number_of_iterations_cond): If condition
	is false in the first iteration, but !every_iteration, return false
	instead of true with niter->niter zero.

--- gcc/tree-ssa-loop-niter.c.jj	2019-01-10 11:43:02.254577008 +0100
+++ gcc/tree-ssa-loop-niter.c	2019-01-18 19:51:00.245504728 +0100
@@ -1824,6 +1824,8 @@ number_of_iterations_cond (struct loop *
   tree tem = fold_binary (code, boolean_type_node, iv0->base, iv1->base);
   if (tem && integer_zerop (tem))
     {
+      if (!every_iteration)
+	return false;
       niter->niter = build_int_cst (unsigned_type_for (type), 0);
       niter->max = 0;
       return true;

	Jakub



More information about the Gcc-patches mailing list