[Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 and bool0 <= bool1 as !bool0 | bool1

2023-05-20 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101807

--- Comment #6 from Andrew Pinski  ---
Looks like I only implemented this for do_store_flag which is good but it needs
to also implemented for do_jump too.

Take:
```
#define bool _Bool
bool j(void);
bool h(void);
bool f(bool a, bool b)
{
if(a

[Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 and bool0 <= bool1 as !bool0 | bool1

2023-05-20 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101807

--- Comment #5 from Andrew Pinski  ---
Created attachment 55128
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55128=edit
Patch which I am testing

This one includes the cost model here.
Did a quick test on mips to see it produces the set compare instruction still.

[Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 and bool0 <= bool1 as !bool0 | bool1

2023-05-18 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101807

--- Comment #4 from Andrew Pinski  ---
Here is what I have so far without the cost model:

  /* Hand bool0 CMP bool1 because bitwise operators
 are normally better than comparisons.  */
  if (INTEGRAL_TYPE_P (type)
  && ((tree_nonzero_bits (arg0) == 1 && tree_nonzero_bits (arg1) == 1)
  || (unsignedp && TYPE_PRECISION (type) == 1)))
{
  tree b0 = arg0;
  tree b1 = arg1;
  bool not_p = false;
  bool operand1_not_p = false;
  tree_code code = ERROR_MARK;
  switch (ops->code)
{
case EQ_EXPR:
  not_p = true;
  code = BIT_XOR_EXPR;
  break;
case NE_EXPR:
  code = BIT_XOR_EXPR;
  break;
case GT_EXPR:
  std::swap (b0, b1);
  code = BIT_AND_EXPR;
  operand1_not_p = true;
  break;
case LT_EXPR:
  code = BIT_AND_EXPR;
  operand1_not_p = true;
  break;
case GE_EXPR:
  std::swap (b0, b1);
  code = BIT_IOR_EXPR;
  operand1_not_p = true;
  break;
case LE_EXPR:
  code = BIT_IOR_EXPR;
  operand1_not_p = true;
  break;
default:
  code = ERROR_MARK;
  break;
}
  if (code != ERROR_MARK)
{
  tree exp;
  tree one = build_int_cst (type, 1);
  if (operand1_not_p)
b0 = build2_loc (loc, BIT_XOR_EXPR, type, b0, one);
  exp = build2_loc (loc, code, type, b0, b1);
  if (not_p)
exp = build2_loc (loc, BIT_XOR_EXPR, type, exp, one);
  return expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
}
}

[Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 and bool0 <= bool1 as !bool0 | bool1

2023-05-18 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101807

--- Comment #3 from Andrew Pinski  ---
(In reply to Andrew Pinski from comment #2)
> Actually I need to check the cost, e.g. on MIPS, there is an one instruction
> which does the less than without doing anything.

RISCV too ...

[Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 and bool0 <= bool1 as !bool0 | bool1

2023-05-18 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101807

--- Comment #2 from Andrew Pinski  ---
Actually I need to check the cost, e.g. on MIPS, there is an one instruction
which does the less than without doing anything.

That is for:
bool f0(bool a, bool b)
{
return a

[Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 and bool0 <= bool1 as !bool0 | bool1

2023-05-18 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101807

Andrew Pinski  changed:

   What|Removed |Added

 Ever confirmed|0   |1
   Assignee|unassigned at gcc dot gnu.org  |pinskia at gcc dot 
gnu.org
   Last reconfirmed||2023-05-18
 Status|UNCONFIRMED |ASSIGNED

--- Comment #1 from Andrew Pinski  ---
I have a patch.

It even handles:
unsigned f(unsigned a, unsigned b)
{
if (a > 1) __builtin_unreachable();
if (b > 1) __builtin_unreachable();
return a