#endif
/* (nop_outer_cast)-(inner_cast)var -> -(outer_cast)(var)
- if var is smaller in precision.
- This is always safe for both doing the negative in signed or unsigned
- as the value for undefined will not show up.
+ If var is smaller in precision this is always safe for both doing
+ the negative in signed or unsigned as the value for undefined will not
+ show up. Else it is safe if the negation is done in an unsigned type.
Note the outer cast cannot be a boolean type as the only valid values
are 0,-1/1 (depending on the signedness of the boolean) and the negative
is there to get the correct value. */
(convert (negate:s@1 (convert:s @0)))
(if (INTEGRAL_TYPE_P (type)
&& tree_nop_conversion_p (type, TREE_TYPE (@1))
- && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0))
+ && (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (@0))
+ || TYPE_UNSIGNED (type))
&& TREE_CODE (type) != BOOLEAN_TYPE)
(negate (convert @0))))
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi" } */
+
+unsigned int
+ZSTD_countTrailingZeros32_fallback (unsigned int val)
+{
+ static const unsigned int DeBruijn[32]
+ = { 0, 1, 28, 2, 29, 14, 24, 3,
+ 30, 22, 20, 15, 25, 17, 4, 8,
+ 31, 27, 13, 23, 21, 19, 16, 7,
+ 26, 12, 18, 6, 11, 5, 10, 9};
+ return DeBruijn[((unsigned int) ((val & -(int) val) * 0x077CB531U)) >> 27];
+}
+
+/* { dg-final { scan-assembler "tzcnt" } } */