[Bug target/114732] ge can't be reversed to unlt for bcd compares

2024-04-16 Thread guihaoc at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114732

--- Comment #6 from HaoChen Gui  ---
(In reply to Segher Boessenkool from comment #3)
> 1001, 0101, 0011 I mean of course.
> 
> In some ways CCmode models this better than CCFPmode, but we do not actually
> model
> the SO bit (bit 3) at all in CCmode.  It is a nice feature of CCmode (that we
> actually use as fundamental, in the backend code) that CCmode always has
> exactly
> one of three bits "hot" (and CCFPmode always one of four).  Bit 3 (SO) in
> CCmode
> is treated as not being part of the CC really, but an extra thing.  This
> doesn't
> work all that well of course.
> 
> So we really need st least three CC modes:
> 
> -- Exactly one of bits 0..3 hot, like CCFPmode;
> -- Exactly one of bits 0..2 hot, bit 3 independently set, like CCmode (and
>that independent bit 3 modeled nicely as well, unlike what we have), and
>also like in the BCD insns;
> -- Bit 0 is all-true, bit 2 is all-false, like in the vcmp* insns.
> 
> Do we need some other CC mode as well?  Doe we want separately named CC modes
> for the different variants of this (like the integer CC mode vs. the BCD
> one)?
> We already have a separate CCUNSmode which is exactly like CCmode, as far as
> the hardware cares, but the meaning is different (for CCUNS the LT and GT
> bits
> are set based on an unsigned integer compare, not a signed one).  There also
> is CCEQmode, which has only bit 2 valid (we use it for constructing one CR
> bit
> from others, like with cror or crnot).

Thanks for your comment. We also have VSX scalar test data class (xststdc*
insns) which use bit 0 as sign and bit 2 as matched. I think they can share
with vcmp* insns.

Could you advice if rtl code "unorder" is suitable for bcd overflow and invalid
bit test? Or we need to create UNSPECs for overflow and invalid bit test.
Thanks.

[Bug target/114732] ge can't be reversed to unlt for bcd compares

2024-04-16 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114732

--- Comment #5 from Segher Boessenkool  ---
(Or, at-most-one-hot, that is!)

[Bug target/114732] ge can't be reversed to unlt for bcd compares

2024-04-16 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114732

--- Comment #4 from Segher Boessenkool  ---
(In reply to Segher Boessenkool from comment #3)
> -- Bit 0 is all-true, bit 2 is all-false, like in the vcmp* insns.

(And bits 1 and 3 are set to zeroes for those insns.  So it is all one-hot
there
as well.  But the meaning is different.)

[Bug target/114732] ge can't be reversed to unlt for bcd compares

2024-04-16 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114732

--- Comment #3 from Segher Boessenkool  ---
1001, 0101, 0011 I mean of course.

In some ways CCmode models this better than CCFPmode, but we do not actually
model
the SO bit (bit 3) at all in CCmode.  It is a nice feature of CCmode (that we
actually use as fundamental, in the backend code) that CCmode always has
exactly
one of three bits "hot" (and CCFPmode always one of four).  Bit 3 (SO) in
CCmode
is treated as not being part of the CC really, but an extra thing.  This
doesn't
work all that well of course.

So we really need st least three CC modes:

-- Exactly one of bits 0..3 hot, like CCFPmode;
-- Exactly one of bits 0..2 hot, bit 3 independently set, like CCmode (and
   that independent bit 3 modeled nicely as well, unlike what we have), and
   also like in the BCD insns;
-- Bit 0 is all-true, bit 2 is all-false, like in the vcmp* insns.

Do we need some other CC mode as well?  Doe we want separately named CC modes
for the different variants of this (like the integer CC mode vs. the BCD one)?
We already have a separate CCUNSmode which is exactly like CCmode, as far as
the hardware cares, but the meaning is different (for CCUNS the LT and GT bits
are set based on an unsigned integer compare, not a signed one).  There also
is CCEQmode, which has only bit 2 valid (we use it for constructing one CR bit
from others, like with cror or crnot).

[Bug target/114732] ge can't be reversed to unlt for bcd compares

2024-04-16 Thread segher at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114732

--- Comment #2 from Segher Boessenkool  ---
The fourth CR bit for BCD insns does not mean "unordered", it means "invalid or
overflow".  It behaves exactly as unordered though, except that it can signal
overflow as well as one of the lt gt eq conditions at the same time (so 1100,
1010, 1001 are valid bit settings from it).  This part makes CCFP not ideal,
but the codegen as shown here is correct nevertheless.

[Bug target/114732] ge can't be reversed to unlt for bcd compares

2024-04-16 Thread guihaoc at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114732

--- Comment #1 from HaoChen Gui  ---
A straightforward test case.  It passes when compiling with O0 and aborts when
compiling with O2.

//test.c
#include 

#define BCD_POS0  12//  0xC
#define BCD_NEG   13//  0xD

void abort (void);

vector unsigned char maxbcd (unsigned int sign)
{
  vector unsigned char result;
  int i;

  for (i = 15; i > 0; i--)
result[i] = 0x99;

  result[0] = 0x9 << 4 | sign;

  return result;
}


__attribute__ ((noinline))
int foo (vector unsigned char a, vector unsigned char b)
{
  return __builtin_vec_bcdsub_ge (a, b, 0) != 1;
}

int main(void)
{
  vector unsigned char a = maxbcd (BCD_POS0);
  vector unsigned char b = maxbcd (BCD_NEG);

  if (foo(a, b))
abort ();

  return 0;
}