[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