i386: Fix up X87_ENABLE_{FLOAT,ARITH} in conditions [PR94440]
authorJakub Jelinek <jakub@redhat.com>
Tue, 8 Dec 2020 14:44:10 +0000 (15:44 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 8 Dec 2020 14:44:10 +0000 (15:44 +0100)
commite401db7bfd8cf86d3833805a81b1252884eb1c9d
tree107c5ffc77038f58a8a955bd8dfeee421a9cc547
parent0bd4fecbea3b3da9befe24906f699d63fb28ed71
i386: Fix up X87_ENABLE_{FLOAT,ARITH} in conditions [PR94440]

The documentation says
     For a named pattern, the condition may not depend on the data in
     the insn being matched, but only the target-machine-type flags.
The i386 backend violates that by using flag_excess_precision and
flag_unsafe_math_optimizations in the conditions too, which is bad
when optimize attribute or pragmas are used.  The problem is that the
middle-end caches the enabled conditions for the optabs for a particular
switchable target, but multiple functions can share the same
TARGET_OPTION_NODE, but have different TREE_OPTIMIZATION_NODE with different
flag_excess_precision or flag_unsafe_math_optimizations, so the enabled
conditions then match only one of those.

I think best would be to just have a single options node for both the
generic and target options, then such problems wouldn't exist, but that
would be very risky at this point and quite large change.

So, instead the following patch just shadows flag_excess_precision and
flag_unsafe_math_optimizations values for uses in the instruction conditions
in TargetVariable and during set_cfun artificially creates new
TARGET_OPTION_NODE if flag_excess_precision and/or
flag_unsafe_math_optimizations change from what is recorded in their
TARGET_OPTION_NODE.  The target nodes are hashed, so worst case we can get 4
times as many target option nodes if one would for each unique target option
try all the flag_excess_precision and flag_unsafe_math_optimizations values.

2020-12-08  Jakub Jelinek  <jakub@redhat.com>

PR target/94440
* config/i386/i386.opt (ix86_excess_precision,
ix86_unsafe_math_optimizations): New TargetVariables.
* config/i386/i386.h (X87_ENABLE_ARITH, X87_ENABLE_FLOAT): Use
ix86_unsafe_math_optimizations instead of
flag_unsafe_math_optimizations and ix86_excess_precision instead of
flag_excess_precision.
* config/i386/i386.c (ix86_excess_precision): Rename to ...
(ix86_get_excess_precision): ... this.
(TARGET_C_EXCESS_PRECISION): Define to ix86_get_excess_precision.
* config/i386/i386-options.c (ix86_valid_target_attribute_tree,
ix86_option_override_internal): Update ix86_unsafe_math_optimization
from flag_unsafe_math_optimizations and ix86_excess_precision
from flag_excess_precision when constructing target option nodes.
(ix86_set_current_function): If flag_unsafe_math_optimizations
or flag_excess_precision is different from the one recorded
in TARGET_OPTION_NODE, create a new target option node for the
current function and switch to that.
gcc/config/i386/i386-options.c
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.opt
gcc/testsuite/gcc.target/i386/pr94440-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr94440-2.c [new file with mode: 0644]