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;

Reply via email to