--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target stdint_types } */
+
+#include <stdint.h>
+
+uint64_t var_0 = 18128133247277979402ULL;
+int64_t var_14 = 6557021550272328915LL;
+uint64_t var_83 = 10966786425750692026ULL;
+
+void test()
+{
+ var_14 = var_0 + (_Bool)7;
+ var_83 = 1 + (int)var_0; // 1 + 888395530
+}
+
+int main()
+{
+ test();
+ if (var_83 != 888395531)
+ __builtin_abort ();
+ return 0;
+}
is the same. */
static tree
-valueized_wider_op (tree wide_type, tree op)
+valueized_wider_op (tree wide_type, tree op, bool allow_truncate)
{
if (TREE_CODE (op) == SSA_NAME)
op = vn_valueize (op);
return tem;
/* Or the op is truncated from some existing value. */
- if (TREE_CODE (op) == SSA_NAME)
+ if (allow_truncate && TREE_CODE (op) == SSA_NAME)
{
gimple *def = SSA_NAME_DEF_STMT (op);
if (is_gimple_assign (def)
|| gimple_assign_rhs_code (def) == MULT_EXPR))
{
tree ops[3] = {};
+ /* When requiring a sign-extension we cannot model a
+ previous truncation with a single op so don't bother. */
+ bool allow_truncate = TYPE_UNSIGNED (TREE_TYPE (rhs1));
/* Either we have the op widened available. */
- ops[0] = valueized_wider_op (type,
- gimple_assign_rhs1 (def));
+ ops[0] = valueized_wider_op (type, gimple_assign_rhs1 (def),
+ allow_truncate);
if (ops[0])
- ops[1] = valueized_wider_op (type,
- gimple_assign_rhs2 (def));
+ ops[1] = valueized_wider_op (type, gimple_assign_rhs2 (def),
+ allow_truncate);
if (ops[0] && ops[1])
{
ops[0] = vn_nary_op_lookup_pieces