https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112843
--- Comment #7 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Jakub Jelinek from comment #6) > (In reply to Andrew Macleod from comment #5) > > what do you mean? when a statement is changed, it may generate a different > > range than it did before, > > No, that would be a bug. If some IL changes need to extend existing range, > then > reset_flow_sensitive_info needs to be called for the SSA_NAME. Not from rangers point of view. You may change _1 = _2 + 5 to _1 = _6 + 5 and it finds it has a better understanding of the range of _6, and so it can further refine the range for _1 based on that. So it merely checks to see if the changes to the statement means it can understand it better. In particular: const char *lossage = _result ? "constant string" : 0; if (__builtin_expect (lossage != ((void *)0) , 0)) { unsigned __message_length = __builtin_strlen (lossage); if (! __builtin_constant_p (__message_length)) dead (); } This provides an IL update which happens later in compilation when builtin_expect gives us a rbetter result which gives us a much better range and can then fold away the call to dead() > > > 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, > > But unfortunately that is pretty much unavoidable in changes like this. > So, I have > lhs1 = some_stmt; > and want to change it to > lhs2 = some_stmt; > lhs1 = (lhs_type) lhs2; > (where lhs2 has a different type from lhs). > The options to do that are either what the code does right now, i.e. > first create lhs1 = (lhs_type) lhs2; stmt, add it after lhs1 = some_stmt; > (including update_stmt), then gimple_set_lhs on the first stmt to lhs2, then > update_stmt on the first stmt, but this is temporarily invalid IL, because > two different stmts in the IL have the same lhs, or as changed in the patch > gimple_set_lhs on the first stmt to lhs2 (but no update_stmt), create the > second stmt, add it including update_stmt, then update_stmt on the first > one; this is also invalid IL, the effects of update_stmt haven't been done > until the second update_stmt; or gimple_set_lhs and update_stmt on the first > one (but then lhs1 has no definition and we insert a stmt into the IL > without the definition, so again temporarily invalid IL). Im still confused tho. So what I think you are doing is taking lhs1 = some_stmt and rewriting it to a different type, and it looks like looping thru the operands so that some_stmt is consuming the right types too.. so the type of some_stmt is changing from lhs1_type to lhs2_type. adn then we create a new stmt for lhs1. to avoid lying why dont we just create a new stmt 'g' before stmt lhs2 = some_stmt with the operands converted and then when that is done, simply update stmt lhs1 = (lhs1_type) lhs2 the the IL is never in an invalid state? Otherwise if we are going to have invalid IL states, we have to turn off any automatic updating... you could possible just save all the update/sets until the end.. that might work. The biggest issue would be that lhs1 was in the IL so ranger expects the block to be set for its def stmt and it is being added via a new stmt whic is not in the IL yet when the update happens... its expects gimple_bb to be set for a DEF that it has seen. Isn't the "normal" way to do this to leave lhs1 = some_stmt and then add lhs2 = (lhs2_type) lhs1 and follow immeidate uses and change all the occurences of lhs1 to lhs2?