------- Comment #47 from rguenth at gcc dot gnu dot org  2008-03-28 22:12 
-------
What is interesting is that j__target_type___XDLU_10__20 is a unsigned sub type
with range [10, 20] of a signed base type with range [-128, 127].  So, we
enter compare_values ((js__TtB)20, (j__target_type___XDLU_10__20)128)
(both types have a precision of 8 bits, but the out-of-range value 128 is
not representable in the base type, but is interpreted as -128).

So, why is this range check

  if (target_first_66 == 128)
    goto <bb 7>;
  else
    goto <bb 8>;

<bb 7>:
  __gnat_rcheck_12 ("join_equal.adb", 15);

using a value not representable in the base type?  The TYPE_MIN/MAX_VALUEs
are of the type of the base type, so target_first_66s value range is
[10, 20] at the point of this comparison.  Is this supposed to be
a comparison with -128 or with 128?  That is, is this

  target_first_66 == TYPE_MIN_VALUE (js__TtB)

?  I guess so.

The problem is that we try to compare different typed values here, the
10 and 20 of signed base type and the 128 of unsigned sub type.  If
we for the comparison canonicalize the 128 to the signed base type
(which is the only thing that makes sense) we get an overflow value
as it wraps to -128 and the comparison result will be ignored because
"it assumes that signed overflow is undefined".  Bah.

So let's try avoiding setting the overflow flag for conversions from
a sub type to its base type.  Then I have a patch that evaluates

      target_first_66 == 128

to false based on the initial value range idea for default SSA_NAMEs
and the only remaining range checks are

grep gnat_rcheck j.ads.127t.optimized 
  __gnat_rcheck_04 ("join_equal.adb", 13);
  __gnat_rcheck_12 ("join_equal.adb", 29);
  __gnat_rcheck_12 ("join_equal.adb", 39);


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30911

Reply via email to