Bug 98304 - Failure to optimize bitwise arithmetic pattern
Summary: Failure to optimize bitwise arithmetic pattern
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 11.0
: P3 enhancement
Target Milestone: 13.0
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2020-12-15 21:54 UTC by Gabriel Ravier
Modified: 2023-09-21 10:38 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-11-25 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gabriel Ravier 2020-12-15 21:54:11 UTC
int f1(int n)
{
    return n - (((n > 63) ? n : 63) & -64);
}

This can be optimized to `return (n <= 63) ? n : (n & 63);` (and presumably the same optimization should be doable with other powers of 2).

PS: I found this optimization while looking at how this :

int f1(int n)
{
    while (n >= 64)
        n -= 64;

    return n;
}

is optimized. LLVM outputs the first example I gave here, while GCC outputs the optimization I gave here.
Comment 1 Andrew Pinski 2021-11-25 22:33:43 UTC
  _1 = MAX_EXPR <n_3(D), 63>;
  _2 = _1 & -64;
  _4 = n_3(D) - _2;

Something like:

(simplify
 (minus @0 (bit_and (max @0 INTEGER_CST@1) INTEGER_CST@2))
 (if (@1 == (@2)-1)
  (if (TYPE_SIGN (type) == UNSIGNED)
   (bit_and @0 @1)
   (cond (le @0 @1) @0 (bit_and @0 @1))
  )
 )
)

Note LLVM handles the unsigned case already.

Also note also even though GCC can handle the loop case for signed, it only handles it on the RTL level, for gimple GCC produces:
  _3 = n_2(D) + -64;
  _8 = (unsigned int) n_2(D);
  _9 = _8 + 4294967232; // _9 = _3 - 64
  _10 = _9 >> 6; // _10 = _9/64
  _11 = (int) _10;
  _12 = _11 * -64;
  n_1 = _3 + _12;
Comment 2 Andrew Pinski 2021-11-25 22:39:29 UTC
> @1 == (@2)-1

Should have been:
@1 == -(@2-1)

maybe check that @1 is a mask.
Comment 3 GCC Commits 2022-07-09 16:08:53 UTC
The master branch has been updated by Jeff Law <law@gcc.gnu.org>:

https://gcc.gnu.org/g:d9fa599dc7584d89e758a09a3d68982f12d8751c

commit r13-1587-gd9fa599dc7584d89e758a09a3d68982f12d8751c
Author: Sam Feifer <sfeifer@redhat.com>
Date:   Sat Jul 9 12:08:01 2022 -0400

    [PATCH] match.pd: Add new bitwise arithmetic pattern [PR98304]
    
            PR tree-optimization/98304
    
    gcc:
    
            * match.pd (n - (((n > C1) ? n : C1) & -C2)): New simplification.
    
    gcc/testsuite:
    
            * gcc.c-torture/execute/pr98304-2.c: New test.
            * gcc.dg/pr98304-1.c: New test.
Comment 4 Andrew Pinski 2023-09-17 05:58:18 UTC
Fixed