public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* DIV in inline assembly: volatile needed due to "divide error" side effect?
@ 2021-08-29  1:32 Jeremy Sawicki
  2021-08-29  8:11 ` Alexander Monakov
  0 siblings, 1 reply; 2+ messages in thread
From: Jeremy Sawicki @ 2021-08-29  1:32 UTC (permalink / raw)
  To: gcc-help

I am attempting to access the x86_64 DIV instruction from inline
assembly as follows:

inline void div128(uint64_t* q, uint64_t *r,
                    uint64_t n1, uint64_t n0, uint64_t d)
{
     __asm__("divq %4"
             : "=a" (*q), "=d" (*r)
             : "1" (n1), "0" (n0), "rm" (d)
             : "cc");
}

I declare input and output operands, but is that sufficient? The DIV
instruction can produce a divide error for certain inputs.  The GCC
documentation says that inline assembly may be discarded or moved out
of loops.  Can it also be speculatively executed?  I have a case in
GCC 11.2 where a single DIV is duplicated and executed on two different
inputs coming from two sides of a conditional.  One of the inputs (the
one not chosen by the conditional) produces a divide error.

Is my code at fault?  Do I need the volatile qualifier?  Or is GCC not
supposed to speculatively execute inline assembly?

Here is a reproducible case: https://godbolt.org/z/37z3foTff

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: DIV in inline assembly: volatile needed due to "divide error" side effect?
  2021-08-29  1:32 DIV in inline assembly: volatile needed due to "divide error" side effect? Jeremy Sawicki
@ 2021-08-29  8:11 ` Alexander Monakov
  0 siblings, 0 replies; 2+ messages in thread
From: Alexander Monakov @ 2021-08-29  8:11 UTC (permalink / raw)
  To: Jeremy Sawicki; +Cc: gcc-help

On Sat, 28 Aug 2021, Jeremy Sawicki wrote:

> I am attempting to access the x86_64 DIV instruction from inline
> assembly as follows:
> 
> inline void div128(uint64_t* q, uint64_t *r,
>                    uint64_t n1, uint64_t n0, uint64_t d)
> {
>     __asm__("divq %4"
>             : "=a" (*q), "=d" (*r)
>             : "1" (n1), "0" (n0), "rm" (d)
>             : "cc");
> }
> 
> I declare input and output operands, but is that sufficient? The DIV
> instruction can produce a divide error for certain inputs.  The GCC
> documentation says that inline assembly may be discarded or moved out
> of loops.  Can it also be speculatively executed?  I have a case in
> GCC 11.2 where a single DIV is duplicated and executed on two different
> inputs coming from two sides of a conditional.  One of the inputs (the
> one not chosen by the conditional) produces a divide error.
> 
> Is my code at fault?  Do I need the volatile qualifier?  Or is GCC not
> supposed to speculatively execute inline assembly?

Since your code takes care to invoke 'div128' only with safe inputs, it's
fine. GCC has no way to distinguish potentially-trapping asm statements,
so to be conservatively correct it may not move them speculatively.

Can you file your testcase in the Bugzilla? It might be a good idea to
reference these existing bug reports:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82677
(general discussion of the issue you're facing)

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93491
(not your issue, but related in the sense that pure/const functions
need to be non-trapping only for the inputs they receive in the abstract
machine -- same applies to inline asms)

Alexander

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-08-29  8:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-29  1:32 DIV in inline assembly: volatile needed due to "divide error" side effect? Jeremy Sawicki
2021-08-29  8:11 ` Alexander Monakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).