My tester started spitting out failures for targets with 16bit integers after the introduction of range-ops.
It turns out two of the selftests in range_tests assume that shorts and ints are different sizes. The first creates a range with [0, MAXINT] bounds, converts it to a short and verifies that the resultant range is [MINSHORT, MAXSHORT]. That's the proper behavior for a narrowing conversion. But when ints and shorts have the same size the conversion is a nop. The second test creates a nonzero int range, then converts it to a short and again tests the resultant range. In this case as well when ints and shorts have different sizes the result should be [MINSHORT, MAXSHORT]. But when ints and shorts have the same size the resultant range is unchanged. This patch makes both tests conditional on the precision of int being larger than the precision of a short. The net result is the 16bit integer targets no longer fail the selftests allowing them to proceed normally through the target library builds and gcc testsuite runs. Bootstrapped and regression tested on x86_64 and others. We've still got guality regressions relative to the last good run, but those are unrelated to this change (At least some are Jan's. Others still need analysis). Installing on the trunk momentarily. Jeff
* range-op.cc (range_tests): Avoid two tests when ints and shorts are the same size. diff --git a/gcc/range-op.cc b/gcc/range-op.cc index b538b00459a..a67cdbf77ba 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -2909,10 +2909,14 @@ range_tests () // If a range is in any way outside of the range for the converted // to range, default to the range for the new type. - r1 = value_range_base (integer_zero_node, maxint); - range_cast (r1, short_integer_type_node); - ASSERT_TRUE (r1.lower_bound () == wi::to_wide (minshort) - && r1.upper_bound() == wi::to_wide (maxshort)); + if (TYPE_PRECISION (TREE_TYPE (maxint)) + > TYPE_PRECISION (short_integer_type_node)) + { + r1 = value_range_base (integer_zero_node, maxint); + range_cast (r1, short_integer_type_node); + ASSERT_TRUE (r1.lower_bound () == wi::to_wide (minshort) + && r1.upper_bound() == wi::to_wide (maxshort)); + } // (unsigned char)[-5,-1] => [251,255]. r0 = rold = value_range_base (SCHAR (-5), SCHAR (-1)); @@ -3019,11 +3023,15 @@ range_tests () // "NOT 0 at signed 32-bits" ==> [-MIN_32,-1][1, +MAX_32]. This is // is outside of the range of a smaller range, return the full // smaller range. - r0 = range_nonzero (integer_type_node); - range_cast (r0, short_integer_type_node); - r1 = value_range_base (TYPE_MIN_VALUE (short_integer_type_node), - TYPE_MAX_VALUE (short_integer_type_node)); - ASSERT_TRUE (r0 == r1); + if (TYPE_PRECISION (integer_type_node) + > TYPE_PRECISION (short_integer_type_node)) + { + r0 = range_nonzero (integer_type_node); + range_cast (r0, short_integer_type_node); + r1 = value_range_base (TYPE_MIN_VALUE (short_integer_type_node), + TYPE_MAX_VALUE (short_integer_type_node)); + ASSERT_TRUE (r0 == r1); + } // Casting NONZERO from a narrower signed to a wider signed. //