[RFC][PR target/39726 P4 regression] match.pd pattern to do type narrowing

Joseph Myers joseph@codesourcery.com
Tue Feb 3 12:23:00 GMT 2015


On Tue, 3 Feb 2015, Jeff Law wrote:

> +/* Given a bit-wise operation performed in mode P1 on operands
> +   in some narrower type P2 that feeds an outer masking operation.
> +   See if the mask turns off all the bits outside P2, and if so
> +   perform the all the operations in P2 and just convert the final
> +   result from P1 to P2.  */
> +(for inner_op (bit_and bit_ior bit_xor)
> +  (simplify
> +    (bit_and (inner_op (convert @0) (convert @1)) INTEGER_CST@3)
> +    (if ((TREE_INT_CST_LOW (@3) & ~GET_MODE_MASK (TYPE_MODE (TREE_TYPE (@0)))) == 0

Are you sure about checking TREE_INT_CST_LOW here?  What if the inner type 
is wider than HOST_WIDE_INT?  (That could occur with bit-fields of type 
__int128, for example.)  I think the check for what bits are set needs to 
be written in a wide-int-safe way - maybe something like tree_int_cst_sgn 
(@3) > 0 && tree_int_cst_min_precision (@3, UNSIGNED) <= TYPE_PRECISION 
(TREE_TYPE (@1)).

> +	 && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1))
> +	 && TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (TREE_TYPE (@1))
> +	 && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0)))
> +      (convert (bit_and (inner_op @0 @1) (convert @3))))))

I still don't think this is safe.  Suppose @0 and @1 are -128 in type 
int8_t and @3 is 128 in a wider type and the operation is AND.  Then the 
original expression has result 128.  But if you convert @3 to int8_t you 
get -128 and this would result in -128 from the simplified expression.

If the inner values are signed and the mask includes the sign bit of the 
inner type, you have to zero-extend to the wider type (e.g. convert the 
inner values to unsigned), not sign-extend.

(If the inner values are signed, it's *also* valid to optimize with a mask 
where both the sign bit of the inner type and all higher bits are set, 
such as a mask of -128 above; in that case, you do need to sign-extend.  
If the inner values are unsigned, no check on the mask value is needed at 
all as all higher bits in the mask can just be discarded.  Both of these 
statements only apply for bitwise operations, not arithmetic.)

-- 
Joseph S. Myers
joseph@codesourcery.com



More information about the Gcc-patches mailing list