[Bug target/82170] New: gcc optimizes int range-checking poorly on x86-64
eggert at gnu dot org
gcc-bugzilla@gcc.gnu.org
Sun Sep 10 22:16:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82170
Bug ID: 82170
Summary: gcc optimizes int range-checking poorly on x86-64
Product: gcc
Version: 7.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: eggert at gnu dot org
Target Milestone: ---
Created attachment 42148
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42148&action=edit
source code that is poorly optimized on x86-64
GCC on Fedora 26 x86-64 (GCC 7.1.1 20170622 (Red Hat 7.1.1-3) generates
poorly-optimized machine instructions for C code that tests in the obvious way
whether a 'long long' fits in 'int'. If n is long long, the expression (INT_MIN
<= n && n <= INT_MAX) should generate code that is no worse than
(!__builtin_add_overflow_p (n, 0, 0)). However, with -O2 optimization before
the conditional branch, the former expression generates four instructions
containing two literal constants, whereas the latter generates just two
instructions that reference only registers.
For the code that prompted this bug report we will likely use an "#if __GNUC__
< 7" that uses __builtin_add_overflow_p for GCC 7 and later, and the portable
code otherwise. It'd be nicer, though, if we could just use the portable code.
See:
https://sourceware.org/ml/libc-alpha/2017-09/msg00411.html
Attached are a source program inrange.c and an assembly-language file inrange.s
produced by 'gcc -O2 -S' that illustrates the problem. Akthough the two
functions checked_arg_GCC7 and checked_arg_portable should have the same
machine code, the former is more efficient than the latter.
More information about the Gcc-bugs
mailing list