Bug 83123 - Int compare - different asm code for different return type
Summary: Int compare - different asm code for different return type
Status: RESOLVED DUPLICATE of bug 95731
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 7.2.0
: P3 enhancement
Target Milestone: 11.0
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2017-11-23 08:25 UTC by Daniel Fruzynski
Modified: 2021-08-14 21:28 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64-*-*, i?86-*-*
Build:
Known to work: 11.1.0
Known to fail: 10.3.0
Last reconfirmed: 2017-11-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Fruzynski 2017-11-23 08:25:59 UTC
int test1(int a, int b)
{
  return (a < 0) && (b < 0);
}
bool test2(int a, int b)
{
  return (a < 0) && (b < 0);
}

This produces following code, when compiled with -O2. For some reason 2nd function performs shifts first, then and. This is not necessary, you can and first, then shift. The same issue is for checking if any of numbers is negative - or can be executed first, then shift.

test1(int, int):
  and esi, edi
  mov eax, esi
  shr eax, 31
  ret
test2(int, int):
  mov eax, edi
  shr esi, 31
  shr eax, 31
  and eax, esi
  ret
Comment 1 Richard Biener 2017-11-23 10:44:10 UTC
The first case is somehow optimized by combine while the latter is not.
The gimple is almost equal, so is the expanded RTL.

test1 (int a, int b)
{
  _Bool _1;
  _Bool _2;
  _Bool _3;
  int _6;

  <bb 2> [local count: 1073741825]:
  _1 = a_4(D) < 0;
  _2 = b_5(D) < 0;
  _3 = _1 & _2;
  _6 = (int) _3;
  return _6;

test2 (int a, int b)
{
  _Bool _1;
  _Bool _2;
  _Bool _3;

  <bb 2> [local count: 1073741825]:
  _1 = a_4(D) < 0;
  _2 = b_5(D) < 0;
  _3 = _1 & _2;
  return _3;
Comment 2 Segher Boessenkool 2017-11-23 17:34:08 UTC
In the first case (with the extend to SImode) the extend is combined
with the AND, to an AND in SImode.  After that, the 3-insn combination
of the two shifts with the AND is something combine knows how to split.

In the second case this of course does not happen.
Comment 3 Andrew Pinski 2021-08-14 21:26:43 UTC
This is now optimized at the gimple level to just:

  _7 = a_3(D) & b_4(D);
  _8 = _7 < 0;
Comment 4 Andrew Pinski 2021-08-14 21:28:12 UTC
Handled by 95731.

*** This bug has been marked as a duplicate of bug 95731 ***