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;

Reply via email to