Bug 91174 - Suboptimal code for arithmetic with bool and char
Summary: Suboptimal code for arithmetic with bool and char
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2019-07-15 14:28 UTC by Antony Polukhin
Modified: 2019-07-16 09:20 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64-*-*, i?86-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Antony Polukhin 2019-07-15 14:28:55 UTC
Consider the example:

int test (bool x) {
    return '0' + x;
}


For the above snippet the following suboptimal assembly is generated:


test(bool):
  movzx eax, dil
  add eax, 48
  ret


More efficient assembly would be:

test(bool):
  lea eax, [rdi + 48]
  ret
Comment 1 Florian Weimer 2019-07-15 14:42:55 UTC
For which ABI do you propose the change?  It's not correct for GNU/Linux:

“When a value of type _Bool is returned or passed in a register or on the stack,
bit 0 contains the truth value and bits 1 to 7 shall be zero.” And the footnote says: “Other bits are left unspecified, hence the consumer side of those values can rely on it being 0 or 1 when truncated to 8 bit.”
Comment 2 Antony Polukhin 2019-07-16 08:57:50 UTC
(In reply to Florian Weimer from comment #1)
> For which ABI do you propose the change?  It's not correct for GNU/Linux:

As far as I understand the proposed change does not touch ABI. `lea eax, [rdi + 48]` is equivalent to `movzx+add`
Comment 3 Florian Weimer 2019-07-16 09:01:19 UTC
(In reply to Antony Polukhin from comment #2)
> (In reply to Florian Weimer from comment #1)
> > For which ABI do you propose the change?  It's not correct for GNU/Linux:
> 
> As far as I understand the proposed change does not touch ABI. `lea eax,
> [rdi + 48]` is equivalent to `movzx+add`

According to the x86-64 psABI, for bool, only the lower 8 bits of the register are defined when passing a bool value.  This means that the movzx instruction is not optional because the int result needs all 32 bits defined.

GCC already uses lea in cases where the upper 24 bits do not matter, as in this example:

char test (bool x) {
    return '0' + x;
}
Comment 4 Antony Polukhin 2019-07-16 09:12:08 UTC
Sorry, now I understood that the bug is invalid. Please close.
Comment 5 Florian Weimer 2019-07-16 09:20:00 UTC
Closing.