On Wed, Nov 6, 2013 at 3:04 PM, Ilya Enkovich <enkovich....@gmail.com> wrote: > 2013/11/6 Richard Biener <richard.guent...@gmail.com>: >> On Wed, Nov 6, 2013 at 2:31 PM, Ilya Enkovich <enkovich....@gmail.com> wrote: >>> 2013/11/6 Richard Biener <richard.guent...@gmail.com>: >>>> On Wed, Nov 6, 2013 at 12:59 PM, Ilya Enkovich <enkovich....@gmail.com> >>>> wrote: >>>>> 2013/11/6 Richard Biener <richard.guent...@gmail.com>: >>>>>> On Wed, Nov 6, 2013 at 12:00 PM, Ilya Enkovich <enkovich....@gmail.com> >>>>>> wrote: >>>>>>> 2013/11/6 Richard Biener <richard.guent...@gmail.com>: >>>>>>>> On Tue, Nov 5, 2013 at 3:24 PM, Ilya Enkovich <enkovich....@gmail.com> >>>>>>>> wrote: >>>>>>>>> 2013/11/5 Richard Biener <richard.guent...@gmail.com>: >>>>>>>>>> On Tue, Nov 5, 2013 at 1:52 PM, Ilya Enkovich >>>>>>>>>> <enkovich....@gmail.com> wrote: >>>>>>>>>>> >>>>>>>>>>> For input parameter P I need to have >>>>>>>>>>> BOUNDS = __builtin_arg_bnd (P) >>>>>>>>>>> to somehow refer to bounds of P in GIMPLE. Optimizations may modify >>>>>>>>>>> __builtin_arg_bnd (P) replacing P with its copy or some value. It >>>>>>>>>>> makes call useless because removes information about parameter whose >>>>>>>>>>> bounds we refer to. I want such optimization to ignore >>>>>>>>>>> __builtin_arg_bnd calls and always leave default SSA_NAME of >>>>>>>>>>> PARM_DECL >>>>>>>>>>> there as arg. >>>>>>>>>> >>>>>>>>>> How does a compilable testcase look like that shows how the default >>>>>>>>>> def >>>>>>>>>> is used? And what transforms break that use? I really cannot see >>>>>>>>>> how this would happen (and you didn't add a testcase). >>>>>>>>> >>>>>>>>> Here is a test source: >>>>>>>>> >>>>>>>>> extern int bar1 (int *p); >>>>>>>>> extern int bar2 (int); >>>>>>>>> >>>>>>>>> int foo (int *p) >>>>>>>>> { >>>>>>>>> if (!p) >>>>>>>>> return bar1 (p); >>>>>>>>> return bar2 (10); >>>>>>>>> } >>>>>>>>> >>>>>>>>> After instrumentation GIMPLE looks like: >>>>>>>>> >>>>>>>>> foo (int * p) >>>>>>>>> { >>>>>>>>> <unnamed type> __bound_tmp.0; >>>>>>>>> int _1; >>>>>>>>> int _6; >>>>>>>>> int _8; >>>>>>>>> >>>>>>>>> <bb 6>: >>>>>>>>> __bound_tmp.0_9 = __builtin_ia32_arg_bnd (p_3(D)); >>>>>>>>> >>>>>>>>> <bb 2>: >>>>>>>>> if (p_3(D) == 0B) >>>>>>>>> goto <bb 3>; >>>>>>>>> else >>>>>>>>> goto <bb 4>; >>>>>>>>> >>>>>>>>> <bb 3>: >>>>>>>>> _6 = bar1 (p_3(D), __bound_tmp.0_9); >>>>>>>>> goto <bb 5>; >>>>>>>>> >>>>>>>>> <bb 4>: >>>>>>>>> _8 = bar2 (10); >>>>>>>>> >>>>>>>>> <bb 5>: >>>>>>>>> # _1 = PHI <_6(3), _8(4)> >>>>>>>>> return _1; >>>>>>>>> >>>>>>>>> } >>>>>>>>> >>>>>>>>> Here is optimized GIMPLE (if I do not apply my changes in >>>>>>>>> tree-ssa-dom.c): >>>>>>>>> >>>>>>>>> foo (int * p) >>>>>>>>> { >>>>>>>>> <unnamed type> __bound_tmp.0; >>>>>>>>> int _1; >>>>>>>>> int _6; >>>>>>>>> int _8; >>>>>>>>> >>>>>>>>> <bb 2>: >>>>>>>>> if (p_3(D) == 0B) >>>>>>>>> goto <bb 3>; >>>>>>>>> else >>>>>>>>> goto <bb 4>; >>>>>>>>> >>>>>>>>> <bb 3>: >>>>>>>>> __bound_tmp.0_9 = __builtin_ia32_arg_bnd (0B); [return slot >>>>>>>>> optimization] >>>>>>>>> _6 = bar1 (0B, __bound_tmp.0_9); [tail call] >>>>>>>>> goto <bb 5>; >>>>>>>>> >>>>>>>>> <bb 4>: >>>>>>>>> _8 = bar2 (10); [tail call] >>>>>>>>> >>>>>>>>> <bb 5>: >>>>>>>>> # _1 = PHI <_6(3), _8(4)> >>>>>>>>> return _1; >>>>>>>>> >>>>>>>>> } >>>>>>>>> >>>>>>>>> Now during expand or inline of foo I cannot determine the value for >>>>>>>>> __bound_tmp.0_9. >>>>>>>> >>>>>>>> Well, but clearly you can see that bounds for p == NULL are >>>>>>>> useless and thus there is no problem with the transform. >>>>>>> >>>>>>> This example just demonstrates the issue. I may use some var's address >>>>>>> in comparison with the similar result. And value does not always allow >>>>>>> to determine bounds, because pointers with the same value may have >>>>>>> different bounds. >>>>>> >>>>>> Some vars address can be used for better bounds deriving though. >>>>>> Well, it clearly shows it's a "get me good results" issue and not >>>>>> a correctness issue. And for "good results" you trade in missed >>>>>> general optimizations. That doesn't sound very good to me. >>>>> >>>>> That is definitely a correctness issue. >>>> >>>> Then please add a runtime testcase that fails before and passes after >>>> your patch. >>>> >>>>> Compiler cannot assume bounds >>>>> by pointer value ignoring bounds passed to the function. >>>> >>>> But it can certainly drop bounds to "unknown"? You certainly cannot >>>> rely on no such transform taking place. Maybe this just shows that >>>> your "refering to the parameter" is done wrong and shouldn't have >>>> used the SSA name default def. What do you do for parameters >>>> that have their address taken btw? You'll get >>>> >>>> foo (void *p) >>>> { >>>> p_2 = *p; >>>> __builtin_ia32_arg_bnd (p_2); >>>> >>>> which isn't desired? >>> >>> In this case you just make a load and bounds for p_2 are obtained >>> using bndldx call. I would be glad to use better way to refer to the >>> argument but I do not see one. >> >> Err, my mistake - I meant >> >> foo (void *p) >> { >> p_2 = p; >> __builtin_ia32_arg_bnd (p_2); > > Well, it does not make much difference. Such params are allocated on > the stack by expand. So, here p_2 = p is load from memory and bounds > should be loaded by bndldx. Expand is responsible to store bounds > using bndstx when it allocates p on the stack.
The parameter is incoming in a register still. >> >>>> >>>> Hmm, unfortunately on x86_64 I get >>>> >>>> ./cc1 -quiet t.c -fcheck-pointer-bounds >>>> t.c:1:0: error: -fcheck-pointers is not supported for this target >>>> extern int bar1 (int *p); >>>> ^ >>>> >>>> trying a simple testcase. Grepping shows me no target supports >>>> chkp_bound_mode ..? What's this stuff in our tree that has no way >>>> of testing it ... :/ >>> >>> You should pass -mmpx to enable it on the target. Current version in >>> the mpx tree should build most of tests correctly but it is not >>> updated to the current state. >> >>> ./cc1 -quiet t.c -fcheck-pointer-bounds -mmpx >> t.c:1:0: error: -fcheck-pointers is not supported for this target >> extern int bar1 (int *p); >> ^ >> >> hmm, maybe it's configure disabled somehow (this is just my dev tree). >> But I still see no chkp_bound_mode implementation. > > I'll check it and probably update the branch. I'm looking at trunk which has loads of this stuff already. >> >> Note that POINTER_BOUNDS_TYPE shouldn't have been a new >> tree code either but should be a RECORD_TYPE. See how >> va_list doesn't use a new TREE_CODE either. > > va_list is either a pointer or pointer to a record (array of one > record) and is handled as a regular pointer to a regular record. > Bounds are not a record of two pointers at least due to binary format. > You do not pass it as regular record, use special bound mode for whole > record. Why to use RECORD_TYPE for bounds if it'll never be handled as > regular RECORD_TYPE? Then you only can update it completely? Seems awfully target specific for sth introduced at the GIMPLE level. Oh well. Richard. > Ilya > >> >> Richard. >> >>> Ilya >>> >>>> >>>> Richard. >>>> >>>>> SSA_NAME_OCCURS_IN_ABNORMAL_PHI usage results in missed optimizations. >>>>> My original patch does not. >>>>> >>>>> Ilya >>>>> >>>>>> >>>>>> Richard. >>>>>> >>>>>>>> >>>>>>>> Also sth weird is going on as your arg_bnd call gets [return slot >>>>>>>> optimization]. >>>>>>>> It seems that your POINTER_BOUNDS_TYPE is seen as aggregate somehow. >>>>>>> >>>>>>> Target is responsible for having return slot optimization here. And >>>>>>> target expands all such calls. So, do not see the problem here. >>>>>>> >>>>>>> Ilya >>>>>>> >>>>>>>> >>>>>>>> Richard. >>>>>>>> >>>>>>>>> Ilya >>>>>>>>>> >>>>>>>>>> Richard. >>>>>>>>>>