[Bug inline-asm/49611] Inline asm should support input/output of flags

2018-06-01 Thread ubizjak at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

Uroš Bizjak  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED

--- Comment #18 from Uroš Bizjak  ---
(In reply to David from comment #16)

> Still, if I were Richard, I'd be closing this bug.  If someone has
> optimization issues with his solution, that's a new bug.

This was implemented some time ago.

[Bug inline-asm/49611] Inline asm should support input/output of flags

2015-07-20 Thread gccbugzilla at limegreensocks dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #16 from David gccbugzilla at limegreensocks dot com ---
I've tried it now and it seems to do good things.  This code:

int main(int argc, char *argv[])
{
   char x;

   asm(setc : =@ccc(x));

   if (!x)
  return 6;
   else
  return argc;
}

produces this output (-O3):

movl$6, %eax
/APP
 # 6 ./r.cpp 1
setc
 # 0  2
/NO_APP
cmovc   %ebx, %eax
addq$32, %rsp
popq%rbx
ret

Although a minor variation (change return argc to return 7) ends up doing
setc+cmpb, so it's not a perfect solution.

Still, if I were Richard, I'd be closing this bug.  If someone has optimization
issues with his solution, that's a new bug.


[Bug inline-asm/49611] Inline asm should support input/output of flags

2015-07-20 Thread gcc.hall at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #17 from Jeremy gcc.hall at gmail dot com ---
Did you mean stc rather than setc ???

But yes, it looks like its working well.

On 20 July 2015 at 10:05, gccbugzilla at limegreensocks dot com 
gcc-bugzi...@gcc.gnu.org wrote:

 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

 --- Comment #16 from David gccbugzilla at limegreensocks dot com ---
 I've tried it now and it seems to do good things.  This code:

 int main(int argc, char *argv[])
 {
char x;

asm(setc : =@ccc(x));

if (!x)
   return 6;
else
   return argc;
 }

 produces this output (-O3):

 movl$6, %eax
 /APP
  # 6 ./r.cpp 1
 setc
  # 0  2
 /NO_APP
 cmovc   %ebx, %eax
 addq$32, %rsp
 popq%rbx
 ret

 Although a minor variation (change return argc to return 7) ends up
 doing
 setc+cmpb, so it's not a perfect solution.

 Still, if I were Richard, I'd be closing this bug.  If someone has
 optimization
 issues with his solution, that's a new bug.

 --
 You are receiving this mail because:
 You are on the CC list for the bug.



[Bug inline-asm/49611] Inline asm should support input/output of flags

2015-07-19 Thread gcc.hall at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #15 from Jeremy gcc.hall at gmail dot com ---
Perhaps the optimizer can reduce seta; test; jnz to ja since the
compiler now knows the intention.  In which case this is a great solution.

On 17 July 2015 at 22:24, gccbugzilla at limegreensocks dot com 
gcc-bugzi...@gcc.gnu.org wrote:

 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

 --- Comment #14 from David gccbugzilla at limegreensocks dot com ---
 (In reply to Jeremy from comment #12)

  It probably does a setcc on x86 which doesn't really gain much

 I don't have a 6.0 build to test with yet, but I don't believe that's quite
 correct.  Looking at the testsuite that got checked in with it, we see
 both:

 asm-flag-2.c:
 /* { dg-final { scan-assembler seta } } */

 asm-flag-3.c:
 /* { dg-final { scan-assembler ja } } */

 --
 You are receiving this mail because:
 You are on the CC list for the bug.



[Bug inline-asm/49611] Inline asm should support input/output of flags

2015-07-17 Thread gcc.hall at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #12 from Jeremy gcc.hall at gmail dot com ---
Hi David,
That's very interesting.  Its not in gcc 5.2.0 released yesterday though.
It probably does a setcc on x86 which doesn't really gain much, but on ARM
it could be useful.
More useful (as of gcc 5.0) is the new __builtin_xxx_overflow which uses
the overflow flag directly.   So for int16_t  operands for example:
if(   __builtin_add_overflow( a, b, result)  )
 printf( overflow);
it would emit addw; jno.

Jeremy



On 17 July 2015 at 06:41, gccbugzilla at limegreensocks dot com 
gcc-bugzi...@gcc.gnu.org wrote:

 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

 --- Comment #11 from David gccbugzilla at limegreensocks dot com ---
 Apparently this feature has been checked in:
 https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#FlagOutputOperands

 --
 You are receiving this mail because:
 You are on the CC list for the bug.



[Bug inline-asm/49611] Inline asm should support input/output of flags

2015-07-17 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #13 from Andrew Pinski pinskia at gcc dot gnu.org ---
(In reply to Jeremy from comment #12)
 Hi David,
 That's very interesting.  Its not in gcc 5.2.0 released yesterday though.

That is because 5.2 is a patch release off of the 5 branch. It was added to gcc
6 and above. 

 It probably does a setcc on x86 which doesn't really gain much, but on ARM
 it could be useful.
 More useful (as of gcc 5.0) is the new __builtin_xxx_overflow which uses
 the overflow flag directly.   So for int16_t  operands for example:
 if(   __builtin_add_overflow( a, b, result)  )
  printf( overflow);
 it would emit addw; jno.
 
 Jeremy
 
 
 
 On 17 July 2015 at 06:41, gccbugzilla at limegreensocks dot com 
 gcc-bugzi...@gcc.gnu.org wrote:
 
  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611
 
  --- Comment #11 from David gccbugzilla at limegreensocks dot com ---
  Apparently this feature has been checked in:
  https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#FlagOutputOperands
 
  --
  You are receiving this mail because:
  You are on the CC list for the bug.
 


[Bug inline-asm/49611] Inline asm should support input/output of flags

2015-07-17 Thread gccbugzilla at limegreensocks dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #14 from David gccbugzilla at limegreensocks dot com ---
(In reply to Jeremy from comment #12)

 It probably does a setcc on x86 which doesn't really gain much

I don't have a 6.0 build to test with yet, but I don't believe that's quite
correct.  Looking at the testsuite that got checked in with it, we see both:

asm-flag-2.c:
/* { dg-final { scan-assembler seta } } */

asm-flag-3.c:
/* { dg-final { scan-assembler ja } } */


[Bug inline-asm/49611] Inline asm should support input/output of flags

2015-07-16 Thread gccbugzilla at limegreensocks dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #10 from David gccbugzilla at limegreensocks dot com ---
There was some discussion of this on the gcc mailing list.  Not sure what
became of it: https://gcc.gnu.org/ml/gcc/2015-05/msg6.html


[Bug inline-asm/49611] Inline asm should support input/output of flags

2015-07-16 Thread gccbugzilla at limegreensocks dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #11 from David gccbugzilla at limegreensocks dot com ---
Apparently this feature has been checked in:
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#FlagOutputOperands


[Bug inline-asm/49611] Inline asm should support input/output of flags

2014-06-02 Thread gcc.hall at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #8 from Jeremy gcc.hall at gmail dot com ---
Asm goto does not allow any outputs, which does limit its usefulness.


[Bug inline-asm/49611] Inline asm should support input/output of flags

2014-06-02 Thread scovich at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #9 from Ryan Johnson scovich at gmail dot com ---
(In reply to Andi Kleen from comment #7)
 You can do many of these things these days with asm goto, however it
 typically requires non-structured control flow (goto labels).
I filed this bug after determining that asm goto was unsuitable for this
purpose.

Goto labels are not a problem per se (actually kind of slick), but asm goto
requires all outputs to pass through memory and so is only good for control
flow (not computation plus exceptional case). It also requires the actual
branching and all attendant glue to happen in assembly. Both limitations
increase bulk and hamper the optimizer, and go against (what I thought was) the
intention that inline asm normally be used for very small snippets of code the
compiler can't handle. At some point you may as well just setcc and do a new
comparison/branch outside the asm block; less bug-prone and would probably
yield faster and cleaner code, too.


[Bug inline-asm/49611] Inline asm should support input/output of flags

2014-06-01 Thread andi-gcc at firstfloor dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

Andi Kleen andi-gcc at firstfloor dot org changed:

   What|Removed |Added

 CC||andi-gcc at firstfloor dot org

--- Comment #7 from Andi Kleen andi-gcc at firstfloor dot org ---
You can do many of these things these days with asm goto, however it typically
requires non-structured control flow (goto labels)

https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#GotoLabels


[Bug inline-asm/49611] Inline asm should support input/output of flags

2014-05-30 Thread gcc.hall at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

Jeremy gcc.hall at gmail dot com changed:

   What|Removed |Added

 CC||gcc.hall at gmail dot com

--- Comment #5 from Jeremy gcc.hall at gmail dot com ---
It may not be possible, but perhaps a simpler thing might be for
the asm() to notionally return a single boolean value which
reflects ONE flag only.

By default this could be the ZF flag (which is probably the most
useful).  It would not generate any extra code at all. Thus:

   if( asm( test %%eax,%%eax ))

would emit:

   test eax,eax
   jz

rather than the usual route involving setcc and a second test.

The actual flag notionally returned could be changed with an attribute:

  __attribute__ ((asm_return(cc_carry)))
  __attribute__ ((asm_return(cc_overflow)))
  __attribute__ ((asm_return(cc_zero)))
  __attribute__ ((asm_return(cc_sign)))
  __attribute__ ((asm_return(cc_parity)))

or shorter, for example:

  __attribute__ ((cc_carry))

The inverse condition is simply expressed with  !asm(...)

The new code would also allow:

  bool zero = asm( test %%eax,%%eax );

where the compiler would emit setz.
or

  x = asm( test %%eax,%%eax ) ? 10 : 20;

where the compiler might emit cmovz.

It would not break any existing code because nothing yet expects a return from
an asm,
neither would it preclude exporting all the flags with =cc in the future.

It would be a hard error if a flag is not supported by the current platform as
code cannnot be generated.
GCC does not examine the asm template string, if the flag is not set then the
result is UB, just like use of an undefined variable.

A final, more useful, example:

  // Implement left *= right reporting signed integer overflow
#define checked_multiply(left,right) \
__attribute__ ((asm_return(cc_overflow))) \
asm( imul %1,%0 : +r (left) : r (right) )

allowing an efficient implementation of:

   if( checked_multiply( a, b ) )
   {
  handle overflow
   }


Possible documentation follows... 

Return Value

If you are using the asm_return attribute, you are informing the compiler that
a comparison has already been done in your assembler code, and the flags have
been set appropriately.  The compiler can now use those flags to perform
conditional jumps, conditional assignments, etc.  Which conditional operator
should be used is determined by which value is specified to asm_return.  For
example on i386:

if( __attribute__(asm_return(cc_carry)) asm() )
  printf (Carry yes\n);
else
  printf (Carry no\n);

indicates that the asm template has set a value in the Carry flag, and GCC
should use the jc/jnc instructions to jump to the correct location. Similarly:

int a = __attribute__(asm_return(cc_zero)) asm() ?  23 : 42;

could use the i386 cmovz instruction to perform the assignment.  And

bool DidOverflow = __attribute__(asm_return(cc_overflow)) asm();

could use i386's seto.

Which flags (if any) are supported depend upon your platform (see Asm
Attributes). If no asm_return attribute is specified, it is an error to attempt
to use the return value from the asm.  It is acceptable for code to ignore the
returned flags.




[Bug inline-asm/49611] Inline asm should support input/output of flags

2014-05-30 Thread scovich at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #6 from Ryan Johnson scovich at gmail dot com ---
(In reply to Jeremy from comment #5)
 It may not be possible, but perhaps a simpler thing might be for
 the asm() to notionally return a single boolean value which
 reflects ONE flag only.

Interesting!

Ironically, limiting it to one flag opens the way to cleanly specify branching
based on multiple flags. The optimizer just needs to recognize that when it
sees two otherwise-equivalent (non-volatile) asm statements with different
asm_return attribute, it's really just one asm statement that sets multiple
flags. Thus: 

#ifdef USE_ASM
#define CMP(a,b) asm(cmp %0 %1 : : r(a), r(b))
#define BELOW(a,b) (__attribute__((asm_return(cc_carry))) CMP(a,b))
#define EQUAL(a,b) (__attribute__((asm_return(cc_zero))) CMP(a,b))
#else
#define BELOW(a,b) ((a)  (b))
#define EQUAL(a,b) ((a) == (b))
#endif
int do_it(unsigned int a, unsigned int b, int c, int d, int e, int f) {
int x;
if (BELOW(a,b))
x = c+d;
else if (EQUAL(a,b))
x = d+e;
else
x = c+e;
return x+f;
}

Would produce the same assembly code output---with only one
comparison---whether USE_ASM was defined or not.

Even more fun would be if the optimizer could recognize conditionals that
depend on multiple flags (like x86 less or equal) and turn this:

if ((__attribute__((asm_return(cc_zero))) CMP(a,b) 
|| __attribute__((asm_return(cc_overflow))) CMP(a,b) 
!= __attribute__((asm_return(cc_sign))) CMP(a,b))
do_less_or_equal();
do_something_else();

into:

cmp %[a] %[b]
jg 1f
call do_less_or_equal
1:
call do_something_else

Much of the flag-wrangling machinery seems to already exist, because the
compiler emits the above asm if you replace the inline asm with either a = b
or a  b || a == b (assuming now that a and b are signed ints).


[Bug inline-asm/49611] Inline asm should support input/output of flags

2012-06-28 Thread jbemmel at zonnet dot nl
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

Jeroen van Bemmel jbemmel at zonnet dot nl changed:

   What|Removed |Added

 CC||jbemmel at zonnet dot nl

--- Comment #4 from Jeroen van Bemmel jbemmel at zonnet dot nl 2012-06-28 
16:06:18 UTC ---
Ideally, there would be some way to express that a given asm goto block depends
on the flags, to prevent GCC from reordering flags-changing instructions and
breaking the code.

As a compromise, GCC could simply assume by default that asm goto blocks depend
on the flags. Like Ryan, I believe that most people using asm goto would use it
for such a purpose, and any missed optimization opportunities are a small price
to pay for correct code.


[Bug inline-asm/49611] Inline asm should support input/output of flags

2012-04-12 Thread scovich at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #3 from Ryan Johnson scovich at gmail dot com 2012-04-12 16:39:32 
UTC ---
FYI: based on a discussion from quite some time ago [1], it seems that the
Linux kernel folks would be tickled pink to have this feature, and discussed
several potential ways to implement it.

[1] http://lkml.indiana.edu/hypermail/linux/kernel/0111.2/0256.html


[Bug inline-asm/49611] Inline asm should support input/output of flags

2011-07-04 Thread scovich at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #2 from Ryan Johnson scovich at gmail dot com 2011-07-04 20:32:01 
UTC ---
(In reply to comment #1)
 Making this work reliably is probably more work than making GCC use the flags
 from more cases from regular C code.

Does that mean each such case would need to be identified individually and then
hard-wired into i386.md? The existence of modes like CCGC, CCGOC, CCNO, etc. in
i386-modes.def made me hope that some high-level mechanism existed for
reasoning about the semantics of condition codes. Or does that mechanism exist,
and is just difficult to expose to inline asm for some reason?


[Bug inline-asm/49611] Inline asm should support input/output of flags

2011-07-02 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49611

--- Comment #1 from Richard Guenther rguenth at gcc dot gnu.org 2011-07-02 
12:36:44 UTC ---
Making this work reliably is probably more work than making GCC use the flags
from more cases from regular C code.