new file mode 100644
@@ -0,0 +1,31 @@
+/* { dg-options "-O2" } */
+
+void runtime_error (void) __attribute__ ((noreturn));
+void compiletime_error (void) __attribute__ ((noreturn, error ("")));
+
+static void
+compiletime_check_equals_1 (int *x, int y)
+{
+ int __p = *x != y;
+ if (__builtin_constant_p (__p) && __p)
+ compiletime_error ();
+ if (__p)
+ runtime_error ();
+}
+
+static void
+compiletime_check_equals_2 (int *x, int y)
+{
+ int __p = *x != y;
+ if (__builtin_constant_p (__p) && __p)
+ compiletime_error (); /* { dg-error "call to" } */
+ if (__p)
+ runtime_error ();
+}
+
+void
+foo (int *x)
+{
+ compiletime_check_equals_1 (x, 5);
+ compiletime_check_equals_2 (x, 10);
+}
@@ -5634,6 +5634,7 @@ register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
the value zero or one, then we may be able to assert values
for SSA_NAMEs which flow into COND. */
+
/* In the case of NAME == 1 or NAME != 0, for BIT_AND_EXPR defining
statement of NAME we can assert both operands of the BIT_AND_EXPR
have nonzero value. */
@@ -5673,6 +5674,27 @@ register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
register_edge_assert_for_1 (op1, EQ_EXPR, e, si);
}
}
+
+ /* In the case of NAME != 0 or NAME == 0, if NAME's defining statement
+ is a widening type conversion then we can assert that NAME's
+ RHS is accordingly nonzero or zero. */
+ if ((comp_code == EQ_EXPR || comp_code == NE_EXPR)
+ && integer_zerop (val))
+ {
+ gimple def_stmt = SSA_NAME_DEF_STMT (name);
+ if (is_gimple_assign (def_stmt))
+ {
+ enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
+ if (CONVERT_EXPR_CODE_P (def_code))
+ {
+ tree lhs = gimple_assign_lhs (def_stmt);
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ if (TYPE_PRECISION (TREE_TYPE (lhs))
+ >= TYPE_PRECISION (TREE_TYPE (rhs)))
+ register_edge_assert_for_1 (rhs, comp_code, e, si);
+ }
+ }
+ }
}