public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/101807] New: bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1
@ 2021-08-06 21:22 pinskia at gcc dot gnu.org
  2023-05-18 19:18 ` [Bug middle-end/101807] " pinskia at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-06 21:22 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 101807
           Summary: bool0 < bool1 Should expand as !bool0 &bool1 and bool0
                    <= bool1 as !bool0 | bool1
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pinskia at gcc dot gnu.org
  Target Milestone: ---

Take:
bool f(bool a, bool b)
{
    return a<b;
}
bool g(bool a, bool b)
{
  return !a & b;
}
These two should produce similar code.
<= is similar.

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

* [Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1
  2021-08-06 21:22 [Bug middle-end/101807] New: bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1 pinskia at gcc dot gnu.org
@ 2023-05-18 19:18 ` pinskia at gcc dot gnu.org
  2023-05-18 20:00 ` pinskia at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-18 19:18 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> 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 <pinskia at gcc dot gnu.org> ---
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<b;
}


Which gives:
        xorl    $1, %edi
        movl    %edi, %eax
        andl    %esi, %eax

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

* [Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1
  2021-08-06 21:22 [Bug middle-end/101807] New: bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1 pinskia at gcc dot gnu.org
  2023-05-18 19:18 ` [Bug middle-end/101807] " pinskia at gcc dot gnu.org
@ 2023-05-18 20:00 ` pinskia at gcc dot gnu.org
  2023-05-18 20:01 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-18 20:00 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
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<b;
}
bool g(bool a, bool b)
{
  return !a & b;
}
f0:
        jr      $31
        sltu    $2,$4,$5
g:
        xori    $4,$4,0x1
        jr      $31
        and     $2,$5,$4

And then after my current patch both are expanded like g. which is wrong.

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

* [Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1
  2021-08-06 21:22 [Bug middle-end/101807] New: bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1 pinskia at gcc dot gnu.org
  2023-05-18 19:18 ` [Bug middle-end/101807] " pinskia at gcc dot gnu.org
  2023-05-18 20:00 ` pinskia at gcc dot gnu.org
@ 2023-05-18 20:01 ` pinskia at gcc dot gnu.org
  2023-05-18 20:35 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-18 20:01 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(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 ...

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

* [Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1
  2021-08-06 21:22 [Bug middle-end/101807] New: bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1 pinskia at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2023-05-18 20:01 ` pinskia at gcc dot gnu.org
@ 2023-05-18 20:35 ` pinskia at gcc dot gnu.org
  2023-05-20 17:07 ` pinskia at gcc dot gnu.org
  2023-05-20 18:29 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-18 20:35 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
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);
        }
    }

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

* [Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1
  2021-08-06 21:22 [Bug middle-end/101807] New: bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1 pinskia at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2023-05-18 20:35 ` pinskia at gcc dot gnu.org
@ 2023-05-20 17:07 ` pinskia at gcc dot gnu.org
  2023-05-20 18:29 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-20 17:07 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Created attachment 55128
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55128&action=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.

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

* [Bug middle-end/101807] bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1
  2021-08-06 21:22 [Bug middle-end/101807] New: bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1 pinskia at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2023-05-20 17:07 ` pinskia at gcc dot gnu.org
@ 2023-05-20 18:29 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-20 18:29 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
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<b) return h();
    return j();
}
bool g(bool a, bool b)
{
  if (!a & b) return h();
  return j();
}
bool fi(signed char a, signed char b)
{
  if (a!=0&&a!=1) __builtin_unreachable();
  if (b!=0&&b!=1) __builtin_unreachable();
    if(a<b) return h();
    return j();
}
bool gi(signed char a, signed char b)
{
  if (a!=0&&a!=1) __builtin_unreachable();
  if (b!=0&&b!=1) __builtin_unreachable();
  if (!a & b) return h();
  return j();
}
```

on aarch64, we want f and g, and f and gi to produce the same code. But
currently only g and gi produce the best code of:
```
        bic     x0, x1, x0
        tbnz    x0, 0, .L13
```

It is even more interesting on x86, g produces two jumps while f and g produces
the best code:
```
        cmpb    %sil, %dil
        jb      .L4
```

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

end of thread, other threads:[~2023-05-20 18:29 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-06 21:22 [Bug middle-end/101807] New: bool0 < bool1 Should expand as !bool0 &bool1 and bool0 <= bool1 as !bool0 | bool1 pinskia at gcc dot gnu.org
2023-05-18 19:18 ` [Bug middle-end/101807] " pinskia at gcc dot gnu.org
2023-05-18 20:00 ` pinskia at gcc dot gnu.org
2023-05-18 20:01 ` pinskia at gcc dot gnu.org
2023-05-18 20:35 ` pinskia at gcc dot gnu.org
2023-05-20 17:07 ` pinskia at gcc dot gnu.org
2023-05-20 18:29 ` pinskia at gcc dot gnu.org

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).