On Thu, Apr 28, 2022 at 8:43 PM Jeff Law <jeffreya...@gmail.com> wrote: > > > > On 4/28/2022 10:30 AM, Aldy Hernandez wrote: > > [Jeff, this is the same patch I sent you last week with minor tweaks > > to the commit message.] > And I just dropped it into the tester. We should have the vast majority > of targets tested by this time tomorrow. > > > > > [Despite the verbosity of the message, this is actually a pretty > > straightforward patch. It should've gone in last cycle, but there > > was a nagging regression I couldn't get to until after stage1 > > had closed.] > You had other, non-work/gcc priorities. No worries at missing gcc-12.
Ha. I keep forgetting I have a permanent excuse going forward for any delays... parenthood! > > > > > > There are 3 uses of EVRP in DOM that must be converted. > > Unfortunately, they need to be converted in one go, so further > > splitting of this patch would be problematic. > ACK > > > > There's nothing here earth shattering. It's all pretty obvious in > > retrospect, but I've added a short description of each use to aid in > > reviewing: > > > > * Convert evrp use in cprop to ranger. > > > > This is easy, as cprop in DOM was converted to the ranger API last > > cycle, so this is just a matter of using a ranger instead of an > > evrp_range_analyzer. > Yea. We may have covered this before, but what does ranger do with a > conditional equivalence? > > ie if we have something like > > if (a == b) > { > blah blah > } > > Within the true arm we know there's an equivalence. *But* we don't want > to just blindly replace a with b or vice-versa. The equivalence is > primarily useful for simplification rather than propagation. > > In fact, we every much do not want to cprop in these cases. It rarely > helps in a meaningful way and there's no good way to know which is the > better value to use. Canonicalization on SSA_NAMEs doesn't really help > due to SSA_NAME recycling. Ranger only returns constants, not symbolics, so the call to range_of_expr is guaranteed to be constant. I verified that this subtle change to range_of_expr didn't cause any problems in my conversion to the value_query API in commit e1d01f4973 (last cyce): There is one subtle change. The call to vr_value's op_with_constant_singleton_value_range can theoretically return non-constants, unlike the range_query API which only returns constants. In this particular case it doesn't matter because the symbolic stuff will have been handled by the const_and_copies/avail_exprs read in the SSA_NAME_VALUE copy immediately before. I have verified this is the case by asserting that all calls to op_with_constant_singleton_value_range at this point return either NULL or an INTEGER_CST. Just to be clear, even though ranger doesn't return a symbolic, it does know about relations via the relation oracle the ranger uses. So on the TRUE arm, it will know that a==b, which it can leverage to fold any statements. This could be done with the statement folding API in gimple-range-fold.h (or via range_of_stmt). You could theoretically query the relation oracle yourself with query_relation() which are exported by the ranger (via the range_query class it inherits from). But for the case above, we're calling range_of_expr which is guaranteed to be a constant. Since we're calling range_of_expr on operands, we shouldn't be folding anything. OTOH, if you were to call range_of_stmt on the conditional, it could return TRUE/FALSE based on how it would fold. In dom_opt_dom_walker::fold_cond() which I have provided in the patch, we will fold conditionals with knowledge of relations, because it uses range_of_stmt. BTW, when frange and prange come live, there will be other attributes that may be attached to a range. For instance for prange, we'll have a "points-to" attribute. For example: p_5 = &foo; The range of p_5 will be nonzero with a points-to attribute of &foo + 0 or some such. So later this cycle we'll have symbolics of sorts, but never in the range itself, but as an attribute say prange::get_points_to(). Similarly for floats. We'll probably have not-NAN, not-INF, etc attributes. > > > > > > * Convert evrp use in threader to ranger. > > > > The idea here is to use the hybrid approach we used for the initial > > VRP threader conversion last cycle. The DOM threader will continue > > using the forward threader infrastructure while continuing to query > > DOM data structures, and only if the conditional does not relsolve, > > using the ranger. This gives us the best of both worlds, and is a > > proven approach. > > > > Furthermore, as frange and prange come live in the next cycle, we > > can move away from the forward threader altogether, and just add > > another backward threader. This will not only remove the last use > > of the forward threader, but will allow us to remove at least 1 or 2 > > threader instances. > Excellent. > > > > > * Convert conditional folding to use the method used by the ranger and > > evrp. Previously DOM was calling into the guts of > > simplify_using_ranges::vrp_visit_cond_stmt. The blessed way now is > > using fold_cond() which rewrites the conditional and edges > > automatically. > > > > When legacy is removed, simplify_using_ranges will be further > > cleaned up, and there will only be one entry point into simplifying > > a statement. > Sure. > > > > > * DOM was setting global ranges determined from unreachable edges as a > > side-effect of using the evrp engine. We must handle these cases > > before nuking evrp, and DOM seems like a good fit. I've just moved > > the snippet to DOM, but it could live anywhere else we do a DOM > > walk. > It was a semi-desirable to record/refine global ranges in DOM, but I'd > be surprised if too much code depended on that. Presumably there's a > testcase in the suite which we don't handle well if we don't let DOM > refine/record global ranges? > > > > > For the record, this is the case *vrp handled: > > > > <bb C>: > > ... > > if (c_5(D) != 5) > > goto <bb N>; > > else > > goto <bb M>; > > <bb N>: > > __builtin_unreachable (); > > <bb M>: > > > > If M dominates all uses of c_5, we can set the global range of c_5 > > to [5,5]. > And that will only happen if M eventually loops back to the conditional, > right? Otherwise all the uses wouldn't be dominated. I suspect this is > exceedingly rare in practice an it looks really familiar. This is > coming from a testcase, right? > > This is the only part of the patch that makes me go "ewwww", so I would > like to at least explore if we can rethink the value of that test. [the above is discussed down thread] > > > There is a a regression on Wstringop-overflow-4.C which I'm planning > > on XFAILing. It's another variant of the usual middle-end false > > positives: having no ranges produces no warnings, but slightly refined > > ranges, or worse-- isolating specific problematic cases in the > > threader causes flare-ups. > ACK. > > > > > > As an aside, as Richi has suggested, I think we should discuss > > restricting the threader's ability to thread highly unlikely paths. > > These cause no end of pain for middle-end warnings. However, > > I don't know if this would conflict with path isolation for > > things like null dereferencing. ISTR you were interested in this. > I've never though too much about it. You're thinking of Richi :-) > > It's a balance. I bet if we stop threading those paths we're going to > see other issues start popping up like uninitialized warnings. > > It may be the case that it's really the constant propagation on an > isolated path that's more problematical for those warnings. But I would > probably contend that what isolation is doing is showing how certain > constant values can flow into places where they're not expected and > could cause problems. So I wouldn't necessary suggest throttling it. > > Happy to be proven wrong here! > > > > > > BTW, I think the Wstringop-overflow-4.C test is problematic and I've > > attached my analysis. Basically the regression is caused by a bad > > interaction with the rounding/alignment that placement new has inlined > > into the IL. This happens for int16_r[] which the test is testing. > > Ranger can glean some range info, which causes DOM threading to > > isolate a path which causes a warning. > Presumably this is triggering a warning at the new() call? Yes. Aldy