On May 25, 2018 7:31:43 PM GMT+02:00, Martin Sebor <mse...@gmail.com> wrote: >On 05/25/2018 01:02 AM, Richard Biener wrote: >> On Thu, May 24, 2018 at 11:22 PM Martin Sebor <mse...@gmail.com> >wrote: >> >>> On 05/24/2018 11:15 AM, Richard Biener wrote: >>>> On May 24, 2018 7:02:17 PM GMT+02:00, Martin Sebor ><mse...@gmail.com> >> wrote: >>>>> On 05/24/2018 03:39 AM, Richard Biener wrote: >>>>>> On Thu, May 24, 2018 at 12:50 AM Martin Sebor <mse...@gmail.com> >>>>> wrote: >>>>>> >>>>>>> The attached patch enhances the get_size_range() function to >>>>>>> extract more accurate ranges out of MIN_EXPR and MAX_EXPR nodes >>>>>>> with SSA_NAME operand(s). This helps -Wstringop-overflow avoid >>>>>>> false positives on some targets in cases like some of those >>>>>>> reported in bug 85623 - strncmp() warns about attribute >nonstring >>>>>>> incorrectly in -Wstringop-overflow >>>>>> >>>>>>> When first trying to expand calls to __builtin_strncmp, most >back >>>>>>> ends succeed even when the expansion results in a call to the >>>>> library >>>>>>> function. The powerpc64 back-end, however, fails and and allows >>>>>>> the generic expansion to take place. There is a subtle >difference >>>>>>> between the two cases that shows up when examining the bound of >>>>>>> the strncmp call expression (the third argument): in the >original >>>>>>> call expression (in expand_builtin_strncmp) the bound is or can >be >>>>>>> an SSA_NAME. But when the early expansion fails, >>>>>>> expand_builtin_strncmp transforms the original call expression >into >>>>>>> a new one, substituting MIN_EXPR (bound, CST) for the bound >where >>>>>>> CST is the constant result of strlen (STR), with STR being >either >>>>>>> the first or second strncmp argument. When the bound is an >SSA_NAME >>>>>>> the subsequent attempt to determine its range from the MIN_EXPR >>>>> fails. >>>>>> >>>>>> Hmm, wouldn't sth extracted from the attached random patch I have >>>>> lying >>>>>> around be more useful in general? That is, refactor the GENERIC >>>>>> expression walk in determine_value_range_1 to sth that can be >used >>>>>> in the current get_range_info () interface? Or if we don't want >to >>>>> change >>>>>> that to accept non-SSA names add a corresponding >get_expr_range_info >>>>> () >>>>>> interface. >>>>> >>>>> Thanks. It is certainly more general. I'm just not sure how much >>>>> use the generality can be put to because... >>>>> >>>>>> If you do that please cut out the dominator/loop condition >handling >>>>> and >>>>>> refrain from the idea of looking at SSA def stmts. >>>>> >>>>> ...I've done that but I'm having trouble exercising the code >except >>>>> for this bug. (I've run the C testsuite but the only tests that >end >>>>> up in it call it with uninteresting arguments like VAR_DECL). Do >>>>> you have any suggestions? >>>> >>>> Well, what builds the MIN_EXPR for your testcase? I orinigally used >it >> for niters analysis which deals with complex GENERIC expressions. If >you >> just changed get_range_info then of course callers are guarded with >SSA >> name checks. >> >>> In pr85888 it's built by expand_builtin_strncmp (so very late). >>> It doesn't seem like a good use case because of this code: >> >>> /* Expand the library call ourselves using a stabilized argument >>> list to avoid re-evaluating the function's arguments twice. >*/ >>> tree fn = build_call_nofold_loc (loc, fndecl, 3, arg1, arg2, >len); >>> gcc_assert (TREE_CODE (fn) == CALL_EXPR); >>> CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp); >>> return expand_call (fn, target, target == const0_rtx); >> >>> AFAICS, the new call expression is the same as the old one, the only >>> difference is the LEN argument which is the MIN_EXPR. >> >>> The code was added in r72380 where the stabilization referred to >>> calling save_expr() on the arguments. That code has been gone >>> since r242556 so I think a better/more targeted solution to fix >>> pr85888 than either of our approaches might be to simply call >>> expand_call() on the original CALL_EXPR with the original >>> arguments, including ARG3. >> >>> I don't fully understand the point of the save_expr() calls there >>> (and they're still in builtin_expand_strcmp), so if they need to >>> be restored then they would presumably include ARG3. I.e., >>> expand_call() would be called using ARG3 in the original SSA_NAME >>> form rather than the MIN_EXPR wrapper created by the function. >> >>> Attached is a patch that implements the first approach above. >> >>> If the SAVE_EXPRs are needed for some reason, it would be good >>> to have a test case to verify it. I haven't been able to come >>> up with one (or find an existing test that fails due to their >>> removal) but that could very well be because my limited >>> understanding of what they're for (and poor testsuite coverage). >> >>> I'm also up for taking your patch and trying to make use of it >>> for other trees where get_range_info() is currently being called >>> for SSA_NAMEs only. But it feels like a separate project from >>> this bug fix. >> >> But your patch makes the whole 'len' computation after >> >> /* If we don't have a constant length for the first, use the >length >> of the second, if we know it. If neither string is constant >length, >> use the given length argument. We don't require a constant for >> this case; some cost analysis could be done if both are >available >> but neither is constant. For now, assume they're equally >cheap, >> unless one has side effects. If both strings have constant >lengths, >> use the smaller. */ >> >> if (!len1 && !len2) >> len = len3; >> else if (!len1) >> ... >> /* If we are not using the given length, we must incorporate it >here. >> The actual new length parameter will be MIN(len,arg3) in this >case. */ >> if (len != len3) >> len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, >len3); >> >> dead if expand_cmpstrn_or_cmpmem doesn't expand things inline. >> I believe the idea is to possibly reduce 'len' for expansion of the >> libcall. >> >> OTOH all this "optimization" should have been done as folding >> and not at RTL expansion time. Thus if the issue is getting >> a warning from the recursive re-expansion of the adjusted >> call then removing this "postmature" optimization and making >> sure it happens earlier as folding might be indeed a good thing. >> >> But your patch as-is looks like it loses some optimization >> (and I'm not caring about "folding" at -O0). > >On the one affected target (as far as I know) it increases >the code size by adding a branch. I wouldn't have thought >of that as an optimization. Since it bloats code, at >a minimum I'd expect the decision to be gated for -Os. But >I'm not sure the branch is necessarily a win either -- it >will certainly depend on whether strncpy makes use of it. > >At the same time, if you believe this code is deliberately >crafted this way I wouldn't want to undo it just to suppress >a warning. So I'm back to the question: is my first patch >good enough for now to suppress the warning or do you want >me to use your patch?
I don't like to have random pieces of range propagation code spread throughout the compiler so no, your first patch isn't OK. A variant using a new get_expr_range_info is preferred. Richard. >I don't have a problem using yours but in the first pass >I wouldn't want to do more than just fix the warning; with >it fixed, I could the look into removing some of the guards >for SSA_NAME around calls to get_range_info(). > >Martin > >> Richard. >> >>> Martin >> >>>> >>>>> Martin >>>>> >>>>> PS I was able to create a test that at -O0 could call it with >>>>> a more interesting argument such as: >>>>> >>>>> const __SIZE_TYPE__ i = 3, j = 5; >>>>> >>>>> int f (void) >>>>> { >>>>> return __builtin_strncmp ("1234", "123", i < j ? i : j); >>>>> } >>>>> >>>>> Here, the first call to gimple_fold_builtin_string_compare() that >>>>> I picked as a test case sees: >>>>> >>>>> j.0_1 = 5; >>>>> i.1_2 = 3; >>>>> _3 = MIN_EXPR <j.0_1, i.1_2>; >>>>> D.1963 = __builtin_strncmp ("1234", "123", _3); >>>>> >>>>> Above, _3's range info is not available yet at this point so >>>>> the expression could be evaluated but only by looking at def >stmts. >>>>> Why is it not a good idea? >>>> >>>> Because it raises complexity concerns unless you also populate >> intermediate SSA range Infos and stop at present ones. And you can't >deal >> with conditional info as the patch tries to do (but I wouldn't keep >that >> either initially). >>>> >>>> Richard. >>>> >>>>> >>>>> Martin >>>>