diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 028dfc748489aeae691ba6a12f6895fc2fb5dc20..f112f1ba291e15c25dcf1bd5a3ebad305d017d09 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-08-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR target/23360
+	* config/i386/crtfastmath.c (set_fast_math): Check if DAZ is
+	available for setting it.
+
 2005-08-14  Ira Rosen  <irar@il.ibm.com>
 
 	PR tree-optimization/23320
diff --git a/gcc/config/i386/crtfastmath.c b/gcc/config/i386/crtfastmath.c
index 3412d6ceda6e943cd7e95063a5c2efd1ebf2d463..fdff24723ac80aa8c544950fd0aac18392bea2f3 100644
--- a/gcc/config/i386/crtfastmath.c
+++ b/gcc/config/i386/crtfastmath.c
@@ -34,11 +34,15 @@
 #define MXCSR_DAZ (1 << 6)	/* Enable denormals are zero mode */
 #define MXCSR_FTZ (1 << 15)	/* Enable flush to zero mode */
 
+#define FXSAVE	(1 << 24)
+#define SSE	(1 << 25)
+
 static void __attribute__((constructor))
 set_fast_math (void)
 {
 #ifndef __x86_64__
-  /* SSE is the part of 64bit. Only need to check it for 32bit.  */
+  /* All 64-bit targets have SSE and DAZ; only check them explicitly
+     for 32-bit ones. */
   unsigned int eax, ebx, ecx, edx;
 
   /* See if we can use cpuid.  */
@@ -62,11 +66,45 @@ set_fast_math (void)
 		: "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
 		: "0" (1));
 
-  if (edx & (1 << 25))
-#endif
+  if (edx & SSE)
     {
       unsigned int mxcsr = __builtin_ia32_stmxcsr ();
-      mxcsr |= MXCSR_DAZ | MXCSR_FTZ;
+  
+      mxcsr |= MXCSR_FTZ;
+
+      if (edx & FXSAVE)
+	{
+	  /* Check if DAZ is available.  */
+	  struct
+	    {
+	      unsigned short int cwd;
+	      unsigned short int swd;
+	      unsigned short int twd;
+	      unsigned short int fop;
+	      long int fip;
+	      long int fcs;
+	      long int foo;
+	      long int fos;
+	      long int mxcsr;
+	      long int mxcsr_mask;
+	      long int st_space[32];
+	      long int xmm_space[32];
+	      long int padding[56];
+	    } __attribute__ ((aligned (16))) fxsave;
+
+	  __builtin_memset (&fxsave, 0, sizeof (fxsave));
+
+	  asm volatile ("fxsave %0" : : "m" (fxsave));
+
+	  if (fxsave.mxcsr_mask & MXCSR_DAZ)
+	    mxcsr |= MXCSR_DAZ;
+	}
+
       __builtin_ia32_ldmxcsr (mxcsr);
     }
+#else
+  unsigned int mxcsr = __builtin_ia32_stmxcsr ();
+  mxcsr |= MXCSR_DAZ | MXCSR_FTZ;
+  __builtin_ia32_ldmxcsr (mxcsr);
+#endif
 }