On Thu, Jul 13, 2017 at 6:18 AM, Andrew Pinski <pins...@gmail.com> wrote:
> On Wed, Jul 12, 2017 at 9:10 PM, Marc Glisse <marc.gli...@inria.fr> wrote:
>> On Wed, 12 Jul 2017, Andrew Pinski wrote:
>>
>>> Hi,
>>>  Unlike most other expressions, BIT_INSERT_EXPR has an implicit
>>> operand of the precision/size of the second operand.  This means if we
>>> have an integer constant for the second operand and that compares to
>>> the same constant value, vn_nary_op_eq would return that these two
>>> expressions are the same.  But in the case I was looking into the
>>> integer constants had different types, one with 1 bit precision and
>>> the other with 2 bit precision which means the BIT_INSERT_EXPR were
>>> not equal at all.
>>>
>>> This patches the problem by checking to see if BIT_INSERT_EXPR's
>>> operand 1's (second operand) type  has different precision to return
>>> false.
>>>
>>> Is this the correct location or should we be checking for this
>>> differently?  If this is the correct location, is the patch ok?
>>> Bootstrapped and tested on aarch64-linux-gnu with no regressions (and
>>> also tested with a few extra patches to expose BIT_INSERT_EXPR).
>>>
>>> Thanks,
>>> Andrew Pinski
>>>
>>> ChangeLog:
>>> * tree-ssa-sccvn.c (vn_nary_op_eq): Check BIT_INSERT_EXPR's operand 1
>>> to see if the types precision matches.
>>
>>
>> Hello,
>>
>> since BIT_INSERT_EXPR is implicitly an expression with 4 arguments, it makes
>> sense that we may need a few such special cases. But shouldn't the hash
>> function be in sync with the equality comparator? Does operand_equal_p need
>> the same?
>
> The hash function does not need to be exactly the same.  The only
> requirement there is if vn_nary_op_eq returns true then the hash has
> to be the same.  Now we could improve the hash by using the precision
> which will allow us not to compare as much in some cases.
>
> Yes operand_equal_p needs the same handling; I did not notice that
> until you mention it..
> Right now it does:
>         case BIT_INSERT_EXPR:
>           return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);

Aww.  The issue is that operand_equal_p treats INTEGER_CSTs of different
type/precision but the same value as equal.

Revisiting that, while a good idea, shouldn't block a fix here.  So ...

Index: tree-ssa-sccvn.c
===================================================================
--- tree-ssa-sccvn.c    (revision 250159)
+++ tree-ssa-sccvn.c    (working copy)
@@ -2636,6 +2636,14 @@ vn_nary_op_eq (const_vn_nary_op_t const
     if (!expressions_equal_p (vno1->op[i], vno2->op[i]))
       return false;

+  /* BIT_INSERT_EXPR has an implict operand as the type precision
+     of op1.  Need to check to make sure they are the same.  */
+  if (vno1->opcode == BIT_INSERT_EXPR)
+    if (INTEGRAL_TYPE_P (TREE_TYPE (vno1->op[0]))
+       && TYPE_PRECISION (TREE_TYPE (vno1->op[1]))
+           != TYPE_PRECISION (TREE_TYPE (vno2->op[1])))
+      return false;
+

the case can be restricted to INTEGER_CST vno1->op[0] I think:

  if (vno1->opcode == BIT_INSERT_EXPR
      && TREE_CODE (vno1->op[0]) == INTEGER_CST
      && TYPE_PRECISION (....

and yes, operand_equal_p needs a similar fix.  Can you re-post with that added?
Do you have a testcase?

Thanks,
Richard.

> Thanks,
> Andrew Pinski
>
>>
>> --
>> Marc Glisse

Reply via email to