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

            Bug ID: 101991
           Summary: bit_and or bit_ior with an invariant inside loop is
                    not pulled out of the loop
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pinskia at gcc dot gnu.org
  Target Milestone: ---

Take these two functions:
int f(int t, int d, int e)
{
  int r = d;
  for(int i = 0; i < t; i++)
    r &= e;
  return r;
}

int f1(int t, int d, int e)
{
  int r = d;
  if (0 < t)
    r &= e;
  return r;
}
They should produce the same code.  Right now f still has a loop in it.
The same is true with bit_ior.

Note the code is really bad when the vectorizer comes around really.
I forgot how I found this either.
Note clang/ICC also vectorize this code crappily.
clang on the trunk almost gets there but still has a loop:

        movl    %esi, %eax
        xorl    %esi, %esi
        testl   %edi, %edi
        cmovgl  %edi, %esi
        jle     .LBB0_6
# %bb.1:
        leal    -1(%rsi), %edi
        movl    %esi, %ecx
        andl    $7, %ecx
        cmpl    $7, %edi
        jb      .LBB0_4
# %bb.2:
        andl    $-8, %esi
        negl    %esi
        .p2align        4, 0x90
.LBB0_3:                                # =>This Inner Loop Header: Depth=1
        addl    $8, %esi
        jne     .LBB0_3
.LBB0_4:
        andl    %edx, %eax
        testl   %ecx, %ecx
        je      .LBB0_6
        .p2align        4, 0x90
.LBB0_5:                                # =>This Inner Loop Header: Depth=1
        addl    $-1, %ecx
        jne     .LBB0_5
.LBB0_6:
        retq

Reply via email to