Hi, Testing boolean vector conversions I found several runtime regressions and investigation showed it's due to incorrect conversion caused by unsigned boolean type. When boolean vector is represented as an integer vector on target it's a signed integer actually. Unsigned boolean type was chosen due to possible single bit values, but for multiple bit values it causes wrong casting. The easiest way to fix it is to use signed boolean value. The following patch does this and fixes my problems with conversion. Bootstrapped and tested on x86_64-unknown-linux-gnu. Is it OK?
Thanks, Ilya -- gcc/ 2015-10-28 Ilya Enkovich <enkovich....@gmail.com> * optabs.c (expand_vec_cond_expr): Always get sign from type. * tree.c (wide_int_to_tree): Support negative values for boolean. (build_nonstandard_boolean_type): Use signed type for booleans with precision greater than 1. diff --git a/gcc/optabs.c b/gcc/optabs.c index e1ac0b8..37a67f1 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -5373,7 +5373,6 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2, op0a = TREE_OPERAND (op0, 0); op0b = TREE_OPERAND (op0, 1); tcode = TREE_CODE (op0); - unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a)); } else { @@ -5382,9 +5381,9 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2, op0a = op0; op0b = build_zero_cst (TREE_TYPE (op0)); tcode = LT_EXPR; - unsignedp = false; } cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a)); + unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a)); gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode) diff --git a/gcc/tree.c b/gcc/tree.c index e77d4b8..712390f 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1451,7 +1451,7 @@ wide_int_to_tree (tree type, const wide_int_ref &pcst) case BOOLEAN_TYPE: /* Cache false or true. */ limit = 2; - if (hwi < 2) + if (IN_RANGE (hwi, 0, 1)) ix = hwi; break; @@ -8076,7 +8076,10 @@ build_nonstandard_boolean_type (unsigned HOST_WIDE_INT precision) type = make_node (BOOLEAN_TYPE); TYPE_PRECISION (type) = precision; - fixup_unsigned_type (type); + if (precision > 1) + fixup_signed_type (type); + else + fixup_unsigned_type (type); if (precision <= MAX_INT_CACHED_PREC) nonstandard_boolean_type_cache[precision] = type;