Patchwork [doc,testsuite,libgfortran] Avoid use of SSE/SSE2/SSE3 on Solaris 8/9 x86

login
register
mail settings
Submitter Rainer Orth
Date July 9, 2010, 1:22 p.m.
Message ID <yddwrt4x01w.fsf@manam.CeBiTec.Uni-Bielefeld.DE>
Download mbox | patch
Permalink /patch/58402/
State New
Headers show

Comments

Rainer Orth - July 9, 2010, 1:22 p.m.
My first attempts to build mainline for Solaris 8/9 x86 have just been
using the Solaris 8 and 9 assemblers on Solaris 11.  While a couple of
problems could be sorted out this way, actually bootstrapping found a
couple of others.  The most pressing one is that before Solaris 9 4/04,
the Solaris kernel doesn't save and restore SSE and SSE2 registers, so
any attempt to execute SSE/SSE2 instructions causes the program to
receive SIGILL, even if the CPU supports the insns:

Solaris/IA32 should save/restore SSE/SSE2 register set on context switch
http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4783204

To avoid the problem, I globally default -march to pentiumpro on Solaris
8 and 9, not only for Solaris 8 with Sun as as in this patch:

	http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01267.html

but there are still two areas that must be fixed because they use
SSE/SSE2 instructions regardless:

* libgfortran determines if the CPU is capable of executing SSE
  instructions at runtime and uses them if so.  This check is not
  enough and caused all Fortran exectution tests both in
  gcc/testsuite/gfortran.* and libgomp to fail.

* Similarly, the SSE/SSE2/SSE3 testcases in gcc.target/i386 use the same
  technique (cf. gcc.target/sse{, 2, 3}-check.h), and fail the same way.

Unfortunately, this problem cannot easily be detected at runtime, as
would be possible on Solaris 10+ with getisax(2), but we need to set up
a signal handler, try some instruction, and act accordingly.
Unfortunately, this is more involved than it may seem at first: you
cannot simply return from a SIGILL handler after setting some flag
variable, since the faulting instruction will be executed again, leading
to an infinite loop.  My solution was inspired by the way GNU libsigsegv
handles SEGV: they return from the signal handler with setcontext(2).  I
can do the same here, provided I set set PC to the next instruction
after the faulting one.  Therefore, I need to know exact insn lengths
and preferably use insns with side effects that don't hurt.

The meat of the patch which implements this can be found in
libgfortran/config/fpu-387.h and gcc.target/i386/sol2-check.h.  The
former takes care of libgfortran, the latter of all tests using
sse-check{, 2, 3}.h.  For the few remaining testcases that hardcode
-msse or -msse2, I need some new effective-target keywords: sse for the
ability to compile/assemble sse insns, sse_runtime and sse2_runtime for
the ability to execute them.

With this in place, I've been able to reduce testsuite failures from
ca. 13000 to just a handful.  There will a few unrelated followup
patches that bring Solaris 8/9 x86 testsuite results practically en par
with Solaris 10 and 11.

Bootstrapped without regressions on i386-pc-solaris2.{8, 9, 10, 11},
both with Sun as and GNU as.

At the moment, the 4.5 branch is broken on Solaris 8/9 x86, since it
won't even bootstrap without --with-arch=pentiumpro on Solaris 8 and 9,
which is a regression from 4.4.  Like this patch

	http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01276.html

I'd like to backport the current one to the 4.4 and 4.5 branches after
some soak time on mainline.

Ok for mainline now and the 4.4 and 4.5 branches later?

	Rainer


2010-06-14  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc:
	* config.gcc (i[34567]86-*-solaris2*): Default with_arch_32 to
	pentiumpro on Solaris 8 and 9/x86.
	* doc/install.texi (Specific, i?86-*-solaris2.[89]): Recommend GNU as.
	Document SSE/SSE2 support.
	* doc/sourcebuild.texi (Effective-Target Keywords): Document sse,
	sse_runtime, sse2_runtime.

	gcc/testsuite:
	* lib/target-supports.exp (check_effective_target_sse_runtime):
	New proc.
	* lib/target-supports.exp (check_effective_target_sse2_runtime):
	New proc.
	(check_effective_target_sse): New proc.
	* gcc.target/i386/sol2-check.h: New file.
	* gcc.target/i386/sse-check.h (ILL_INSN, ILL_INSN_LEN): Define.
	Include sol2-check.h.
	(main) Only run do_test () if sol2_check ().
	* gcc.target/i386/sse2-check.h: Likewise.
	* gcc.target/i386/sse3-check.h: Likewise.
	* gcc.dg/vect/tree-vect.h (check_vect) [__i386__ || __x86_64__]
	[__sun__ && __svr4__]: Execute SSE2 instruction.
	* lib/fortran-torture.exp (get-fortran-torture-options): Only add
	-msse2 if check_effective_target_sse2_runtime.
	* gfortran.dg/vect/vect.exp: Likewise.
	* gcc.target/i386/math-torture/math-torture.exp: Only add options
	with -msse to MATH_TORTURE_OPTIONS if check_effective_target_sse.
	* g++.dg/debug/dwarf2/const2b.C: Use dg-require-effective-target sse.
	* g++.dg/ext/vector14.C: Likewise.
	* g++.dg/other/mmintrin.C: Likewise.
	* gcc.dg/20020418-1.c: Likewise.
	* gcc.dg/debug/dwarf2/const-2b.c: Likewise.
	* gcc.dg/format/ms_unnamed-1.c: Likewise.
	* gcc.dg/format/unnamed-1.c: Likewise.
	Adapt dg-warning line number.
	* gcc.dg/graphite/pr40281.c: Likewise.
	* gcc.dg/pr32176.c: Likewise.
	* gcc.dg/pr40550.c: Likewise.
	* gcc.dg/prefetch-loop-arrays-1.c: Likewise.
	* gcc.dg/torture/pr36891.c: Likewise.
	* gcc.target/i386/20020218-1.c: Likewise.
	* gcc.target/i386/20020523.c: Likewise.
	* gcc.target/i386/abi-1.c: Likewise.
	* gcc.target/i386/brokensqrt.c: Likewise.
	* gcc.target/i386/fastcall-sseregparm.c: Likewise.
	* gcc.target/i386/pr13366.c: Likewise.
	* gcc.target/i386/pr13685.c: Likewise.
	* gcc.target/i386/pr24306.c: Likewise.
	* gcc.target/i386/pr31486.c: Likewise.
	* gcc.target/i386/pr32065-1.c: Likewise.
	* gcc.target/i386/pr32065-2.c: Likewise.
	* gcc.target/i386/pr32389.c: Likewise.
	* gcc.target/i386/pr38824.c: Likewise.
	* gcc.target/i386/pr38931.c: Likewise.
	* gcc.target/i386/pr39592-1.c: Likewise.
	* gcc.target/i386/pr43766.c: Likewise.
	* gcc.target/i386/recip-divf.c: Likewise.
	* gcc.target/i386/recip-sqrtf.c: Likewise.
	* gcc.target/i386/recip-vec-divf.c: Likewise.
	* gcc.target/i386/recip-vec-sqrtf.c: Likewise.
	* gcc.target/i386/sse-1.c: Likewise.
	* gcc.target/i386/sse-16.c: Likewise.
	* gcc.target/i386/sse-2.c: Likewise.
	* gcc.target/i386/sse-20.c: Likewise.
	* gcc.target/i386/sse-3.c: Likewise.
	* gcc.target/i386/sse-7.c: Likewise.
	* gcc.target/i386/sse-9.c: Likewise.
	* gcc.target/i386/sse-addps-1.c: Likewise.
	* gcc.target/i386/sse-addss-1.c: Likewise.
	* gcc.target/i386/sse-andnps-1.c: Likewise.
	* gcc.target/i386/sse-andps-1.c: Likewise.
	* gcc.target/i386/sse-cmpss-1.c: Likewise.
	* gcc.target/i386/sse-comiss-1.c: Likewise.
	* gcc.target/i386/sse-comiss-2.c: Likewise.
	* gcc.target/i386/sse-comiss-3.c: Likewise.
	* gcc.target/i386/sse-comiss-4.c: Likewise.
	* gcc.target/i386/sse-comiss-5.c: Likewise.
	* gcc.target/i386/sse-comiss-6.c: Likewise.
	* gcc.target/i386/sse-copysignf-vec.c: Likewise.
	* gcc.target/i386/sse-cvtsi2ss-1.c: Likewise.
	* gcc.target/i386/sse-cvtsi2ss-2.c: Likewise.
	* gcc.target/i386/sse-cvtss2si-1.c: Likewise.
	* gcc.target/i386/sse-cvtss2si-2.c: Likewise.
	* gcc.target/i386/sse-cvttss2si-1.c: Likewise.
	* gcc.target/i386/sse-cvttss2si-2.c: Likewise.
	* gcc.target/i386/sse-divps-1.c: Likewise.
	* gcc.target/i386/sse-divss-1.c: Likewise.
	* gcc.target/i386/sse-init-v4hi-1.c: Likewise.
	* gcc.target/i386/sse-init-v4sf-1.c: Likewise.
	* gcc.target/i386/sse-maxps-1.c: Likewise.
	* gcc.target/i386/sse-maxss-1.c: Likewise.
	* gcc.target/i386/sse-minps-1.c: Likewise.
	* gcc.target/i386/sse-minss-1.c: Likewise.
	* gcc.target/i386/sse-movaps-1.c: Likewise.
	* gcc.target/i386/sse-movaps-2.c: Likewise.
	* gcc.target/i386/sse-movhlps-1.c: Likewise.
	* gcc.target/i386/sse-movhps-1.c: Likewise.
	* gcc.target/i386/sse-movhps-2.c: Likewise.
	* gcc.target/i386/sse-movlhps-1.c: Likewise.
	* gcc.target/i386/sse-movmskps-1.c: Likewise.
	* gcc.target/i386/sse-movntps-1.c: Likewise.
	* gcc.target/i386/sse-movss-1.c: Likewise.
	* gcc.target/i386/sse-movss-2.c: Likewise.
	* gcc.target/i386/sse-movss-3.c: Likewise.
	* gcc.target/i386/sse-movups-1.c: Likewise.
	* gcc.target/i386/sse-movups-2.c: Likewise.
	* gcc.target/i386/sse-mulps-1.c: Likewise.
	* gcc.target/i386/sse-mulss-1.c: Likewise.
	* gcc.target/i386/sse-orps-1.c: Likewise.
	* gcc.target/i386/sse-rcpps-1.c: Likewise.
	* gcc.target/i386/sse-recip-vec.c: Likewise.
	* gcc.target/i386/sse-recip.c: Likewise.
	* gcc.target/i386/sse-rsqrtps-1.c: Likewise.
	* gcc.target/i386/sse-set-ps-1.c: Likewise.
	* gcc.target/i386/sse-sqrtps-1.c: Likewise.
	* gcc.target/i386/sse-subps-1.c: Likewise.
	* gcc.target/i386/sse-subss-1.c: Likewise.
	* gcc.target/i386/sse-ucomiss-1.c: Likewise.
	* gcc.target/i386/sse-ucomiss-2.c: Likewise.
	* gcc.target/i386/sse-ucomiss-3.c: Likewise.
	* gcc.target/i386/sse-ucomiss-4.c: Likewise.
	* gcc.target/i386/sse-ucomiss-5.c: Likewise.
	* gcc.target/i386/sse-ucomiss-6.c: Likewise.
	* gcc.target/i386/sse-unpckhps-1.c: Likewise.
	* gcc.target/i386/sse-unpcklps-1.c: Likewise.
	* gcc.target/i386/sse-xorps-1.c: Likewise.
	* gcc.target/i386/ssefn-1.c: Likewise.
	* gcc.target/i386/ssefn-3.c: Likewise.
	* gcc.target/i386/sseregparm-1.c: Likewise.
	* gcc.target/i386/stackalign/return-3.c: Likewise.
	* gcc.target/i386/vectorize1.c: Likewise.
	* gcc.target/i386/vperm-v4sf-1.c: Likewise.
	* gcc.target/i386/xorps-sse.c: Likewise.
	* gfortran.dg/pr28158.f90: Likewise.
	* gfortran.dg/pr30667.f: Likewise.
	* gnat.dg/loop_optimization7.adb: Likewise.
	* gnat.dg/sse_nolib.adb: Likewise.
	* g++.dg/other/i386-1.C: Use dg-require-effective-target sse2_runtime.
	* g++.dg/other/pr40446.C: Likewise.
	* gcc.dg/compat/union-m128-1_main.c: Likewise.
	* gcc.dg/compat/vector-1a_main.c: Likewise.
	* gcc.dg/compat/vector-2a_main.c: Likewise.
	* gcc.dg/pr36584.c: Likewise.
	* gcc.dg/pr37544.c: Likewise.
	* gcc.dg/torture/pr16104-1.c: Likewise.
	* gcc.dg/torture/pr35771-1.c: Likewise.
	* gcc.dg/torture/pr35771-2.c: Likewise.
	* gcc.dg/torture/pr35771-3.c: Likewise.
	* gcc.dg/torture/stackalign/alloca-2.c: Likewise.
	* gcc.dg/torture/stackalign/alloca-3.c: Likewise.
	* gcc.dg/torture/stackalign/push-1.c: Likewise.
	* gcc.dg/torture/stackalign/vararg-3.c: Likewise.
	* gcc.target/i386/pr39315-2.c: Likewise.
	* gcc.target/i386/pr39315-4.c: Likewise.
	* gcc.target/i386/vperm-v2df.c: Likewise.
	* gcc.target/i386/vperm-v2di.c: Likewise.
	* gcc.target/i386/vperm-v4sf-1.c: Use dg-require-effective-target
	sse_runtime.
	* gcc.target/i386/vperm-v4si-1.c: Use dg-require-effective-target
	sse2_runtime.

	libgfortran:
	* config/fpu-387.h [__sun__ && __svr4__] Include <signal.h>,
	<ucontext.h>.
	(sigill_caught): New.
	(sigill_hdlr): New function
	(has_sse) [__sun__ && __svr4__]: Check if SSE instruction causes
	SIGILL.
H.J. Lu - July 9, 2010, 2:36 p.m.
On Fri, Jul 9, 2010 at 6:22 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> My first attempts to build mainline for Solaris 8/9 x86 have just been
> using the Solaris 8 and 9 assemblers on Solaris 11.  While a couple of
> problems could be sorted out this way, actually bootstrapping found a
> couple of others.  The most pressing one is that before Solaris 9 4/04,
> the Solaris kernel doesn't save and restore SSE and SSE2 registers, so
> any attempt to execute SSE/SSE2 instructions causes the program to
> receive SIGILL, even if the CPU supports the insns:
>
> Solaris/IA32 should save/restore SSE/SSE2 register set on context switch
> http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4783204
>
> To avoid the problem, I globally default -march to pentiumpro on Solaris
> 8 and 9, not only for Solaris 8 with Sun as as in this patch:
>
>        http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01267.html
>
> but there are still two areas that must be fixed because they use
> SSE/SSE2 instructions regardless:
>
> * libgfortran determines if the CPU is capable of executing SSE
>  instructions at runtime and uses them if so.  This check is not
>  enough and caused all Fortran exectution tests both in
>  gcc/testsuite/gfortran.* and libgomp to fail.
>
> * Similarly, the SSE/SSE2/SSE3 testcases in gcc.target/i386 use the same
>  technique (cf. gcc.target/sse{, 2, 3}-check.h), and fail the same way.
>
> Unfortunately, this problem cannot easily be detected at runtime, as
> would be possible on Solaris 10+ with getisax(2), but we need to set up
> a signal handler, try some instruction, and act accordingly.
> Unfortunately, this is more involved than it may seem at first: you
> cannot simply return from a SIGILL handler after setting some flag
> variable, since the faulting instruction will be executed again, leading
> to an infinite loop.  My solution was inspired by the way GNU libsigsegv
> handles SEGV: they return from the signal handler with setcontext(2).  I
> can do the same here, provided I set set PC to the next instruction
> after the faulting one.  Therefore, I need to know exact insn lengths
> and preferably use insns with side effects that don't hurt.
>
> The meat of the patch which implements this can be found in
> libgfortran/config/fpu-387.h and gcc.target/i386/sol2-check.h.  The
> former takes care of libgfortran, the latter of all tests using
> sse-check{, 2, 3}.h.  For the few remaining testcases that hardcode
> -msse or -msse2, I need some new effective-target keywords: sse for the
> ability to compile/assemble sse insns, sse_runtime and sse2_runtime for
> the ability to execute them.
>
> With this in place, I've been able to reduce testsuite failures from
> ca. 13000 to just a handful.  There will a few unrelated followup
> patches that bring Solaris 8/9 x86 testsuite results practically en par
> with Solaris 10 and 11.
>
> Bootstrapped without regressions on i386-pc-solaris2.{8, 9, 10, 11},
> both with Sun as and GNU as.
>
> At the moment, the 4.5 branch is broken on Solaris 8/9 x86, since it
> won't even bootstrap without --with-arch=pentiumpro on Solaris 8 and 9,
> which is a regression from 4.4.  Like this patch
>
>        http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01276.html
>
> I'd like to backport the current one to the 4.4 and 4.5 branches after
> some soak time on mainline.
>
> Ok for mainline now and the 4.4 and 4.5 branches later?
>
>        Rainer
>
>
> 2010-06-14  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
>

I don't think we should make testsuite so much complex to support
old and broken Solaris. I'd rather to remove support for broken
Solaris 8/9 x86.
Rainer Orth - July 9, 2010, 2:41 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

> I don't think we should make testsuite so much complex to support
> old and broken Solaris. I'd rather to remove support for broken
> Solaris 8/9 x86.

This patch is exactly along the same lines as a previous one to check
for SSE/SSE2 support in the assembler:

	http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01276.html

Why would one accept the former and reject the corresponding runtime
tests of the latter?  And where do you see actual complexity?  The beef
of the patch is concentrated in two files (sol2-check.h and fpu-387.h)
and a single function call (sol2_check).  Agreed, the patch is large,
but mostly mechanical.

	Rainer
H.J. Lu - July 9, 2010, 3:24 p.m.
On Fri, Jul 9, 2010 at 7:41 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> I don't think we should make testsuite so much complex to support
>> old and broken Solaris. I'd rather to remove support for broken
>> Solaris 8/9 x86.
>
> This patch is exactly along the same lines as a previous one to check
> for SSE/SSE2 support in the assembler:
>
>        http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01276.html
>
> Why would one accept the former and reject the corresponding runtime
> tests of the latter?  And where do you see actual complexity?  The beef
> of the patch is concentrated in two files (sol2-check.h and fpu-387.h)
> and a single function call (sol2_check).  Agreed, the patch is large,
> but mostly mechanical.
>

Your patch makes testcase to check both sse and sse run-time.
I don't like another check in testcase for SSE.
Rainer Orth - July 9, 2010, 3:30 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

> Your patch makes testcase to check both sse and sse run-time.
> I don't like another check in testcase for SSE.

I originally meant to test in check_effective_target_sse{, 2} if the
current test is an execution test and only then perform the sse runtime
check.  Unfortunately, it doesn't seem to be possible to do this check
reliably (if at all).

On the other hand, the only tests that need to be modified by adding the
sse*_runtime effective-target keyword are those that don't use
sse*-check.h.

	Rainer
H.J. Lu - July 9, 2010, 3:54 p.m.
On Fri, Jul 9, 2010 at 8:30 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> Your patch makes testcase to check both sse and sse run-time.
>> I don't like another check in testcase for SSE.
>
> I originally meant to test in check_effective_target_sse{, 2} if the
> current test is an execution test and only then perform the sse runtime
> check.  Unfortunately, it doesn't seem to be possible to do this check
> reliably (if at all).
>
> On the other hand, the only tests that need to be modified by adding the
> sse*_runtime effective-target keyword are those that don't use
> sse*-check.h.

I would prefer to change those tests to use sse*-check.h, instead of adding
sse*_runtime.
Rainer Orth - July 9, 2010, 3:59 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

> I would prefer to change those tests to use sse*-check.h, instead of adding
> sse*_runtime.

That's certainly a possibility, but way more invasive.  I'd like to hear
other opinions before starting down that route.  We will still need
sse*_runtime for a couple of tests, though.  E.g. some fortran *.exp
files need that check.

	Rainer
H.J. Lu - July 9, 2010, 4:07 p.m.
On Fri, Jul 9, 2010 at 8:59 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> I would prefer to change those tests to use sse*-check.h, instead of adding
>> sse*_runtime.
>
> That's certainly a possibility, but way more invasive.  I'd like to hear
> other opinions before starting down that route.  We will still need
> sse*_runtime for a couple of tests, though.  E.g. some fortran *.exp
> files need that check.
>

I really don't like another SSE check for broken Solaris. We should
just drop its support.
Rainer Orth - July 9, 2010, 4:15 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

> I really don't like another SSE check for broken Solaris. We should
> just drop its support.

If you can tell me how to include a C header in a Fortran program, we
can do without ...

	Rainer
H.J. Lu - July 9, 2010, 4:29 p.m.
On Fri, Jul 9, 2010 at 9:15 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> I really don't like another SSE check for broken Solaris. We should
>> just drop its support.
>
> If you can tell me how to include a C header in a Fortran program, we
> can do without ...
>

I suggest to add your check for broken Solaris in configure and
refuse to build gcc on such platform.
Rainer Orth - July 9, 2010, 4:31 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

> I suggest to add your check for broken Solaris in configure and
> refuse to build gcc on such platform.

Because some SSE* tests fail?  Nonsense.

	Rainer
Uros Bizjak - July 9, 2010, 4:32 p.m.
On Fri, 2010-07-09 at 15:22 +0200, Rainer Orth wrote:
> My first attempts to build mainline for Solaris 8/9 x86 have just been
> using the Solaris 8 and 9 assemblers on Solaris 11.  While a couple of
> problems could be sorted out this way, actually bootstrapping found a
> couple of others.  The most pressing one is that before Solaris 9 4/04,
> the Solaris kernel doesn't save and restore SSE and SSE2 registers, so
> any attempt to execute SSE/SSE2 instructions causes the program to
> receive SIGILL, even if the CPU supports the insns:
> 
> Solaris/IA32 should save/restore SSE/SSE2 register set on context switch
> http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4783204
> 
> To avoid the problem, I globally default -march to pentiumpro on Solaris
> 8 and 9, not only for Solaris 8 with Sun as as in this patch:
> 
> 	http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01267.html
> 
> but there are still two areas that must be fixed because they use
> SSE/SSE2 instructions regardless:
> 
> * libgfortran determines if the CPU is capable of executing SSE
>   instructions at runtime and uses them if so.  This check is not
>   enough and caused all Fortran exectution tests both in
>   gcc/testsuite/gfortran.* and libgomp to fail.
> 
> * Similarly, the SSE/SSE2/SSE3 testcases in gcc.target/i386 use the same
>   technique (cf. gcc.target/sse{, 2, 3}-check.h), and fail the same way.
> 
> Unfortunately, this problem cannot easily be detected at runtime, as
> would be possible on Solaris 10+ with getisax(2), but we need to set up
> a signal handler, try some instruction, and act accordingly.
> Unfortunately, this is more involved than it may seem at first: you
> cannot simply return from a SIGILL handler after setting some flag
> variable, since the faulting instruction will be executed again, leading
> to an infinite loop.  My solution was inspired by the way GNU libsigsegv
> handles SEGV: they return from the signal handler with setcontext(2).  I
> can do the same here, provided I set set PC to the next instruction
> after the faulting one.  Therefore, I need to know exact insn lengths
> and preferably use insns with side effects that don't hurt.
> 
> The meat of the patch which implements this can be found in
> libgfortran/config/fpu-387.h and gcc.target/i386/sol2-check.h.  The
> former takes care of libgfortran, the latter of all tests using
> sse-check{, 2, 3}.h.  For the few remaining testcases that hardcode
> -msse or -msse2, I need some new effective-target keywords: sse for the
> ability to compile/assemble sse insns, sse_runtime and sse2_runtime for
> the ability to execute them.
> 
> With this in place, I've been able to reduce testsuite failures from
> ca. 13000 to just a handful.  There will a few unrelated followup
> patches that bring Solaris 8/9 x86 testsuite results practically en par
> with Solaris 10 and 11.
> 
> Bootstrapped without regressions on i386-pc-solaris2.{8, 9, 10, 11},
> both with Sun as and GNU as.
> 
> At the moment, the 4.5 branch is broken on Solaris 8/9 x86, since it
> won't even bootstrap without --with-arch=pentiumpro on Solaris 8 and 9,
> which is a regression from 4.4.  Like this patch
> 
> 	http://gcc.gnu.org/ml/gcc-patches/2010-05/msg01276.html
> 
> I'd like to backport the current one to the 4.4 and 4.5 branches after
> some soak time on mainline.
> 
> Ok for mainline now and the 4.4 and 4.5 branches later?

This patch is OK, but please commit it without sse{,2}_runtime changes.

Please prepare another incremental patch that includes sse{,2}_runtime
stuff, we will discuss your approach separatelly.

Thanks,
Uros.
Rainer Orth - July 9, 2010, 4:38 p.m.
Uros Bizjak <ubizjak@gmail.com> writes:

>> Ok for mainline now and the 4.4 and 4.5 branches later?
>
> This patch is OK, but please commit it without sse{,2}_runtime changes.

Fine, thanks.

> Please prepare another incremental patch that includes sse{,2}_runtime
> stuff, we will discuss your approach separatelly.

Ok.  To be honest, H.J.'s suggestion to use sse*-check.h as far as
possible, while more invasive, is certainly attractive since we need
only a single mechanism everywhere (well, with the exception of the few
*.exp files that decide whether or not to add -msse2 on x86).  This way,
nobody needs to worry about the sse*_runtime stuff in individual
testcases.

	Rainer
H.J. Lu - July 9, 2010, 4:48 p.m.
On Fri, Jul 9, 2010 at 9:31 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> I suggest to add your check for broken Solaris in configure and
>> refuse to build gcc on such platform.
>
> Because some SSE* tests fail?  Nonsense.
>

Will '-march=native" work on such systems?
Rainer Orth - July 9, 2010, 4:53 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

> Will '-march=native" work on such systems?

Not on Solaris 8 or older Solaris 9.  E.g. on S8, -march=native passes
-march=k8-sse3, which may break.

Will have a look, thanks.

	Rainer
H.J. Lu - July 9, 2010, 4:56 p.m.
On Fri, Jul 9, 2010 at 9:53 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> Will '-march=native" work on such systems?
>
> Not on Solaris 8 or older Solaris 9.  E.g. on S8, -march=native passes
> -march=k8-sse3, which may break.
>

If your OS doesn't support SSE, but -march=native may generate SSE
instructions, then you get a big problem.
Rainer Orth - July 9, 2010, 4:58 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

> If your OS doesn't support SSE, but -march=native may generate SSE
> instructions, then you get a big problem.

Well, only if you use -march=native ;-)  It's obviously the same problem
addressed by this patch: the presence of SSE support in the CPU is not
enough to decide if the insns can actually be used.  Same solution,
obviously.

	Rainer
H.J. Lu - July 9, 2010, 6:06 p.m.
On Fri, Jul 9, 2010 at 9:58 AM, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> If your OS doesn't support SSE, but -march=native may generate SSE
>> instructions, then you get a big problem.
>
> Well, only if you use -march=native ;-)  It's obviously the same problem
> addressed by this patch: the presence of SSE support in the CPU is not
> enough to decide if the insns can actually be used.  Same solution,
> obviously.
>

If you put this knowledge somewhere in gcc, you can use it to check SSE
support. That is "gcc -msse2" should fail to compile if SSE2 isn''t supported
by target OS.
Rainer Orth - July 9, 2010, 6:09 p.m.
"H.J. Lu" <hjl.tools@gmail.com> writes:

> If you put this knowledge somewhere in gcc, you can use it to check SSE
> support. That is "gcc -msse2" should fail to compile if SSE2 isn''t supported
> by target OS.

I don't think this makes sense: by the same logic, gcc would forbid to
create 64-bit code if the system running the compiler isn't capable of
executing the resulting code.

	Rainer
Eric Botcazou - Nov. 17, 2010, 9:30 p.m.
> 	* gnat.dg/loop_optimization7.adb: Likewise.
> 	* gnat.dg/sse_nolib.adb: Likewise.

This disabled the testcases everywhere.  You cannot use dg-require-effective 
markers in the gnat.dg testsuite since the harness will try to compile a C 
test with gnatmake and this isn't supported.

Patch

diff -r 748345bc6714 gcc/config.gcc
--- a/gcc/config.gcc	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/config.gcc	Fri Jul 09 12:16:17 2010 +0200
@@ -1253,13 +1253,10 @@ 
 	# Set default arch_32 to pentium4, tune_32 to generic like the other
 	# i386 targets, although config.guess defaults to i386-pc-solaris2*.
 	case ${target} in
-	*-*-solaris2.8*)
-		if test x$gas = xyes; then
-			with_arch_32=${with_arch_32:-pentium4}
-		else
-			# Solaris 8/x86 as cannot handle sse2.
-			with_arch_32=${with_arch_32:-pentiumpro}
-		fi
+	*-*-solaris2.[89]*)
+		# Solaris 8 and 9/x86 cannot execute SSE/SSE2 instructions by
+		# default.
+		with_arch_32=${with_arch_32:-pentiumpro}
 		;;
 	*)
 		with_arch_32=${with_arch_32:-pentium4}
diff -r 748345bc6714 gcc/doc/install.texi
--- a/gcc/doc/install.texi	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/doc/install.texi	Fri Jul 09 12:16:17 2010 +0200
@@ -2898,6 +2898,8 @@ 
 @item
 @uref{#ix86-x-linux,,i?86-*-linux*}
 @item
+@uref{#ix86-x-solaris289,,i?86-*-solaris2.[89]}
+@item
 @uref{#ix86-x-solaris210,,i?86-*-solaris2.10}
 @item
 @uref{#ia64-x-linux,,ia64-*-linux}
@@ -3473,6 +3475,26 @@ 
 @html
 <hr />
 @end html
+@heading @anchor{ix86-x-solaris289}i?86-*-solaris2.[89]
+The Sun assembler in Solaris 8 and 9 has several bugs and limitations.
+While GCC works around them, several features are missing, so it is
+@c FIXME: which ones?
+recommended to use the GNU assembler instead.  There is no bundled
+version, but the current version, from GNU binutils 2.20.1, is known to
+work.
+
+Solaris~2/x86 doesn't support the execution of SSE/SSE2 instructions
+before Solaris~9 4/04, even if the CPU supports them.  Programs will
+receive @code{SIGILL} if they try.  The fix is available both in
+Solaris~9 Update~6 and kernel patch 112234-12 or newer.  There is no
+corresponding patch for Solaris 8.  To avoid this problem,
+@option{-march} defaults to @samp{pentiumpro} on Solaris 8 and 9.  If
+you have the patch installed, you can configure GCC with an appropriate
+@option{--with-arch} option, but need GNU @command{as} for SSE2 support.
+
+@html
+<hr />
+@end html
 @heading @anchor{ix86-x-solaris210}i?86-*-solaris2.10
 Use this for Solaris 10 or later on x86 and x86-64 systems.  This
 configuration is supported by GCC 4.0 and later versions only.  Unlike
diff -r 748345bc6714 gcc/doc/sourcebuild.texi
--- a/gcc/doc/sourcebuild.texi	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/doc/sourcebuild.texi	Fri Jul 09 12:16:17 2010 +0200
@@ -1604,9 +1604,18 @@ 
 @item hard_float
 Target supports FPU instructions.
 
+@item sse
+Target supports compiling @code{sse} instructions.
+
+@item sse_runtime
+Target supports the execution of @code{sse} instructions.
+
 @item sse2
 Target supports compiling @code{sse2} instructions.
 
+@item sse2_runtime
+Target supports the execution of @code{sse2} instructions.
+
 @item sync_char_short
 Target supports atomic operations on @code{char} and @code{short}.
 
diff -r 748345bc6714 gcc/testsuite/g++.dg/debug/dwarf2/const2b.C
--- a/gcc/testsuite/g++.dg/debug/dwarf2/const2b.C	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/const2b.C	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile { target i386*-*-* } } */
 /* { dg-options "-O -gdwarf-2 -dA -msse" } */
+/* { dg-require-effective-target sse } */
 /* { dg-final { scan-assembler "DW_AT_const_value" } } */
 
 typedef float FloatVect __attribute__((__vector_size__(16)));
diff -r 748345bc6714 gcc/testsuite/g++.dg/ext/vector14.C
--- a/gcc/testsuite/g++.dg/ext/vector14.C	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/g++.dg/ext/vector14.C	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 // PR c++/35758
 // { dg-do compile }
-// { dg-options "-msse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+// { dg-options "-msse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
+// { dg-require-effective-target sse }
 // Ignore warning on some powerpc-linux configurations.
 // { dg-prune-output "non-standard ABI extension" }
 // { dg-prune-output "mangled name" }
diff -r 748345bc6714 gcc/testsuite/g++.dg/other/i386-1.C
--- a/gcc/testsuite/g++.dg/other/i386-1.C	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/g++.dg/other/i386-1.C	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do run { target i?86-*-* x86_64-*-* } } */
 /* { dg-options "-msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include <xmmintrin.h>
 
diff -r 748345bc6714 gcc/testsuite/g++.dg/other/mmintrin.C
--- a/gcc/testsuite/g++.dg/other/mmintrin.C	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/g++.dg/other/mmintrin.C	Fri Jul 09 12:16:17 2010 +0200
@@ -1,4 +1,5 @@ 
 // { dg-do compile { target i?86-*-* x86_64-*-* } }
 // { dg-options "-msse" }
+// { dg-require-effective-target sse }
 
 #include <xmmintrin.h>
diff -r 748345bc6714 gcc/testsuite/g++.dg/other/pr40446.C
--- a/gcc/testsuite/g++.dg/other/pr40446.C	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/g++.dg/other/pr40446.C	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 // { dg-do run { target i?86-*-* x86_64-*-* } }
 // { dg-options "-O1 -msse2" }
 // { dg-require-effective-target sse2 }
+// { dg-require-effective-target sse2_runtime }
 
 #include <emmintrin.h>
 #include "cpuid.h"
diff -r 748345bc6714 gcc/testsuite/gcc.dg/20020418-1.c
--- a/gcc/testsuite/gcc.dg/20020418-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/20020418-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
 /* { dg-options "-O2 -msse -ffast-math" { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target sse { target i?86-*-* x86_64-*-* } } */
 
 void bar (float *a, float *b);
 
diff -r 748345bc6714 gcc/testsuite/gcc.dg/compat/union-m128-1_main.c
--- a/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-skip-if "test SSE2 support" { ! { i?86-*-* x86_64-*-* } } } */
 /* { dg-options "-O" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include "cpuid.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.dg/compat/vector-1a_main.c
--- a/gcc/testsuite/gcc.dg/compat/vector-1a_main.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/compat/vector-1a_main.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-skip-if "test SSE2 vector" { ! { i?86-*-* x86_64-*-* } } } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 /* Test compatibility of vector types: layout between separately-compiled
    modules, parameter passing, and function return.  This test uses
diff -r 748345bc6714 gcc/testsuite/gcc.dg/compat/vector-2a_main.c
--- a/gcc/testsuite/gcc.dg/compat/vector-2a_main.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/compat/vector-2a_main.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-skip-if "test SSE2 support" { ! { i?86-*-* x86_64-*-* } } } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 /* Test compatibility of vector types: layout between separately-compiled
    modules, parameter passing, and function return.  This test uses
diff -r 748345bc6714 gcc/testsuite/gcc.dg/debug/dwarf2/const-2b.c
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/const-2b.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/const-2b.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile { target i386*-*-* } } */
 /* { dg-options "-O -gdwarf-2 -dA -msse" } */
+/* { dg-require-effective-target sse } */
 /* { dg-final { scan-assembler "DW_AT_const_value" } } */
 
 typedef float FloatVect __attribute__((__vector_size__(16)));
diff -r 748345bc6714 gcc/testsuite/gcc.dg/format/ms_unnamed-1.c
--- a/gcc/testsuite/gcc.dg/format/ms_unnamed-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/format/ms_unnamed-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -3,6 +3,7 @@ 
 /* { dg-do compile { target { *-*-mingw* } } } */
 /* { dg-options "-Wformat" } */
 /* { dg-options "-Wformat -msse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target sse { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 #define USE_SYSTEM_FORMATS
 #include "format.h"
diff -r 748345bc6714 gcc/testsuite/gcc.dg/format/unnamed-1.c
--- a/gcc/testsuite/gcc.dg/format/unnamed-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/format/unnamed-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -3,6 +3,7 @@ 
 /* { dg-do compile } */
 /* { dg-options "-Wformat" } */
 /* { dg-options "-Wformat -msse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target sse { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 
 #include "format.h"
@@ -20,5 +21,5 @@ 
 {
   printf("%d", x); /* { dg-warning "expects type" } */
   printf("%d", 141592653589793238462643383279502884197169399375105820974944); /* { dg-warning "expects type" } */
-  /* { dg-warning "unsigned only|too large" "constant" { target *-*-* } 22 } */
+  /* { dg-warning "unsigned only|too large" "constant" { target *-*-* } 23 } */
 }
diff -r 748345bc6714 gcc/testsuite/gcc.dg/graphite/pr40281.c
--- a/gcc/testsuite/gcc.dg/graphite/pr40281.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/graphite/pr40281.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O -fprefetch-loop-arrays -w" } */
 /* { dg-options "-O -fprefetch-loop-arrays -march=i686 -msse -w" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target sse { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 void foo(int);
 void bar(int n)
diff -r 748345bc6714 gcc/testsuite/gcc.dg/pr32176.c
--- a/gcc/testsuite/gcc.dg/pr32176.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/pr32176.c	Fri Jul 09 12:16:17 2010 +0200
@@ -3,6 +3,7 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2 -fprefetch-loop-arrays -w" } */
 /* { dg-options "-O2 -fprefetch-loop-arrays -march=i686 -msse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target sse { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 void foo (void)
 {
diff -r 748345bc6714 gcc/testsuite/gcc.dg/pr36584.c
--- a/gcc/testsuite/gcc.dg/pr36584.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/pr36584.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-options "-O2 -lm" } */
 /* { dg-options "-O2 -msse2 -mfpmath=sse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 /* { dg-require-effective-target sse2 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target sse2_runtime { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 #ifdef __i386__
 #include "cpuid.h"
diff -r 748345bc6714 gcc/testsuite/gcc.dg/pr37544.c
--- a/gcc/testsuite/gcc.dg/pr37544.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/pr37544.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-options "-O2" } */
 /* { dg-options "-O2 -msse2 -mtune=core2 -mfpmath=387" { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-require-effective-target sse2 { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-require-effective-target sse2_runtime { target { i?86-*-* x86_64-*-* } } } */
 
 #ifdef __i386__
 #include "cpuid.h"
diff -r 748345bc6714 gcc/testsuite/gcc.dg/pr40550.c
--- a/gcc/testsuite/gcc.dg/pr40550.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/pr40550.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-msse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target sse { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 #ifdef __i386__
 #include "cpuid.h"
diff -r 748345bc6714 gcc/testsuite/gcc.dg/prefetch-loop-arrays-1.c
--- a/gcc/testsuite/gcc.dg/prefetch-loop-arrays-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/prefetch-loop-arrays-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2 -fprefetch-loop-arrays -w" } */
 /* { dg-options "-O2 -fprefetch-loop-arrays -march=i686 -msse -w" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target sse { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 __extension__ typedef __SIZE_TYPE__ size_t;
 
diff -r 748345bc6714 gcc/testsuite/gcc.dg/torture/pr16104-1.c
--- a/gcc/testsuite/gcc.dg/torture/pr16104-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/torture/pr16104-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-do run { target i?86-*-* x86_64-*-* } } */
 /* { dg-options "-msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include "cpuid.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.dg/torture/pr35771-1.c
--- a/gcc/testsuite/gcc.dg/torture/pr35771-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/torture/pr35771-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do run { target i?86-*-* x86_64-*-* } } */
 /* { dg-options "-msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
 
diff -r 748345bc6714 gcc/testsuite/gcc.dg/torture/pr35771-2.c
--- a/gcc/testsuite/gcc.dg/torture/pr35771-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/torture/pr35771-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do run { target i?86-*-* x86_64-*-* } } */
 /* { dg-options "-msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 typedef double __m128d __attribute__ ((__vector_size__ (16), __may_alias__));
 
diff -r 748345bc6714 gcc/testsuite/gcc.dg/torture/pr35771-3.c
--- a/gcc/testsuite/gcc.dg/torture/pr35771-3.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/torture/pr35771-3.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do run { target i?86-*-* x86_64-*-* } } */
 /* { dg-options "-msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
 
diff -r 748345bc6714 gcc/testsuite/gcc.dg/torture/pr36891.c
--- a/gcc/testsuite/gcc.dg/torture/pr36891.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/torture/pr36891.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do compile } */
 /* { dg-options "-ffast-math" } */
 /* { dg-options "-ffast-math -msse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-require-effective-target sse { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 
 #define __vector __attribute__((vector_size(16) ))
 __vector float f(void);
diff -r 748345bc6714 gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c
--- a/gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 /* { dg-options "-msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include <emmintrin.h>
 #include "cpuid.h"
diff -r 748345bc6714 gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c
--- a/gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-3.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 /* { dg-options "-msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include <emmintrin.h>
 #include "cpuid.h"
diff -r 748345bc6714 gcc/testsuite/gcc.dg/torture/stackalign/push-1.c
--- a/gcc/testsuite/gcc.dg/torture/stackalign/push-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/push-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 /* { dg-options "-msse2 -mpreferred-stack-boundary=2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include <emmintrin.h>
 #include "cpuid.h"
diff -r 748345bc6714 gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c
--- a/gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/vararg-3.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
 /* { dg-options "-msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include <stdarg.h>
 #include <emmintrin.h>
diff -r 748345bc6714 gcc/testsuite/gcc.dg/vect/tree-vect.h
--- a/gcc/testsuite/gcc.dg/vect/tree-vect.h	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.dg/vect/tree-vect.h	Fri Jul 09 12:16:17 2010 +0200
@@ -41,6 +41,11 @@ 
     want_level = 1, want_c = bit_SSSE3, want_d = 0;
 # else
     want_level = 1, want_c = 0, want_d = bit_SSE2;
+#  if defined(__sun__) && defined(__svr4__)
+    /* Before Solaris 9 4/04, trying to execute an SSE2 instruction gives
+       SIGILL even if the CPU can handle them.  */
+    asm volatile ("unpcklpd %xmm0,%xmm2");
+#  endif
 # endif
 
     if (!__get_cpuid (want_level, &a, &b, &c, &d)
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/20020218-1.c
--- a/gcc/testsuite/gcc.target/i386/20020218-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/20020218-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* Verify that X86-64 only SSE registers aren't restored on IA-32.  */
 /* { dg-do compile } */
 /* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target sse } */
 /* { dg-options "-O2 -msse" } */
 /* { dg-final { scan-assembler-not "xmm8" } } */
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/20020523.c
--- a/gcc/testsuite/gcc.target/i386/20020523.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/20020523.c	Fri Jul 09 12:16:17 2010 +0200
@@ -4,6 +4,7 @@ 
 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse -mfpmath=sse -ffast-math" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/abi-1.c
--- a/gcc/testsuite/gcc.target/i386/abi-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/abi-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* Make certain that we pass V2DF in the correct register for SSE1.  */
 /* { dg-do compile } */
 /* { dg-options "-O1 -msse -mno-sse2" } */
+/* { dg-require-effective-target sse } */
 
 typedef double v2df __attribute__((vector_size (16)));
 v2df foo (void) { return (v2df){ 1.0, 2.0 }; }
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/brokensqrt.c
--- a/gcc/testsuite/gcc.target/i386/brokensqrt.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/brokensqrt.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -ffast-math -msse -mfpmath=sse -mrecip" } */
+/* { dg-require-effective-target sse } */
 #include "sse-check.h"
 
 extern float sqrtf (float);
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/fastcall-sseregparm.c
--- a/gcc/testsuite/gcc.target/i386/fastcall-sseregparm.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/fastcall-sseregparm.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-mpreferred-stack-boundary=4 -msse" } */
 /* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/math-torture/math-torture.exp
--- a/gcc/testsuite/gcc.target/i386/math-torture/math-torture.exp	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/math-torture/math-torture.exp	Fri Jul 09 12:16:17 2010 +0200
@@ -28,19 +28,23 @@ 
 set MATH_TORTURE_OPTIONS [list \
         { -O0 } \
         { -O0 -mfpmath=387 } \
+        { -O0 -mfpmath=387 -ffast-math } \
+        { -O2 } \
+        { -O2 -mfpmath=387 } \
+        { -O2 -mfpmath=387 -ffast-math } \
+]
+
+if { [check_effective_target_sse] } {
+    lappend MATH_TORTURE_OPTIONS \
         { -O0 -msse -mno-sse2 -mfpmath=sse } \
         { -O0 -msse -mno-sse2 -mfpmath=sse,387 } \
-        { -O0 -mfpmath=387 -ffast-math } \
         { -O0 -msse -mno-sse2 -mfpmath=sse -ffast-math } \
         { -O0 -msse -mno-sse2 -mfpmath=sse,387 -ffast-math } \
-        { -O2 } \
-        { -O2 -mfpmath=387 } \
         { -O2 -msse -mno-sse2 -mfpmath=sse } \
         { -O2 -msse -mno-sse2 -mfpmath=sse,387 } \
-        { -O2 -mfpmath=387 -ffast-math } \
         { -O2 -msse -mno-sse2 -mfpmath=sse -ffast-math } \
         { -O2 -msse -mno-sse2 -mfpmath=sse,387 -ffast-math } \
-]
+}
 
 if { [check_effective_target_sse2] } {
     lappend MATH_TORTURE_OPTIONS \
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr13366.c
--- a/gcc/testsuite/gcc.target/i386/pr13366.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr13366.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include <xmmintrin.h>
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr13685.c
--- a/gcc/testsuite/gcc.target/i386/pr13685.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr13685.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* PR target/13685 */
 /* { dg-do run } */
 /* { dg-options "-Os -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr24306.c
--- a/gcc/testsuite/gcc.target/i386/pr24306.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr24306.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-msse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr31486.c
--- a/gcc/testsuite/gcc.target/i386/pr31486.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr31486.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-msse -mno-sse2" } */
+/* { dg-require-effective-target sse } */
 
 typedef double __v2df __attribute__ ((vector_size (16)));
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr32065-1.c
--- a/gcc/testsuite/gcc.target/i386/pr32065-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr32065-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-require-effective-target dfp } */
+/* { dg-require-effective-target sse } */
 /* { dg-options "-msse -std=gnu99" } */
 
 _Decimal128 test (void)
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr32065-2.c
--- a/gcc/testsuite/gcc.target/i386/pr32065-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr32065-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-require-effective-target dfp } */
+/* { dg-require-effective-target sse } */
 /* { dg-options "-Os -msse -std=gnu99" } */
 
 #include "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr32389.c
--- a/gcc/testsuite/gcc.target/i386/pr32389.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr32389.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 
 /* { dg-do compile } */
 /* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target sse } */
 /* { dg-options "-msse" } */
 
 double f1();
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr38824.c
--- a/gcc/testsuite/gcc.target/i386/pr38824.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr38824.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 typedef float v4sf __attribute__ ((__vector_size__ (16)));
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr38931.c
--- a/gcc/testsuite/gcc.target/i386/pr38931.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr38931.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 typedef int __m64 __attribute__ ((__vector_size__ (8)));
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr39315-2.c
--- a/gcc/testsuite/gcc.target/i386/pr39315-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr39315-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O -msse2 -mtune=generic" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 /* { dg-additional-sources pr39315-check.c } */
 
 typedef float __m128 __attribute__ ((__vector_size__ (16)));
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr39315-4.c
--- a/gcc/testsuite/gcc.target/i386/pr39315-4.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr39315-4.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O -msse2 -mtune=generic" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 /* { dg-additional-sources pr39315-check.c } */
 
 typedef float __m128 __attribute__ ((__vector_size__ (16)));
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr39592-1.c
--- a/gcc/testsuite/gcc.target/i386/pr39592-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr39592-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,7 @@ 
    39592.  */
 /* { dg-do compile } */
 /* { dg-options "-ansi -msse" } */
+/* { dg-require-effective-target sse } */
 
 double
 foo (unsigned long var)
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/pr43766.c
--- a/gcc/testsuite/gcc.target/i386/pr43766.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/pr43766.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
 /* { dg-options "-O2 -msse -mregparm=3" { target ilp32 } } */
+/* { dg-require-effective-target sse } */
 
 void p (int *a, int i)
 {
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/recip-divf.c
--- a/gcc/testsuite/gcc.target/i386/recip-divf.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/recip-divf.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2 -ffast-math -msse -mfpmath=sse -mrecip" } */
+/* { dg-require-effective-target sse } */
 
 float t1(float a, float b)
 {
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/recip-sqrtf.c
--- a/gcc/testsuite/gcc.target/i386/recip-sqrtf.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/recip-sqrtf.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2 -ffast-math -msse -mfpmath=sse -mrecip" } */
+/* { dg-require-effective-target sse } */
 
 extern float sqrtf (float);
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/recip-vec-divf.c
--- a/gcc/testsuite/gcc.target/i386/recip-vec-divf.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/recip-vec-divf.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2 -ffast-math -ftree-vectorize -msse -mfpmath=sse -mrecip" } */
+/* { dg-require-effective-target sse } */
 
 float a[16];
 float b[16];
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/recip-vec-sqrtf.c
--- a/gcc/testsuite/gcc.target/i386/recip-vec-sqrtf.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/recip-vec-sqrtf.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2 -ffast-math -ftree-vectorize -msse -mfpmath=sse -mrecip" } */
+/* { dg-require-effective-target sse } */
 
 float a[16];
 float b[16];
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sol2-check.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/testsuite/gcc.target/i386/sol2-check.h	Fri Jul 09 12:16:17 2010 +0200
@@ -0,0 +1,48 @@ 
+#if defined(__sun__) && defined(__svr4__)
+/* Make sure sigaction() is declared even with -std=c99.  */
+#define __EXTENSIONS__
+#include <signal.h>
+#include <ucontext.h>
+
+static volatile sig_atomic_t sigill_caught;
+
+static void
+sigill_hdlr (int sig __attribute((unused)),
+	     siginfo_t *sip __attribute__((unused)),
+	     ucontext_t *ucp)
+{
+  sigill_caught = 1;
+  /* Set PC to the instruction after the faulting one to skip over it,
+     otherwise we enter an infinite loop.  */
+  ucp->uc_mcontext.gregs[EIP] += ILL_INSN_LEN;
+  setcontext (ucp);
+}
+#endif
+
+/* Solaris 2 before Solaris 9 4/04 cannot execute SSE/SSE2 instructions
+   even if the CPU supports them.  Programs receive SIGILL instead, so
+   check for that at runtime.  */
+static int
+sol2_check (void)
+{
+#if defined(__sun__) && defined(__svr4__)
+  struct sigaction act, oact;
+
+  act.sa_handler = sigill_hdlr;
+  sigemptyset (&act.sa_mask);
+  /* Need to set SA_SIGINFO so a ucontext_t * is passed to the handler.  */
+  act.sa_flags = SA_SIGINFO;
+  sigaction (SIGILL, &act, &oact);
+
+  ILL_INSN;
+
+  sigaction (SIGILL, &oact, NULL);
+
+  if (sigill_caught)
+    exit (0);
+  else
+    return 1;
+#else
+  return 1;
+#endif /* __sun__ && __svr4__ */
+}
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* PR 12902 */
 /* { dg-do compile } */
 /* { dg-options "-O1 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include <xmmintrin.h>
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-16.c
--- a/gcc/testsuite/gcc.target/i386/sse-16.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-16.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O0 -msse" } */
+/* { dg-require-effective-target sse } */
 
 typedef float __vr __attribute__ ((vector_size (16)));
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O3 -msse" } */
+/* { dg-require-effective-target sse } */
 #include <xmmintrin.h>
 static const __m128 v_sign = {-.0f, -.0f, -.0f, -.0f};
 static const __m128 v_half = {0.5f, 0.5f, 0.5f, 0.5f};
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-20.c
--- a/gcc/testsuite/gcc.target/i386/sse-20.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-20.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* PR target/13685 */
 /* { dg-options "-Os -msse" } */
+/* { dg-require-effective-target sse } */
 
 typedef float __m128 __attribute__ ((vector_size (16)));
 typedef int __m64 __attribute__ ((vector_size (8)));
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-3.c
--- a/gcc/testsuite/gcc.target/i386/sse-3.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-3.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* PR target/21149 */
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-7.c
--- a/gcc/testsuite/gcc.target/i386/sse-7.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-7.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-9.c
--- a/gcc/testsuite/gcc.target/i386/sse-9.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-9.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-addps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-addps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-addps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-addss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-addss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-addss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-andnps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-andnps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-andnps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-andps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-andps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-andps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-check.h
--- a/gcc/testsuite/gcc.target/i386/sse-check.h	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-check.h	Fri Jul 09 12:16:17 2010 +0200
@@ -1,9 +1,14 @@ 
-#include <stdio.h>
 #include <stdlib.h>
 #include "m128-check.h"
 
 #include "cpuid.h"
 
+/* We need a single SSE instruction here so the handler can safely skip
+   over it.  */
+#define ILL_INSN __asm__ volatile ("movss %xmm2,%xmm1")
+#define ILL_INSN_LEN 4
+#include "sol2-check.h"
+
 static void sse_test (void);
 
 static void
@@ -22,7 +27,7 @@ 
     return 0;
 
   /* Run SSE test only if host has SSE support.  */
-  if (edx & bit_SSE)
+  if ((edx & bit_SSE) && sol2_check ())
     do_test ();
 
   return 0;
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-cmpss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-cmpss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-cmpss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse -std=c99" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-comiss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-comiss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-comiss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-comiss-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-comiss-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-comiss-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-comiss-3.c
--- a/gcc/testsuite/gcc.target/i386/sse-comiss-3.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-comiss-3.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-comiss-4.c
--- a/gcc/testsuite/gcc.target/i386/sse-comiss-4.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-comiss-4.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-comiss-5.c
--- a/gcc/testsuite/gcc.target/i386/sse-comiss-5.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-comiss-5.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-comiss-6.c
--- a/gcc/testsuite/gcc.target/i386/sse-comiss-6.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-comiss-6.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-copysignf-vec.c
--- a/gcc/testsuite/gcc.target/i386/sse-copysignf-vec.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-copysignf-vec.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -ftree-vectorize -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-cvtsi2ss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-cvtsi2ss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-cvtsi2ss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-cvtsi2ss-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-cvtsi2ss-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-cvtsi2ss-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target sse } */
 /* { dg-options "-O2 -msse" } */
 
 #ifndef CHECK_H
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-cvtss2si-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-cvtss2si-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-cvtss2si-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-cvtss2si-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-cvtss2si-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-cvtss2si-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target sse } */
 /* { dg-options "-O2 -msse" } */
 
 #ifndef CHECK_H
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-cvttss2si-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-cvttss2si-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-cvttss2si-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-cvttss2si-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-cvttss2si-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-cvttss2si-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target sse } */
 /* { dg-options "-O2 -msse" } */
 
 #ifndef CHECK_H
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-divps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-divps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-divps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-divss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-divss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-divss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-init-v4hi-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-init-v4hi-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-init-v4hi-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-init-v4sf-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-init-v4sf-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-init-v4sf-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-maxps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-maxps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-maxps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-maxss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-maxss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-maxss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-minps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-minps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-minps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-minss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-minss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-minss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movaps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-movaps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movaps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movaps-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-movaps-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movaps-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movhlps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-movhlps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movhlps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movhps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-movhps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movhps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movhps-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-movhps-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movhps-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movlhps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-movlhps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movlhps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movmskps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-movmskps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movmskps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movntps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-movntps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movntps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-movss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movss-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-movss-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movss-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movss-3.c
--- a/gcc/testsuite/gcc.target/i386/sse-movss-3.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movss-3.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movups-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-movups-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movups-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-movups-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-movups-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-movups-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-mulps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-mulps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-mulps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-mulss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-mulss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-mulss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-orps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-orps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-orps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-rcpps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-rcpps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-rcpps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-recip-vec.c
--- a/gcc/testsuite/gcc.target/i386/sse-recip-vec.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-recip-vec.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -ffast-math -ftree-vectorize -msse -mfpmath=sse -mrecip" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-recip.c
--- a/gcc/testsuite/gcc.target/i386/sse-recip.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-recip.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -ffast-math -msse -mfpmath=sse -mrecip" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-rsqrtps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-rsqrtps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-rsqrtps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-set-ps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-set-ps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-set-ps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-sqrtps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-sqrtps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-sqrtps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-subps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-subps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-subps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-subss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-subss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-subss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-ucomiss-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-ucomiss-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-ucomiss-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-ucomiss-2.c
--- a/gcc/testsuite/gcc.target/i386/sse-ucomiss-2.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-ucomiss-2.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-ucomiss-3.c
--- a/gcc/testsuite/gcc.target/i386/sse-ucomiss-3.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-ucomiss-3.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-ucomiss-4.c
--- a/gcc/testsuite/gcc.target/i386/sse-ucomiss-4.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-ucomiss-4.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-ucomiss-5.c
--- a/gcc/testsuite/gcc.target/i386/sse-ucomiss-5.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-ucomiss-5.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-ucomiss-6.c
--- a/gcc/testsuite/gcc.target/i386/sse-ucomiss-6.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-ucomiss-6.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-unpckhps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-unpckhps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-unpckhps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-unpcklps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-unpcklps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-unpcklps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse-xorps-1.c
--- a/gcc/testsuite/gcc.target/i386/sse-xorps-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse-xorps-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse" } */
+/* { dg-require-effective-target sse } */
 
 #ifndef CHECK_H
 #define CHECK_H "sse-check.h"
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse2-check.h
--- a/gcc/testsuite/gcc.target/i386/sse2-check.h	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse2-check.h	Fri Jul 09 12:16:17 2010 +0200
@@ -2,6 +2,12 @@ 
 #include "cpuid.h"
 #include "m128-check.h"
 
+/* We need a single SSE2 instruction here so the handler can safely skip
+   over it.  */
+#define ILL_INSN __asm__ volatile ("unpcklpd %xmm0,%xmm2")
+#define ILL_INSN_LEN 4
+#include "sol2-check.h"
+
 static void sse2_test (void);
 
 static void
@@ -20,7 +26,7 @@ 
     return 0;
 
   /* Run SSE2 test only if host has SSE2 support.  */
-  if (edx & bit_SSE2)
+  if ((edx & bit_SSE2) && sol2_check ())
     do_test ();
 
   return 0;
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sse3-check.h
--- a/gcc/testsuite/gcc.target/i386/sse3-check.h	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sse3-check.h	Fri Jul 09 12:16:17 2010 +0200
@@ -3,6 +3,12 @@ 
 
 #include "cpuid.h"
 
+/* We need a single SSE3 instruction here so the handler can safely skip
+   over it.  */
+#define ILL_INSN __asm__ volatile ("movddup %xmm1,%xmm2")
+#define ILL_INSN_LEN 4
+#include "sol2-check.h"
+
 static void sse3_test (void);
 
 static void
@@ -21,7 +27,7 @@ 
     return 0;
  
   /* Run SSE3 test only if host has SSE3 support.  */
-  if (ecx & bit_SSE3)
+  if ((ecx & bit_SSE3) && sol2_check ())
     do_test ();
 
   return 0;
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/ssefn-1.c
--- a/gcc/testsuite/gcc.target/i386/ssefn-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/ssefn-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -3,6 +3,7 @@ 
 
 /* { dg-do compile } */
 /* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target sse } */
 /* { dg-final { scan-assembler "movss" } } */
 /* { dg-final { scan-assembler "mulss" } } */
 /* { dg-final { scan-assembler-not "movsd" } } */
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/ssefn-3.c
--- a/gcc/testsuite/gcc.target/i386/ssefn-3.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/ssefn-3.c	Fri Jul 09 12:16:17 2010 +0200
@@ -3,6 +3,7 @@ 
 
 /* { dg-do run } */
 /* { dg-options "-O2 -msse -mfpmath=sse" } */
+/* { dg-require-effective-target sse } */
 
 #include "sse-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/sseregparm-1.c
--- a/gcc/testsuite/gcc.target/i386/sseregparm-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/sseregparm-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2 -msse" } */
 /* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target sse } */
 
 float essef(float) __attribute__((sseregparm));
 double essed(double) __attribute__((sseregparm));
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/stackalign/return-3.c
--- a/gcc/testsuite/gcc.target/i386/stackalign/return-3.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/stackalign/return-3.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do compile } */
 /* { dg-skip-if "" { ! { ilp32 && dfp } } { "*" } { "" } } */
 /* { dg-options "-msse -std=gnu99 -mpreferred-stack-boundary=2" } */
+/* { dg-require-effective-target sse } */
 
 /* This compile only test is to detect an assertion failure in stack branch
    development.  */
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/vectorize1.c
--- a/gcc/testsuite/gcc.target/i386/vectorize1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/vectorize1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 /* PR middle-end/28915 */
 /* { dg-options "-msse -O2 -ftree-vectorize -fdump-tree-vect" } */
+/* { dg-require-effective-target sse } */
 
 extern char lanip[3][40];
 typedef struct
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/vperm-v2df.c
--- a/gcc/testsuite/gcc.target/i386/vperm-v2df.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/vperm-v2df.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O -msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include "isa-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/vperm-v2di.c
--- a/gcc/testsuite/gcc.target/i386/vperm-v2di.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/vperm-v2di.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O -msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include "isa-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c
--- a/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O -msse" } */
+/* { dg-require-effective-target sse } */
+/* { dg-require-effective-target sse_runtime } */
 
 #include "isa-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/vperm-v4si-1.c
--- a/gcc/testsuite/gcc.target/i386/vperm-v4si-1.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/vperm-v4si-1.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* { dg-do run } */
 /* { dg-options "-O -msse2" } */
 /* { dg-require-effective-target sse2 } */
+/* { dg-require-effective-target sse2_runtime } */
 
 #include "isa-check.h"
 
diff -r 748345bc6714 gcc/testsuite/gcc.target/i386/xorps-sse.c
--- a/gcc/testsuite/gcc.target/i386/xorps-sse.c	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gcc.target/i386/xorps-sse.c	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 /* Test that we generate xorps instruction when pxor is not available.  */
 /* { dg-do compile } */
 /* { dg-options "-O -msse -mno-sse2" } */
+/* { dg-require-effective-target sse } */
 /* { dg-final { scan-assembler "xorps\[ \t\]" } } */
 
 #define vector __attribute__ ((vector_size (16)))
diff -r 748345bc6714 gcc/testsuite/gfortran.dg/pr28158.f90
--- a/gcc/testsuite/gfortran.dg/pr28158.f90	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gfortran.dg/pr28158.f90	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 ! { dg-do compile { target i?86-*-* x86_64-*-* } }
 ! { dg-require-effective-target ilp32 }
 ! { dg-options "-O -msse -mfpmath=sse" }
+! { dg-require-effective-target sse }
     subroutine yhalf(z)
     complex cdexpj,z
     z=cdexpj((0.d0,1.d0)*z)
diff -r 748345bc6714 gcc/testsuite/gfortran.dg/pr30667.f
--- a/gcc/testsuite/gfortran.dg/pr30667.f	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gfortran.dg/pr30667.f	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 ! { dg-do compile { target i?86-*-* x86_64-*-* } }
 ! { dg-require-effective-target ilp32 }
 ! { dg-options "-O2 -msse -ftree-vectorize" }
+! { dg-require-effective-target sse } 
       subroutine cblank_cvb(a,ndim)
       character*(*) a
       character*1 blank
diff -r 748345bc6714 gcc/testsuite/gfortran.dg/vect/vect.exp
--- a/gcc/testsuite/gfortran.dg/vect/vect.exp	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gfortran.dg/vect/vect.exp	Fri Jul 09 12:16:17 2010 +0200
@@ -68,7 +68,8 @@ 
 } elseif { [istarget  "spu-*-*"] } {
    set dg-do-what-default run
 } elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
-    if { ![check_effective_target_sse2] } then {
+    if { ![check_effective_target_sse2]
+	 || ![check_effective_target_sse2_runtime]} then {
 	return
     }
     lappend DEFAULT_VECTCFLAGS "-msse2"
diff -r 748345bc6714 gcc/testsuite/gnat.dg/loop_optimization7.adb
--- a/gcc/testsuite/gnat.dg/loop_optimization7.adb	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gnat.dg/loop_optimization7.adb	Fri Jul 09 12:16:17 2010 +0200
@@ -1,6 +1,7 @@ 
 -- { dg-do compile }
 -- { dg-options "-O3" }
 -- { dg-options "-O3 -msse" { target i?86-*-* x86_64-*-* } }
+-- { dg-require-effective-target sse } 
 
 package body Loop_Optimization7 is
 
diff -r 748345bc6714 gcc/testsuite/gnat.dg/sse_nolib.adb
--- a/gcc/testsuite/gnat.dg/sse_nolib.adb	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/gnat.dg/sse_nolib.adb	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,6 @@ 
 --  { dg-do run { target i?86-*-* x86_64-*-* } }
 --  { dg-options "-O1 -msse" }
+--  { dg-require-effective-target sse } 
 
 with Ada.Unchecked_Conversion;
 
diff -r 748345bc6714 gcc/testsuite/lib/fortran-torture.exp
--- a/gcc/testsuite/lib/fortran-torture.exp	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/lib/fortran-torture.exp	Fri Jul 09 12:16:17 2010 +0200
@@ -46,7 +46,8 @@ 
 	set test_tree_vectorize 1
     } elseif { ( [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] )
 	       && [check_effective_target_sse2]
-	       && [check_sse2_hw_available] } {
+	       && [check_sse2_hw_available]
+	       && [check_effective_target_sse2_runtime] } {
 	lappend vectorizer_options "-msse2"
 	set test_tree_vectorize 1
     } elseif { [istarget "mips*-*-*"]
diff -r 748345bc6714 gcc/testsuite/lib/target-supports.exp
--- a/gcc/testsuite/lib/target-supports.exp	Fri Jul 09 12:08:21 2010 +0200
+++ b/gcc/testsuite/lib/target-supports.exp	Fri Jul 09 12:16:17 2010 +0200
@@ -910,6 +910,42 @@ 
     }]
 }
 
+# Return 1 if the target supports running SSE executables, 0 otherwise.
+
+proc check_effective_target_sse_runtime { } {
+    # The Solaris 2 kernel doesn't save and restore SSE registers before
+    # Solaris 9 4/04.  Before that, executables die with SIGILL.
+    if { [istarget i?86-*-solaris2*] } {
+	check_runtime sse_execute {
+	    int main ()
+	    {
+		__asm__ volatile ("movss %xmm2,%xmm1");
+		return 0;
+	    }
+	} "-msse"
+    } else {
+	return 1
+    }
+}
+
+# Return 1 if the target supports running SSE2 executables, 0 otherwise.
+
+proc check_effective_target_sse2_runtime { } {
+    # The Solaris 2 kernel doesn't save and restore SSE2 registers before
+    # Solaris 9 4/04.  Before that, executables die with SIGILL.
+    if { [istarget i?86-*-solaris2*] } {
+	check_runtime sse2_execute {
+	    int main ()
+	    {
+		__asm__ volatile ("unpcklpd %xmm0,%xmm2");
+		return 0;
+	    }
+	} "-msse2"
+    } else {
+	return 1
+    }
+}
+
 # Return 1 if the target supports executing SSE2 instructions, 0
 # otherwise.  Cache the result.
 
@@ -3261,6 +3297,17 @@ 
     } "-O2 -mavx" ]
 }
 
+# Return 1 if sse instructions can be compiled.
+proc check_effective_target_sse { } {
+    return [check_no_compiler_messages sse object {
+	int main ()
+	{
+	    __builtin_ia32_stmxcsr ();
+	    return 0;
+	}
+    } "-O2 -msse" ]
+}
+
 # Return 1 if sse2 instructions can be compiled.
 proc check_effective_target_sse2 { } {
     return [check_no_compiler_messages sse2 object {
diff -r 748345bc6714 libgfortran/config/fpu-387.h
--- a/libgfortran/config/fpu-387.h	Fri Jul 09 12:08:21 2010 +0200
+++ b/libgfortran/config/fpu-387.h	Fri Jul 09 12:16:17 2010 +0200
@@ -1,5 +1,5 @@ 
 /* FPU-related code for x86 and x86_64 processors.
-   Copyright 2005, 2007, 2009 Free Software Foundation, Inc.
+   Copyright 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
    Contributed by Francois-Xavier Coudert <coudert@clipper.ens.fr>
 
 This file is part of the GNU Fortran 95 runtime library (libgfortran).
@@ -27,6 +27,26 @@ 
 #include "cpuid.h"
 #endif
 
+#if defined(__sun__) && defined(__svr4__)
+#include <signal.h>
+#include <ucontext.h>
+
+static volatile sig_atomic_t sigill_caught;
+
+static void
+sigill_hdlr (int sig __attribute((unused)),
+	     siginfo_t *sip __attribute__((unused)),
+	     ucontext_t *ucp)
+{
+  sigill_caught = 1;
+  /* Set PC to the instruction after the faulting one to skip over it,
+     otherwise we enter an infinite loop.  4 is the size of the stmxcsr
+     instruction.  */
+  ucp->uc_mcontext.gregs[EIP] += 4;
+  setcontext (ucp);
+}
+#endif
+
 static int
 has_sse (void)
 {
@@ -36,6 +56,31 @@ 
   if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
     return 0;
 
+#if defined(__sun__) && defined(__svr4__)
+  /* Solaris 2 before Solaris 9 4/04 cannot execute SSE instructions even
+     if the CPU supports them.  Programs receive SIGILL instead, so check
+     for that at runtime.  */
+
+  if (edx & bit_SSE)
+    {
+      struct sigaction act, oact;
+      unsigned int cw_sse;
+
+      act.sa_handler = sigill_hdlr;
+      sigemptyset (&act.sa_mask);
+      /* Need to set SA_SIGINFO so a ucontext_t * is passed to the handler.  */
+      act.sa_flags = SA_SIGINFO;
+      sigaction (SIGILL, &act, &oact);
+
+      asm volatile ("stmxcsr %0" : "=m" (cw_sse));
+
+      sigaction (SIGILL, &oact, NULL);
+
+      if (sigill_caught)
+	return 0;
+    }
+#endif /* __sun__ && __svr4__ */
+
   return edx & bit_SSE;
 #else
   return 1;