[PATCH] New fold_range_test optimizations (take 2)

Jakub Jelinek jakub@redhat.com
Fri Jun 18 13:45:00 GMT 2004


On Thu, Jun 17, 2004 at 06:39:36PM -0600, Roger Sayle wrote:
> This is OK for mainline.  If its no trouble, could you add an extra
> sentence to the comment above build_range_check mentioning that this
> function can return NULL_TREE (all the callers check for a zero result,
> but this isn't described in the function's documentation).

Will do that.

> Thanks also to Alex for catching the INT_MAX + 1 != INT_MIN issue,
> presumably for types narrower than their mode.  With those changes
> it looks like your use of lang_hooks.types.unsigned_type is safe
> even when the C++ front-end returns a "utype" of different width to
> the original "etype", such that fold_convert performs an implicit
> sign extension, c.f. PR middle-end/15069 and
> http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00060.html

Well, it was meant primarily for the hypothetical target using sign + absvalue
encoding for signed integers.

But, concerning C++ enumerals, I wonder if I shouldn't add:
              if (low0 && TREE_CODE (low0) == INTEGER_CST)
                switch (TREE_CODE (TREE_TYPE (low0)))
                  {
+		  case ENUMERAL_TYPE:
+		    if (TYPE_PRECISION (TREE_TYPE (low0))
+			!= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (low0))))
+		      break;
+		    /* FALLTHROUGH */
                  case INTEGER_TYPE:
-                 case ENUMERAL_TYPE:
                  case CHAR_TYPE:
                    if (tree_int_cst_equal (low0,
                                            TYPE_MIN_VALUE (TREE_TYPE (low0))))
                      low0 = 0;
                    break;
and similarly for high1.
Without this, the optimization will change behaviour of:
enum enum3
{
  enum3_zero,
  enum3_one,
  enum3_two,
  enum3_three,
  enum3_four,
  enum3_five,
  enum3_six,
  enum3_seven
};

extern "C" void abort ();

void __attribute__((noinline))
test (enum3 x)
{
  if (x == enum3_zero || x == enum3_seven)
    abort ();
}

void __attribute__((noinline))
foo (unsigned int x)
{
  test ((enum3) x);
}

int
main (void)
{
  foo (8);
  return 0;
}

I'm aware that the conversion of 8 to enum3 type is unspecified in C++,
though am not sure if this optimization for such cases is worth the trouble.

	Jakub



More information about the Gcc-patches mailing list