https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71460
--- Comment #22 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Alexander Cherepanov from comment #12) > On 2016-06-09 11:22, rguenth at gcc dot gnu.org wrote: > > Would be nice to have a testcase for the SRA case as well. > > Source code: > > ---------------------------------------------------------------------- > #define _GNU_SOURCE > #include <fenv.h> > > struct s { double d; char c; }; > > __attribute__((noinline,noclone)) > void copy(struct s *q, struct s *p) > { > struct s tmp = *p; > *q = tmp; > } > > int main() > { > feenableexcept(FE_INVALID); > > struct s x = {0}, y; > ((unsigned char *)&x.d)[7] = 0x7f; > ((unsigned char *)&x.d)[6] = 0xf0; // sNaN > ((unsigned char *)&x.d)[0] = 0x01; > > copy(&y, &x); > } > ---------------------------------------------------------------------- > > Results: > > ---------------------------------------------------------------------- > $ gcc -std=c11 -pedantic -Wall -Wextra -fsignaling-nans -lm -m32 -O3 > test.c && ./a.out > Floating point exception > ---------------------------------------------------------------------- > > gcc version: gcc (GCC) 7.0.0 20160608 (experimental) So for this one the following would work together with the proposed backend fix (but not for the array case). It also makes me think using this target hook is not really the thing to test here given its docs: " @deftypefn {Target Hook} bool TARGET_MEMBER_TYPE_FORCES_BLK (const_tree @var{field}, machine_mode @var{mode}) Return true if a structure, union or array containing @var{field} should be accessed using @code{BLKMODE}. If @var{field} is the only field in the structure, @var{mode} is its mode, otherwise @var{mode} is VOIDmode. @var{mode} is provided in the case where structures of one field would require the structure's mode to retain the field's mode. Normally, this is not needed. " another thing to test here would be MODE_HAS_NANS, but that's too general I think. It seems we lack sth to query from the target, like MODE_ACCESS_CAN_TRAP or so (just thinking of IA64 NaT stuff). At least the following points out the place in SRA to put the fix in - it guards the case artificial accesses are created for a struct copy (though not all of them are ultimatively used - SRA works too "local" for them). We need to be careful to be not too conservative and disable too much of SRA. The hook seems to be used to avoid various issues, not only trapping. Index: gcc/tree-sra.c =================================================================== --- gcc/tree-sra.c (revision 237286) +++ gcc/tree-sra.c (working copy) @@ -969,6 +969,9 @@ scalarizable_type_p (tree type) if (DECL_BIT_FIELD (fld)) return false; + if (targetm.member_type_forces_blk (fld, TYPE_MODE (ft))) + return false; + if (!is_gimple_reg_type (ft) && !scalarizable_type_p (ft)) return false; @@ -994,6 +997,10 @@ scalarizable_type_p (tree type) return false; tree elem = TREE_TYPE (type); + + if (targetm.member_type_forces_blk (elem, TYPE_MODE (elem))) + return false; + if (!is_gimple_reg_type (elem) && !scalarizable_type_p (elem)) return false;