[PATCH 1/3] [builtins] Generic support for __builtin_load_no_speculate()

Richard Earnshaw (lists) Richard.Earnshaw@arm.com
Fri Jan 12 16:16:00 GMT 2018


On 10/01/18 23:26, Jeff Law wrote:
> On 01/08/2018 09:01 AM, Bill Schmidt wrote:
>> On Jan 8, 2018, at 8:06 AM, Richard Earnshaw (lists) <Richard.Earnshaw@arm.com> wrote:
>>>
>>> On 08/01/18 02:20, Bill Schmidt wrote:
>>>> Hi Richard,
>>>>
>>>> Unfortunately, I don't see any way that this will be useful for the ppc targets.  We don't
>>>> have a way to force resolution of a condition prior to continuing speculation, so this
>>>> will just introduce another comparison that we would speculate past.  For our mitigation
>>>> we will have to introduce an instruction that halts all speculation at that point, and place
>>>> it in front of all dangerous loads.  I wish it were otherwise.
>>>
>>> So can't you make the builtin expand to (in pseudo code):
>>>
>>> 	if (bounds_check)
>>> 	  {
>>> 	    __asm ("barrier");
>>> 	    result = *ptr;
>>>          }
>>>        else
>>> 	  result = failval;
>>
>> Could, but this just generates unnecessary code for Power.  We would instead generate
>>
>> 	__asm ("barrier");
>> 	result = *ptr;
>>
>> without any checks.  We would ignore everything but the first argument.
> So how bad would it be to drop the whole concept of failval and make the
> result indeterminate in the out of bounds case.
> 

Indeterminate on its own is too loose.  An arbitrary value fetched from
memory is 'indeterminate', so we'd need tighter wording that that, see
below.

> 
> Would that give us enough freedom to generate an appropriate sequence
> for aarch64 and ppc?  It feels like these two architectures are
> essentially on opposite sides of the spectrum and if we can find a
> reasonable way to handle them that we'd likely have semantics we can use
> on just about any architecture.
> 
> 
> jeff
> 

So if we changed the specification (using the same parameter names) to:

1) When the call to the builtin is not being speculatively executed the
   result is *ptr if lower_bound <= cmpptr < upper_bound and undefined
   otherwise.
2) When code is being speculatively executed either:
   a) execution of subsequent instructions that depend on the result
      will be prevented until it can be proven that the call to the
      builtin is not being speculatively executed (ie until execution
      can continue under point 1), or
   b) speculation may continue using *ptr as the result when
      lower_bound <= cmpptr < upper_bound, or an unspecified constant
      value (eg 0) if cmpptr lies outside that range.

Then I think that meets those requirements.

We could still implement the existing relaxations on permitting the
builtin to be called with only one of upper and lower.

My concern is that this would make it quite hard for programmers to
reason safely about the behaviour overall.

R.



More information about the Gcc-patches mailing list