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.

>
>>>
>>> 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.

>
> 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?

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.
>>>>>>>>>

Reply via email to