https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112843

--- Comment #5 from Andrew Macleod <amacleod at redhat dot com> ---
(In reply to Richard Biener from comment #3)
> (In reply to Richard Biener from comment #2)
> > what?!  Ick.  It definitely shouldn't re-fold anything but only scrap caches
> > _at most_.
> 
> So it does
> 
>   // Only update if it already had a value.
>   if (m_cache.get_global_range (r, lhs))
>     {
>       // Re-calculate a new value using just cache values.
>       Value_Range tmp (TREE_TYPE (lhs));
>       fold_using_range f;
>       fur_stmt src (s, &m_cache);
>       f.fold_stmt (tmp, s, src, lhs);
> 
>       // Combine the new value with the old value to check for a change.
>       if (r.intersect (tmp))
>         {
>           if (dump_file && (dump_flags & TDF_DETAILS))
>             {
>               print_generic_expr (dump_file, lhs, TDF_SLIM);
>               fprintf (dump_file, " : global value re-evaluated to ");
>               r.dump (dump_file);
>               fputc ('\n', dump_file);
>             }
>           m_cache.set_global_range (lhs, r);
> 
> WTF?  If a pass invalidates a range it needs to properly do this itself.
> But update_stmt itself _never_ should alter range info.

what do you mean?  when a statement is changed, it may generate a different
range than it did before, so we re-evaluate the statement to see if the result
is different.  If it is, then we update it in the cache.

All its doing is re-calculating and updating the cache values.

It looks to me like the problem is the stmt is being added in a way that leaves
the IL in an illegal state,

                    tree lhs2 = make_ssa_name (type);
                    gimple *g = gimple_build_assign (lhs, NOP_EXPR, lhs2);
                    if (stmt_ends_bb_p (stmt))
                      {
                        edge e = find_fallthru_edge (gsi_bb (gsi)->succs);
                        gsi_insert_on_edge_immediate (e, g);
                      }
                    else
                      gsi_insert_after (&gsi, g, GSI_SAME_STMT);
                    gimple_set_lhs (stmt, lhs2);

(gdb) p print_generic_expr (stderr, lhs, 0)
_1$3 = void
(gdb) p print_generic_expr (stderr, lhs2, 0)
_12$4 = void
(gdb) p print_gimple_stmt (stderr, stmt, 0, 0)
_1 = x_4(D) * 5;
$5 = void
(gdb) p print_gimple_stmt (stderr, g, 0, 0)
_1 = (_BitInt(128)) _12;
$6 = void

So we have 
_1 = x_4(D) * 5;
then we create 
_1 = (_BitInt(128)) _12;
And add it to the IL...  and finally change the original stmt to 
_12 = x_4(D) * 5

how is that right?  _1 is now a different type?  but regardless, we have 2
statements with _1 as a LHS for a brief time.

And rangers real complaint is that we have a range for _1, but its being
updated by a stmt which is not actually in the IL yet during this update.. so
it is finding no basic block info for an SSA name which is thinks its knows
something about already because it WAS in the IL.

It also does not seem correct to me that you can take an existing SSA_NAME and
change its type on the fly while its still being used in the IL?   Once we
create an ssa name, I thought it was immutable from a type point of view untl
deleted and reused?

(gdb) p print_generic_expr (stderr, lhs->typed.type, 0)
_BitInt(128)$7 = void
(gdb) p print_generic_expr (stderr, lhs2->typed.type, 0)
int128_t$8 = void

Reply via email to