From: Jakub Jelinek Date: Fri, 18 Jun 2004 23:15:59 +0000 (+0200) Subject: fold-const.c (build_range_check): If !in_p and recursive call fails, exit immediately. X-Git-Tag: releases/gcc-4.0.0~7545 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=e1af8299421eb7261ddcadf3630cf6dfa6c32099;p=gcc.git fold-const.c (build_range_check): If !in_p and recursive call fails, exit immediately. * fold-const.c (build_range_check): If !in_p and recursive call fails, exit immediately. If high - low overflows and etype is a signed type, retry with unsigned etype. (merge_ranges): If !in0_p and !in1_p, handle even range2 adjacent to range1 at TYPE_MAX_VALUE and TYPE_MIN_VALUE. * gcc.dg/range-test-1.c: New test. * g++.dg/opt/range-test-1.C: New test. From-SVN: r83369 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9ac5634c0272..069c48e0f9b9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2004-06-19 Jakub Jelinek + + * fold-const.c (build_range_check): If !in_p and recursive call + fails, exit immediately. If high - low overflows and etype is + a signed type, retry with unsigned etype. + (merge_ranges): If !in0_p and !in1_p, handle even range2 adjacent + to range1 at TYPE_MAX_VALUE and TYPE_MIN_VALUE. + 2004-06-18 Richard Henderson * c-gimplify.c (gimplify_condition): Remove. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index f559fffeede0..00fd1346e2c6 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3776,7 +3776,7 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh) /* Given a range, LOW, HIGH, and IN_P, an expression, EXP, and a result type, TYPE, return an expression to test if EXP is in (or out of, depending - on IN_P) the range. */ + on IN_P) the range. Return 0 if the test couldn't be created. */ static tree build_range_check (tree type, tree exp, int in_p, tree low, tree high) @@ -3784,9 +3784,14 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high) tree etype = TREE_TYPE (exp); tree value; - if (! in_p - && (0 != (value = build_range_check (type, exp, 1, low, high)))) - return invert_truthvalue (value); + if (! in_p) + { + value = build_range_check (type, exp, 1, low, high); + if (value != 0) + return invert_truthvalue (value); + + return 0; + } if (low == 0 && high == 0) return fold_convert (type, integer_one_node); @@ -3842,8 +3847,39 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high) } } - if (0 != (value = const_binop (MINUS_EXPR, high, low, 0)) - && ! TREE_OVERFLOW (value)) + value = const_binop (MINUS_EXPR, high, low, 0); + if (value != 0 && TREE_OVERFLOW (value) && ! TYPE_UNSIGNED (etype)) + { + tree utype, minv, maxv; + + /* Check if (unsigned) INT_MAX + 1 == (unsigned) INT_MIN + for the type in question, as we rely on this here. */ + switch (TREE_CODE (etype)) + { + case INTEGER_TYPE: + case ENUMERAL_TYPE: + case CHAR_TYPE: + utype = lang_hooks.types.unsigned_type (etype); + maxv = fold_convert (utype, TYPE_MAX_VALUE (etype)); + maxv = range_binop (PLUS_EXPR, NULL_TREE, maxv, 1, + integer_one_node, 1); + minv = fold_convert (utype, TYPE_MIN_VALUE (etype)); + if (integer_zerop (range_binop (NE_EXPR, integer_type_node, + minv, 1, maxv, 1))) + { + etype = utype; + high = fold_convert (etype, high); + low = fold_convert (etype, low); + exp = fold_convert (etype, exp); + value = const_binop (MINUS_EXPR, high, low, 0); + } + break; + default: + break; + } + } + + if (value != 0 && ! TREE_OVERFLOW (value)) return build_range_check (type, fold (build2 (MINUS_EXPR, etype, exp, low)), 1, fold_convert (etype, integer_zero_node), @@ -3973,7 +4009,75 @@ merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0, 1, low1, 0))) in_p = 0, low = low0, high = high1; else - return 0; + { + /* Canonicalize - [min, x] into - [-, x]. */ + 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 CHAR_TYPE: + if (tree_int_cst_equal (low0, + TYPE_MIN_VALUE (TREE_TYPE (low0)))) + low0 = 0; + break; + case POINTER_TYPE: + if (TYPE_UNSIGNED (TREE_TYPE (low0)) + && integer_zerop (low0)) + low0 = 0; + break; + default: + break; + } + + /* Canonicalize - [x, max] into - [x, -]. */ + if (high1 && TREE_CODE (high1) == INTEGER_CST) + switch (TREE_CODE (TREE_TYPE (high1))) + { + case ENUMERAL_TYPE: + if (TYPE_PRECISION (TREE_TYPE (high1)) + != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (high1)))) + break; + /* FALLTHROUGH */ + case INTEGER_TYPE: + case CHAR_TYPE: + if (tree_int_cst_equal (high1, + TYPE_MAX_VALUE (TREE_TYPE (high1)))) + high1 = 0; + break; + case POINTER_TYPE: + if (TYPE_UNSIGNED (TREE_TYPE (high1)) + && integer_zerop (range_binop (PLUS_EXPR, NULL_TREE, + high1, 1, + integer_one_node, 1))) + high1 = 0; + break; + default: + break; + } + + /* The ranges might be also adjacent between the maximum and + minimum values of the given type. For + - [{min,-}, x] and - [y, {max,-}] ranges where x + 1 < y + return + [x + 1, y - 1]. */ + if (low0 == 0 && high1 == 0) + { + low = range_binop (PLUS_EXPR, NULL_TREE, high0, 1, + integer_one_node, 1); + high = range_binop (MINUS_EXPR, NULL_TREE, low1, 0, + integer_one_node, 0); + if (low == 0 || high == 0) + return 0; + + in_p = 1; + } + else + return 0; + } } else if (subset) in_p = 0, low = low0, high = high0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c2bbd33d1520..f7e42f1587d6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-06-19 Jakub Jelinek + + * gcc.dg/range-test-1.c: New test. + * g++.dg/opt/range-test-1.C: New test. + 2004-06-17 Richard Henderson * objc.dg/sync-1.m: New. diff --git a/gcc/testsuite/g++.dg/opt/range-test-1.C b/gcc/testsuite/g++.dg/opt/range-test-1.C new file mode 100644 index 000000000000..9391748837e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/range-test-1.C @@ -0,0 +1,212 @@ +// Test fold-const.c (fold_range_test) optimizations. +// { dg-do run } */ +// { dg-options "-O2" } */ + +#include +#include +#include + +#if (INT_MAX == 2147483647) && (INT_MIN == -2147483648) \ + && (SCHAR_MIN == -128) && (SCHAR_MAX == 127) \ + && (UCHAR_MIN == 0) && (UCHAR_MAX == 255) + +#ifndef T + +enum integers +{ + int_smallest = INT_MIN, + int_2ndsmallest = INT_MIN + 1, + int_3rdsmallest = INT_MIN + 2, + int_minus2 = -2, + int_minus1 = -1, + int_zero = 0, + int_one = 1, + int_two = 2, + int_3rdlargest = INT_MAX - 2, + int_2ndlargest = INT_MAX - 1, + int_largest = INT_MAX +}; + +enum smallenum +{ + smalle_minus4 = -4, + smalle_minus3 = -3, + smalle_minus2 = -2, + smalle_minus1 = -1, + smalle_zero = 0, + smalle_one = 1, + smalle_two = 2, + smalle_three = 3 +}; + +enum enum2 +{ + enum2_two = 2, + enum2_three = 3, + enum2_four = 4, + enum2_five = 5 +}; + +enum enum3 +{ + enum3_zero, + enum3_one, + enum3_two, + enum3_three, + enum3_four, + enum3_five, + enum3_six, + enum3_seven +}; + +int var; +void +check () +{ + ++var; +} + +#define T(IDX, TYPE, TEST, YESARR, NOARR) \ +void __attribute__((noinline)) \ +test##IDX (TYPE x) \ +{ \ + if (TEST) \ + check (); \ +} +#include "range-test-1.C" +#undef T + +int +main () +{ + int i, fails = 0; + +#define C , +#define T(IDX, TYPE, TEST, YESARR, NOARR) \ + { \ + static TYPE yesarr##IDX [] = YESARR; \ + static TYPE noarr##IDX [] = NOARR; \ + for (i = 0; i < (int) (sizeof (yesarr##IDX) / sizeof (TYPE)); ++i) \ + { \ + var = 0; \ + test##IDX (yesarr##IDX [i]); \ + if (var != 1) \ + printf ("test" #IDX " failed for yesarr [%u]\n", i), ++fails; \ + } \ + var = 0; \ + for (i = 0; i < (int) (sizeof (noarr##IDX) / sizeof (TYPE)); ++i) \ + { \ + test##IDX (noarr##IDX [i]); \ + if (var != 0) \ + printf ("test" #IDX " failed for noarr [%u]\n", i), ++fails; \ + } \ + } +#include "range-test-1.C" +#undef T + + if (fails) + abort (); + + exit (0); +} + +#else + +/* Use `C' instead of `,' below to separate array entries. */ + +/* These ought to be all optimized into single comparison. */ +T(1, unsigned int, x == 0 || x == 1, + { 0 C 1 }, { -1U C 2 C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(2, unsigned int, x == 0 || x == -1U || x == -2U, + { 0 C -1U C -2U }, { -3U C -6U C 1 C 2 C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(3, unsigned int, x == 0 || x == 1 || x == 2, + { 0 C 1 C 2 }, { -3U C -6U C -1U C -2U C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(4, unsigned int, x == 3 || x == 4 || x == 5 || x == 6, + { 3 C 4 C 5 C 6 }, { -3U C 0 C 1 C 2 C 7 C 8 C 12 C 0x7fffffff C 0x80000000 }) +T(5, unsigned int, x == -3U || x == -4U || x == -5U || x == -6U, + { -3U C -4U C -5U C -6U }, { -7U C -8U C -2U C -1U C 1 C 2 C 0x7fffffff C 0x80000000 }) +T(6, unsigned int, x == -3U || x == -4U || x == -5U, + { -3U C -4U C -5U }, { -6U C -7U C -8U C -2U C -1U C 1 C 2 C 0x7fffffff C 0x80000000 }) +T(7, char *, x == (char *) -3UL || x == (char *) -4UL || x == (char *) -5UL, + { (char *) -3UL C (char *) -4UL C (char *) -5UL }, + { (char *) -6UL C (char *) -20UL C (char *) -2UL C (char *) -1UL C (char *) 0 + C (char *) 1UL C (char *) 35UL C (char *) 0x7fffffffUL C (char *) 0x80000000UL }) +T(8, unsigned long, x == -2UL || x == -1UL || x == 0, + { 0 C -1UL C -2UL }, { -3UL C -6UL C 1 C 2 C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(9, unsigned long, x >= -4UL || x <= 8, + { -4UL C -3UL C -2UL C -1UL C 0 C 1 C 2 C 3 C 4 C 5 C 6 C 7 C 8 }, + { -7UL C -5UL C 9 C 10 C 61 C 127 C 0x7fffffff C 0x80000000 }) +T(10, signed char, x == 0 || x == -1 || x == -2 || x == -3, + { 0 C -1 C -2 C -3 }, { -4 C -5 C 1 C 2 C 3 C 35 C -24 }) +T(11, int, x == 0 || x == 1, + { 0 C 1 }, { -1 C 2 C 12 C 35 C INT_MAX C INT_MIN }) +T(12, int, x == 0 || x == -1 || x == -2, + { 0 C -1 C -2 }, { -3 C -6 C 1 C 2 C 12 C 35 C INT_MAX C INT_MIN }) +T(13, int, x == 0 || x == 1 || x == 2, + { 0 C 1 C 2 }, { -3 C -6 C -1 C -2 C 12 C 35 C INT_MAX C INT_MIN }) +T(14, int, x == 3 || x == 4 || x == 5 || x == 6, + { 3 C 4 C 5 C 6 }, { -3 C 0 C 1 C 2 C 7 C 8 C 12 C INT_MAX C INT_MIN }) +T(15, int, x == -3 || x == -4 || x == -5 || x == -6, + { -3 C -4 C -5 C -6 }, { -7 C -8 C -2 C -1 C 1 C 2 C INT_MAX C INT_MIN }) +T(16, int, x == -3 || x == -4 || x == -5, + { -3 C -4 C -5 }, { -6 C -7 C -8 C -2 C -1 C 1 C 2 C INT_MAX C INT_MIN }) +T(17, unsigned int, (x >= -8U && x <= -3U) || x == -2U || x == -1U || x == 0 || x == 1 || x == 2, + { -8U C -7U C -6U C -5U C -4U C -3U C -2U C -1U C 0 C 1 C 2 }, + { -9U C -10U C 3 C 4 C 12 C -54U C INT_MAX C INT_MIN }) +T(18, int, (x >= -8 && x <= -3) || x == -2 || x == -1 || x == 0 || x == 1 || x == 2, + { -8 C -7 C -6 C -5 C -4 C -3 C -2 C -1 C 0 C 1 C 2 }, + { -9 C -10 C 3 C 4 C 12 C -54 C INT_MAX C INT_MIN }) +T(19, unsigned long, x <= 16 || (x >= 18 && x <= -1UL), + { -3UL C -6UL C -1UL C 0 C 1 C 2 C 12 C 15 C 16 C 18 C 19 C 35 C 0x7fffffff + C 0x80000000 }, { 17 }) +T(20, char *, x == (char *) -1UL || x == 0, + { (char *) -1UL C 0 }, { (char *) -6UL C (char *) -20UL C (char *) -2UL + C (char *) 1UL C (char *) 35UL C (char *) 0x7fffffffUL C (char *) 0x80000000UL }) +T(21, integers, x == int_zero || x == int_one, + { int_zero C int_one }, { int_minus1 C int_two C int_largest C int_smallest }) +T(22, int, x == INT_MIN || x == INT_MAX, + { INT_MIN C INT_MAX }, + { -1 C 0 C 1 C INT_MAX - 1 C INT_MAX - 2 C INT_MIN + 1 C INT_MIN + 2 }) +T(23, int, x == INT_MIN + 1 || x == INT_MIN + 2 || x == INT_MIN || x == INT_MAX, + { INT_MIN + 1 C INT_MIN + 2 C INT_MIN C INT_MAX }, + { -1 C 0 C 1 C INT_MAX - 1 C INT_MAX - 2 C INT_MIN + 3 C INT_MIN + 4 }) +T(24, signed char, x == SCHAR_MIN || x == SCHAR_MAX, + { SCHAR_MIN C SCHAR_MAX }, + { -1 C 0 C 1 C SCHAR_MAX - 1 C SCHAR_MAX - 2 C SCHAR_MIN + 1 C SCHAR_MIN + 2 }) +T(25, integers, x == int_smallest || x == int_largest, + { int_smallest C int_largest }, { int_minus1 C int_zero C int_one + C int_2ndsmallest C int_2ndlargest C int_3rdsmallest C int_3rdlargest }) + +/* These should be optimized into unconditional jumps. */ +T(o1, unsigned long, x <= 16 || (x >= 17 && x <= -1UL), + { -3UL C -6UL C -1UL C 0 C 1 C 2 C 12 C 15 C 16 C 17 C 18 C 19 C 35 C 0x7fffffff + C 0x80000000 }, { }) +T(o2, unsigned long, x <= -3UL || (x == -2UL || x == -1UL), + { -3UL C -6UL C -1UL C 0 C 1 C 2 C 12 C 15 C 16 C 17 C 18 C 19 C 35 C 0x7fffffff + C 0x80000000 }, { }) + +/* These should be eventually optimized into a single comparison. */ +T(td1, unsigned char, x == 0 || x == 4 || x == 1 || x == 5 || x == 2 || x == 6 || x == 3, + { 0 C 1 C 2 C 3 C 4 C 5 C 6 }, { 7 C 8 C 127 C 128 C 254 C 255 }) + +/* These should not be optimized into a single comparison. */ +T(n1, smallenum, x == smalle_minus4 || x == smalle_three, + { smalle_minus4 C smalle_three }, { smalle_minus3 C smalle_minus2 C smalle_minus1 + C smalle_zero C smalle_one C smalle_two }) +T(n2, enum2, x == enum2_two || x == enum2_five, + { enum2_two C enum2_five }, { enum2_three C enum2_four }) +T(n3, enum3, x == enum3_zero || x == enum3_seven, + { enum3_zero C enum3_seven }, { enum3_one C enum3_two C enum3_three C enum3_four + C enum3_five C enum3_six }) + +#endif + +#else + +int +main (void) +{ + return 0; +} + +#endif diff --git a/gcc/testsuite/gcc.dg/range-test-1.c b/gcc/testsuite/gcc.dg/range-test-1.c new file mode 100644 index 000000000000..93a90ac7187b --- /dev/null +++ b/gcc/testsuite/gcc.dg/range-test-1.c @@ -0,0 +1,168 @@ +/* Test fold-const.c (fold_range_test) optimizations. */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include +#include +#include + +#if (INT_MAX == 2147483647) && (INT_MIN == -2147483648) \ + && (SCHAR_MIN == -128) && (SCHAR_MAX == 127) \ + && (UCHAR_MIN == 0) && (UCHAR_MAX == 255) + +#ifndef T + +enum integers +{ + int_smallest = INT_MIN, + int_2ndsmallest = INT_MIN + 1, + int_3rdsmallest = INT_MIN + 2, + int_minus2 = -2, + int_minus1 = -1, + int_zero = 0, + int_one = 1, + int_two = 2, + int_3rdlargest = INT_MAX - 2, + int_2ndlargest = INT_MAX - 1, + int_largest = INT_MAX +}; + +int var; +void +check (void) +{ + ++var; +} + +#define T(IDX, TYPE, TEST, YESARR, NOARR) \ +void __attribute__((noinline)) \ +test##IDX (TYPE x) \ +{ \ + if (TEST) \ + check (); \ +} +#include "range-test-1.c" +#undef T + +int +main (void) +{ + int i, fails = 0; + +#define C , +#define T(IDX, TYPE, TEST, YESARR, NOARR) \ + { \ + static TYPE yesarr##IDX [] = YESARR; \ + static TYPE noarr##IDX [] = NOARR; \ + for (i = 0; i < (int) (sizeof (yesarr##IDX) / sizeof (TYPE)); ++i) \ + { \ + var = 0; \ + test##IDX (yesarr##IDX [i]); \ + if (var != 1) \ + printf ("test" #IDX " failed for yesarr [%u]\n", i), ++fails; \ + } \ + var = 0; \ + for (i = 0; i < (int) (sizeof (noarr##IDX) / sizeof (TYPE)); ++i) \ + { \ + test##IDX (noarr##IDX [i]); \ + if (var != 0) \ + printf ("test" #IDX " failed for noarr [%u]\n", i), ++fails; \ + } \ + } +#include "range-test-1.c" +#undef T + + if (fails) + abort (); + + exit (0); +} + +#else + +/* Use `C' instead of `,' below to separate array entries. */ + +/* These ought to be all optimized into single comparison. */ +T(1, unsigned int, x == 0 || x == 1, + { 0 C 1 }, { -1U C 2 C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(2, unsigned int, x == 0 || x == -1U || x == -2U, + { 0 C -1U C -2U }, { -3U C -6U C 1 C 2 C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(3, unsigned int, x == 0 || x == 1 || x == 2, + { 0 C 1 C 2 }, { -3U C -6U C -1U C -2U C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(4, unsigned int, x == 3 || x == 4 || x == 5 || x == 6, + { 3 C 4 C 5 C 6 }, { -3U C 0 C 1 C 2 C 7 C 8 C 12 C 0x7fffffff C 0x80000000 }) +T(5, unsigned int, x == -3U || x == -4U || x == -5U || x == -6U, + { -3U C -4U C -5U C -6U }, { -7U C -8U C -2U C -1U C 1 C 2 C 0x7fffffff C 0x80000000 }) +T(6, unsigned int, x == -3U || x == -4U || x == -5U, + { -3U C -4U C -5U }, { -6U C -7U C -8U C -2U C -1U C 1 C 2 C 0x7fffffff C 0x80000000 }) +T(7, char *, x == (char *) -3UL || x == (char *) -4UL || x == (char *) -5UL, + { (char *) -3UL C (char *) -4UL C (char *) -5UL }, + { (char *) -6UL C (char *) -20UL C (char *) -2UL C (char *) -1UL C (char *) 0 + C (char *) 1UL C (char *) 35UL C (char *) 0x7fffffffUL C (char *) 0x80000000UL }) +T(8, unsigned long, x == -2UL || x == -1UL || x == 0, + { 0 C -1UL C -2UL }, { -3UL C -6UL C 1 C 2 C 12 C 35 C 0x7fffffff C 0x80000000 }) +T(9, unsigned long, x >= -4UL || x <= 8, + { -4UL C -3UL C -2UL C -1UL C 0 C 1 C 2 C 3 C 4 C 5 C 6 C 7 C 8 }, + { -7UL C -5UL C 9 C 10 C 61 C 127 C 0x7fffffff C 0x80000000 }) +T(10, signed char, x == 0 || x == -1 || x == -2 || x == -3, + { 0 C -1 C -2 C -3 }, { -4 C -5 C 1 C 2 C 3 C 35 C -24 }) +T(11, int, x == 0 || x == 1, + { 0 C 1 }, { -1 C 2 C 12 C 35 C INT_MAX C INT_MIN }) +T(12, int, x == 0 || x == -1 || x == -2, + { 0 C -1 C -2 }, { -3 C -6 C 1 C 2 C 12 C 35 C INT_MAX C INT_MIN }) +T(13, int, x == 0 || x == 1 || x == 2, + { 0 C 1 C 2 }, { -3 C -6 C -1 C -2 C 12 C 35 C INT_MAX C INT_MIN }) +T(14, int, x == 3 || x == 4 || x == 5 || x == 6, + { 3 C 4 C 5 C 6 }, { -3 C 0 C 1 C 2 C 7 C 8 C 12 C INT_MAX C INT_MIN }) +T(15, int, x == -3 || x == -4 || x == -5 || x == -6, + { -3 C -4 C -5 C -6 }, { -7 C -8 C -2 C -1 C 1 C 2 C INT_MAX C INT_MIN }) +T(16, int, x == -3 || x == -4 || x == -5, + { -3 C -4 C -5 }, { -6 C -7 C -8 C -2 C -1 C 1 C 2 C INT_MAX C INT_MIN }) +T(17, unsigned int, (x >= -8U && x <= -3U) || x == -2U || x == -1U || x == 0 || x == 1 || x == 2, + { -8U C -7U C -6U C -5U C -4U C -3U C -2U C -1U C 0 C 1 C 2 }, + { -9U C -10U C 3 C 4 C 12 C -54U C INT_MAX C INT_MIN }) +T(18, int, (x >= -8 && x <= -3) || x == -2 || x == -1 || x == 0 || x == 1 || x == 2, + { -8 C -7 C -6 C -5 C -4 C -3 C -2 C -1 C 0 C 1 C 2 }, + { -9 C -10 C 3 C 4 C 12 C -54 C INT_MAX C INT_MIN }) +T(19, unsigned long, (x >= 0 && x <= 16) || (x >= 18 && x <= -1UL), + { -3UL C -6UL C -1UL C 0 C 1 C 2 C 12 C 15 C 16 C 18 C 19 C 35 C 0x7fffffff + C 0x80000000 }, { 17 }) +T(20, char *, x == (char *) -1UL || x == 0, + { (char *) -1UL C 0 }, { (char *) -6UL C (char *) -20UL C (char *) -2UL + C (char *) 1UL C (char *) 35UL C (char *) 0x7fffffffUL C (char *) 0x80000000UL }) +T(21, enum integers, x == int_zero || x == int_one, + { int_zero C int_one }, { int_minus1 C int_two C 12 C 35 C int_largest C int_smallest }) +T(22, int, x == INT_MIN || x == INT_MAX, + { INT_MIN C INT_MAX }, + { -1 C 0 C 1 C INT_MAX - 1 C INT_MAX - 2 C INT_MIN + 1 C INT_MIN + 2 }) +T(23, int, x == INT_MIN + 1 || x == INT_MIN + 2 || x == INT_MIN || x == INT_MAX, + { INT_MIN + 1 C INT_MIN + 2 C INT_MIN C INT_MAX }, + { -1 C 0 C 1 C INT_MAX - 1 C INT_MAX - 2 C INT_MIN + 3 C INT_MIN + 4 }) +T(24, signed char, x == SCHAR_MIN || x == SCHAR_MAX, + { SCHAR_MIN C SCHAR_MAX }, + { -1 C 0 C 1 C SCHAR_MAX - 1 C SCHAR_MAX - 2 C SCHAR_MIN + 1 C SCHAR_MIN + 2 }) +T(25, enum integers, x == int_smallest || x == int_largest, + { int_smallest C int_largest }, { int_minus1 C int_zero C int_one + C int_2ndsmallest C int_2ndlargest C int_3rdsmallest C int_3rdlargest }) + +/* This should be optimized into unconditional jump. */ +T(o1, unsigned long, (x >= 0 && x <= 16) || (x >= 17 && x <= -1UL), + { -3UL C -6UL C -1UL C 0 C 1 C 2 C 12 C 15 C 16 C 17 C 18 C 19 C 35 C 0x7fffffff + C 0x80000000 }, { }) +T(o2, unsigned long, (x >= 0 && x <= -3UL) || (x == -2UL || x == -1UL), + { -3UL C -6UL C -1UL C 0 C 1 C 2 C 12 C 15 C 16 C 17 C 18 C 19 C 35 C 0x7fffffff + C 0x80000000 }, { }) + +/* This should be eventually optimized into a single comparison. */ +T(td1, unsigned char, x == 0 || x == 4 || x == 1 || x == 5 || x == 2 || x == 6 || x == 3, + { 0 C 1 C 2 C 3 C 4 C 5 C 6 }, { 7 C 8 C 127 C 128 C 254 C 255 }) + +#endif + +#else +int +main (void) +{ + return 0; +} +#endif