[i386] __builtin_ia32_stmxcsr could be pure
authorMarc Glisse <marc.glisse@inria.fr>
Wed, 21 Jun 2017 11:20:41 +0000 (13:20 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Wed, 21 Jun 2017 11:20:41 +0000 (11:20 +0000)
2017-06-21  Marc Glisse  <marc.glisse@inria.fr>

gcc/
* config/i386/i386.c (struct builtin_isa): New field pure_p.
Reorder for compactness.
(def_builtin, def_builtin2, ix86_add_new_builtins): Handle pure_p.
(def_builtin_pure, def_builtin_pure2): New functions.
(ix86_init_mmx_sse_builtins) [__builtin_ia32_stmxcsr]: Mark as pure.

gcc/testsuite/
* gcc.target/i386/getround.c: New file.

From-SVN: r249448

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/getround.c [new file with mode: 0644]

index 65ff2356f3bcb24ccb3cb4b62c634ca92453f273..62f91e587a836e71b5a922814f804f80742e014e 100644 (file)
@@ -1,3 +1,11 @@
+2017-06-21  Marc Glisse  <marc.glisse@inria.fr>
+
+       * config/i386/i386.c (struct builtin_isa): New field pure_p.
+       Reorder for compactness.
+       (def_builtin, def_builtin2, ix86_add_new_builtins): Handle pure_p.
+       (def_builtin_pure, def_builtin_pure2): New functions.
+       (ix86_init_mmx_sse_builtins) [__builtin_ia32_stmxcsr]: Mark as pure.
+
 2017-06-21  Marc Glisse  <marc.glisse@inria.fr>
 
        * match.pd (nop_convert): New predicate.
index 9f7290ad2398b18cc288c5bb24b69cca3faa955b..3caeeb0e37716931bddad32092634fb55073475c 100644 (file)
@@ -31935,11 +31935,12 @@ static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];
    but are waiting to be built until a function is declared to use that
    ISA.  */
 struct builtin_isa {
-  const char *name;            /* function name */
-  enum ix86_builtin_func_type tcode; /* type to use in the declaration */
   HOST_WIDE_INT isa;           /* isa_flags this builtin is defined for */
   HOST_WIDE_INT isa2;          /* additional isa_flags this builtin is defined for */
-  bool const_p;                        /* true if the declaration is constant */
+  const char *name;            /* function name */
+  enum ix86_builtin_func_type tcode; /* type to use in the declaration */
+  unsigned char const_p:1;     /* true if the declaration is constant */
+  unsigned char pure_p:1;      /* true if the declaration has pure attribute */
   bool leaf_p;                 /* true if the declaration has leaf attribute */
   bool nothrow_p;              /* true if the declaration has nothrow attribute */
   bool set_and_not_built_p;
@@ -32010,6 +32011,7 @@ def_builtin (HOST_WIDE_INT mask, const char *name,
          ix86_builtins_isa[(int) code].leaf_p = false;
          ix86_builtins_isa[(int) code].nothrow_p = false;
          ix86_builtins_isa[(int) code].const_p = false;
+         ix86_builtins_isa[(int) code].pure_p = false;
          ix86_builtins_isa[(int) code].set_and_not_built_p = true;
        }
     }
@@ -32032,6 +32034,21 @@ def_builtin_const (HOST_WIDE_INT mask, const char *name,
   return decl;
 }
 
+/* Like def_builtin, but also marks the function decl "pure".  */
+
+static inline tree
+def_builtin_pure (HOST_WIDE_INT mask, const char *name,
+                 enum ix86_builtin_func_type tcode, enum ix86_builtins code)
+{
+  tree decl = def_builtin (mask, name, tcode, code);
+  if (decl)
+    DECL_PURE_P (decl) = 1;
+  else
+    ix86_builtins_isa[(int) code].pure_p = true;
+
+  return decl;
+}
+
 /* Like def_builtin, but for additional isa2 flags.  */
 
 static inline tree
@@ -32066,6 +32083,7 @@ def_builtin2 (HOST_WIDE_INT mask, const char *name,
       ix86_builtins_isa[(int) code].leaf_p = false;
       ix86_builtins_isa[(int) code].nothrow_p = false;
       ix86_builtins_isa[(int) code].const_p = false;
+      ix86_builtins_isa[(int) code].pure_p = false;
       ix86_builtins_isa[(int) code].set_and_not_built_p = true;
     }
 
@@ -32087,6 +32105,21 @@ def_builtin_const2 (HOST_WIDE_INT mask, const char *name,
   return decl;
 }
 
+/* Like def_builtin, but also marks the function decl "pure".  */
+
+static inline tree
+def_builtin_pure2 (HOST_WIDE_INT mask, const char *name,
+                  enum ix86_builtin_func_type tcode, enum ix86_builtins code)
+{
+  tree decl = def_builtin2 (mask, name, tcode, code);
+  if (decl)
+    DECL_PURE_P (decl) = 1;
+  else
+    ix86_builtins_isa[(int) code].pure_p = true;
+
+  return decl;
+}
+
 /* Add any new builtin functions for a given ISA that may not have been
    declared.  This saves a bit of space compared to adding all of the
    declarations to the tree, even if we didn't use them.  */
@@ -32125,6 +32158,8 @@ ix86_add_new_builtins (HOST_WIDE_INT isa, HOST_WIDE_INT isa2)
          ix86_builtins[i] = decl;
          if (ix86_builtins_isa[i].const_p)
            TREE_READONLY (decl) = 1;
+         if (ix86_builtins_isa[i].pure_p)
+           DECL_PURE_P (decl) = 1;
          if (ix86_builtins_isa[i].leaf_p)
            DECL_ATTRIBUTES (decl) = build_tree_list (get_identifier ("leaf"),
                                                      NULL_TREE);
@@ -32478,8 +32513,8 @@ ix86_init_mmx_sse_builtins (void)
   /* SSE */
   def_builtin (OPTION_MASK_ISA_SSE, "__builtin_ia32_ldmxcsr",
               VOID_FTYPE_UNSIGNED, IX86_BUILTIN_LDMXCSR);
-  def_builtin (OPTION_MASK_ISA_SSE, "__builtin_ia32_stmxcsr",
-              UNSIGNED_FTYPE_VOID, IX86_BUILTIN_STMXCSR);
+  def_builtin_pure (OPTION_MASK_ISA_SSE, "__builtin_ia32_stmxcsr",
+                   UNSIGNED_FTYPE_VOID, IX86_BUILTIN_STMXCSR);
 
   /* SSE or 3DNow!A */
   def_builtin (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A,
index ccfd2746b876d5df7a0233e6eb4be8ce4d011af6..c9650f6d6f2a39688181b6bf3447da6127fd0b34 100644 (file)
@@ -1,3 +1,7 @@
+2017-06-21  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.target/i386/getround.c: New file.
+
 2017-06-21  Marc Glisse  <marc.glisse@inria.fr>
 
        * gcc.dg/tree-ssa/addadd.c: Un-XFAIL.
diff --git a/gcc/testsuite/gcc.target/i386/getround.c b/gcc/testsuite/gcc.target/i386/getround.c
new file mode 100644 (file)
index 0000000..e9d43b0
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -msse" } */
+
+#include <xmmintrin.h>
+
+unsigned save;
+
+void f(unsigned mode){
+  unsigned tmp = _MM_GET_ROUNDING_MODE();
+  _MM_SET_ROUNDING_MODE(mode);
+  save = tmp;
+}
+
+/* { dg-final { scan-assembler-times "stmxcsr" 1 } } */