On Mon, Aug 22, 2016 at 9:10 AM, Richard Biener <richard.guent...@gmail.com> wrote: > On Sat, Aug 20, 2016 at 1:38 AM, Patrick Palka <patr...@parcs.ath.cx> wrote: >> On Fri, Aug 19, 2016 at 7:30 PM, Patrick Palka <patr...@parcs.ath.cx> wrote: >>> integer_nonzerop() currently unconditionally returns false for a >>> VECTOR_CST argument. This is confusing because one would expect that >>> integer_onep(x) => integer_nonzerop(x) for all x but that is currently >>> not the case. For a VECTOR_CST of all ones i.e. {1,1,1,1}, >>> integer_onep() returns true but integer_nonzerop() returns false. >>> >>> This patch makes integer_nonzerop() handle VECTOR_CSTs in the obvious >>> way and also adds some self tests (the last of which fails without the >>> change). Does this look OK to commit afetr bootstrap + regtesting on >>> x86_64-pc-linux-gnu? >> >> Actually I guess there is some ambiguity as to whether >> integer_nonzerop() should return true for a VECTOR_CST only if it has >> at least one non-zero element or only if all of its elements are >> non-zero... > > From its documentation it looks like integer_nonzerop would be the > same as ! integer_zerop if you pass in a tree code that is handled > by integer_zerop. So I guess it doesn't really make sense to ask > this for a vector?
Thus eventually a cleanup would be to share a common worker for most of the predicates, returning a enum which also contains UNHANDLED and wrap all of the predicates around that... Richard. > Richard. > >>> >>> gcc/ChangeLog: >>> >>> * tree.c (integer_nonzerop): Rewrite to use a switch. Handle >>> VECTOR_CSTs. >>> (test_vector_constants): New static function. >>> (tree_c_tests): Call it. >>> --- >>> gcc/tree.c | 43 ++++++++++++++++++++++++++++++++++++++----- >>> 1 file changed, 38 insertions(+), 5 deletions(-) >>> >>> diff --git a/gcc/tree.c b/gcc/tree.c >>> index 33e6f97..48795c7 100644 >>> --- a/gcc/tree.c >>> +++ b/gcc/tree.c >>> @@ -2439,11 +2439,24 @@ integer_pow2p (const_tree expr) >>> int >>> integer_nonzerop (const_tree expr) >>> { >>> - return ((TREE_CODE (expr) == INTEGER_CST >>> - && !wi::eq_p (expr, 0)) >>> - || (TREE_CODE (expr) == COMPLEX_CST >>> - && (integer_nonzerop (TREE_REALPART (expr)) >>> - || integer_nonzerop (TREE_IMAGPART (expr))))); >>> + switch (TREE_CODE (expr)) >>> + { >>> + case INTEGER_CST: >>> + return !wi::eq_p (expr, 0); >>> + case COMPLEX_CST: >>> + return (integer_nonzerop (TREE_REALPART (expr)) >>> + || integer_nonzerop (TREE_IMAGPART (expr))); >>> + case VECTOR_CST: >>> + { >>> + unsigned i; >>> + for (i = 0; i < VECTOR_CST_NELTS (expr); ++i) >>> + if (integer_nonzerop (VECTOR_CST_ELT (expr, i))) >>> + return true; >>> + return false; >>> + } >>> + default: >>> + return false; >>> + } >>> } >>> >>> /* Return 1 if EXPR is the integer constant one. For vector, >>> @@ -14230,6 +14243,25 @@ test_integer_constants () >>> ASSERT_EQ (type, TREE_TYPE (zero)); >>> } >>> >>> +/* Verify various predicates and operations on vector constants. */ >>> + >>> +static void >>> +test_vector_constants () >>> +{ >>> + tree inner_type = integer_type_node; >>> + tree type = build_vector_type (inner_type, 8); >>> + tree zero = build_zero_cst (type); >>> + tree one = build_one_cst (type); >>> + >>> + ASSERT_TRUE (integer_zerop (zero)); >>> + ASSERT_FALSE (integer_onep (zero)); >>> + ASSERT_FALSE (integer_nonzerop (zero)); >>> + >>> + ASSERT_FALSE (integer_zerop (one)); >>> + ASSERT_TRUE (integer_onep (one)); >>> + ASSERT_TRUE (integer_nonzerop (one)); >>> +} >>> + >>> /* Verify identifiers. */ >>> >>> static void >>> @@ -14258,6 +14290,7 @@ void >>> tree_c_tests () >>> { >>> test_integer_constants (); >>> + test_vector_constants (); >>> test_identifiers (); >>> test_labels (); >>> } >>> -- >>> 2.9.3.650.g20ba99f >>>