cmp (lt ge)
(simplify
(op (clz:s@2 @0) INTEGER_CST@1)
- (if (integer_zerop (@1) && single_use (@2))
- /* clz(X) == 0 is (int)X < 0 and clz(X) != 0 is (int)X >= 0. */
- (with { tree stype = signed_type_for (TREE_TYPE (@0)); }
- (cmp (convert:stype @0) { build_zero_cst (stype); }))
- /* clz(X) == (prec-1) is X == 1 and clz(X) != (prec-1) is X != 1. */
- (if (wi::to_wide (@1) == TYPE_PRECISION (TREE_TYPE (@0)) - 1)
- (op @0 { build_one_cst (TREE_TYPE (@0)); }))))))
+ (if (!sanitize_flags_p (SANITIZE_BUILTIN)
+ /* For -fsanitize=builtin give ubsan pass a chance
+ to instrument it first. */
+ || (cfun && (cfun->curr_properties & PROP_ssa) != 0))
+ (if (integer_zerop (@1) && single_use (@2))
+ /* clz(X) == 0 is (int)X < 0 and clz(X) != 0 is (int)X >= 0. */
+ (with { tree stype = signed_type_for (TREE_TYPE (@0)); }
+ (cmp (convert:stype @0) { build_zero_cst (stype); }))
+ /* clz(X) == (prec-1) is X == 1 and clz(X) != (prec-1) is X != 1. */
+ (if (wi::to_wide (@1) == TYPE_PRECISION (TREE_TYPE (@0)) - 1)
+ (op @0 { build_one_cst (TREE_TYPE (@0)); })))))))
(for op (eq ne)
cmp (lt ge)
(simplify
(op (ctz:s @0) INTEGER_CST@1)
(with { bool ok = true;
HOST_WIDE_INT val = 0;
- if (!tree_fits_shwi_p (@1))
+ if (sanitize_flags_p (SANITIZE_BUILTIN)
+ /* For -fsanitize=builtin give ubsan pass a chance
+ to instrument it first. */
+ && (!cfun
+ || (cfun->curr_properties & PROP_ssa) == 0))
+ ok = false;
+ else if (!tree_fits_shwi_p (@1))
ok = false;
else
{
(op (ctz:s @0) INTEGER_CST@1)
(with { tree type0 = TREE_TYPE (@0);
int prec = TYPE_PRECISION (type0);
+ bool ok = true;
+ if (sanitize_flags_p (SANITIZE_BUILTIN)
+ /* For -fsanitize=builtin give ubsan pass a chance
+ to instrument it first. */
+ && (!cfun
+ || (cfun->curr_properties & PROP_ssa) == 0))
+ ok = false;
}
- (if (prec <= MAX_FIXED_MODE_SIZE)
+ (if (ok && prec <= MAX_FIXED_MODE_SIZE)
(if (tree_int_cst_sgn (@1) < 0 || wi::to_widest (@1) >= prec)
{ constant_boolean_node (op == EQ_EXPR ? false : true, type); }
(op (bit_and @0 { wide_int_to_tree (type0,
else if (TYPE_PRECISION (type0)
== TYPE_PRECISION (long_long_unsigned_type_node))
cfn = CFN_BUILT_IN_CTZLL;
- } }
+ }
+ if (sanitize_flags_p (SANITIZE_BUILTIN)
+ /* For -fsanitize=builtin give ubsan pass a chance
+ to instrument it first. */
+ && (!cfun
+ || (cfun->curr_properties & PROP_ssa) == 0))
+ cfn = CFN_LAST; }
(if (cfn == CFN_CTZ)
(IFN_CTZ (convert:type0 @0))
(if (cfn == CFN_BUILT_IN_CTZ)
--- /dev/null
+/* PR sanitizer/115127 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined" } */
+
+#include <stdio.h>
+
+__attribute__((noipa)) int
+f1 (unsigned a)
+{
+ return __builtin_clz (a) == 0;
+}
+
+__attribute__((noipa)) int
+f2 (unsigned long a)
+{
+ return __builtin_clzl (a) != 0;
+}
+
+__attribute__((noipa)) int
+f3 (unsigned long long a)
+{
+ return __builtin_clzll (a) == __CHAR_BIT__ * __SIZEOF_LONG_LONG__ - 1;
+}
+
+__attribute__((noipa)) int
+f4 (unsigned a)
+{
+ return __builtin_clz (a) != __CHAR_BIT__ * __SIZEOF_INT__ - 1;
+}
+
+__attribute__((noipa)) int
+f5 (unsigned long a)
+{
+ return __builtin_ctzl (a) == 0;
+}
+
+__attribute__((noipa)) int
+f6 (unsigned long long a)
+{
+ return __builtin_ctzll (a) != 0;
+}
+
+__attribute__((noipa)) int
+f7 (unsigned a)
+{
+ return __builtin_ctz (a) == 4;
+}
+
+__attribute__((noipa)) int
+f8 (unsigned long a)
+{
+ return __builtin_ctzl (a) != 4;
+}
+
+__attribute__((noipa)) int
+f9 (unsigned long long a)
+{
+ return __builtin_ctzll (a) >= 4;
+}
+
+__attribute__((noipa)) int
+f10 (unsigned a)
+{
+ return __builtin_ctz (a) < 4;
+}
+
+int
+main ()
+{
+ fprintf (stderr, "FOO MARKER1\n");
+ f1 (0);
+ f2 (0);
+ f3 (0);
+ f4 (0);
+ fprintf (stderr, "FOO MARKER2\n");
+ f5 (0);
+ f6 (0);
+ f7 (0);
+ f8 (0);
+ f9 (0);
+ f10 (0);
+ fprintf (stderr, "FOO MARKER3\n");
+}
+
+/* { dg-output "FOO MARKER1(\n|\r\n|\r)" } */
+/* { dg-output "(\[^\n\r]*runtime error: passing zero to __builtin_clz\\\(\\\), which is not a valid argument\[^\n\r]*(\n|\r\n|\r)){4}" } */
+/* { dg-output "FOO MARKER2(\n|\r\n|\r)" } */
+/* { dg-output "(\[^\n\r]*runtime error: passing zero to __builtin_ctz\\\(\\\), which is not a valid argument\[^\n\r]*(\n|\r\n|\r)){6}" } */
+/* { dg-output "FOO MARKER3" } */