diff mbox

[MPX,runtime,2/2] Add MPX tests

Message ID 20141111155428.GA34837@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Ilya Enkovich Nov. 11, 2014, 4:02 p.m. UTC
Hi,

This patch adds simple runtime MPX tests.

Make check shows no fails for mpx.exp suite for x86_64-unknown-linux-gnu{-m32,-mx32,}.  OK for trunk?

Thanks,
Ilya
--
gcc/

2014-11-11  Ilya Enkovich  <ilya.enkovich@intel.com>

	* config/i386/cpuid.h (bit_MPX): New.

gcc/testsuites/

2014-11-11  Ilya Enkovich  <ilya.enkovich@intel.com>

	* gcc/testsuite/lib/mpx-dg.exp (mpx_link_flags): New.
	(mpx_init): New.
	(mpx_finish): New.
	* gcc.target/i386/mpx/alloca-1-lbv.c: New.
	* gcc.target/i386/mpx/alloca-1-nov.c: New.
	* gcc.target/i386/mpx/alloca-1-ubv.c: New.
	* gcc.target/i386/mpx/arg-addr-1-lbv.c: New.
	* gcc.target/i386/mpx/arg-addr-1-nov.c: New.
	* gcc.target/i386/mpx/arg-addr-1-ubv.c: New.
	* gcc.target/i386/mpx/bitfields-1-lbv.c: New.
	* gcc.target/i386/mpx/bitfields-1-nov.c: New.
	* gcc.target/i386/mpx/bitfields-1-ubv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-lbv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-nov.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-ubv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-2.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-1-lbv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-1-nov.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-2.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-1-nov.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-1-ubv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-2.c: New.
	* gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-1.c: New.
	* gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-lbv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-nov.c: New.
	* gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-ubv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-3.c: New.
	* gcc.target/i386/mpx/builtin-bnd-get-ptr-lbound-1.c: New.
	* gcc.target/i386/mpx/builtin-bnd-get-ptr-lbound-2.c: New.
	* gcc.target/i386/mpx/builtin-bnd-get-ptr-ubound-1.c: New.
	* gcc.target/i386/mpx/builtin-bnd-get-ptr-ubound-2.c: New.
	* gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-1.c: New.
	* gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-2-nov.c: New.
	* gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-3.c: New.
	* gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-1.c: New.
	* gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-lbv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-nov.c: New.
	* gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-ubv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-lbv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-nov.c: New.
	* gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-ubv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-4.c: New.
	* gcc.target/i386/mpx/builtin-bnd-null-ptr-bounds-1-bbv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-1.c: New.
	* gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-lbv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-nov.c: New.
	* gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-ubv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-3.c: New.
	* gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-lbv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-nov.c: New.
	* gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-ubv.c: New.
	* gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-2.c: New.
	* gcc.target/i386/mpx/fastcall-1-lbv.c: New.
	* gcc.target/i386/mpx/fastcall-1-nov.c: New.
	* gcc.target/i386/mpx/fastcall-1-ubv.c: New.
	* gcc.target/i386/mpx/fastcall-2-lbv.c: New.
	* gcc.target/i386/mpx/fastcall-2-nov.c: New.
	* gcc.target/i386/mpx/fastcall-2-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-1-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-1-nov.c: New.
	* gcc.target/i386/mpx/field-addr-1-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-10-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-10-nov.c: New.
	* gcc.target/i386/mpx/field-addr-10-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-2-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-2-nov.c: New.
	* gcc.target/i386/mpx/field-addr-2-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-3-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-3-nov.c: New.
	* gcc.target/i386/mpx/field-addr-3-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-4-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-4-nov.c: New.
	* gcc.target/i386/mpx/field-addr-4-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-5-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-5-nov.c: New.
	* gcc.target/i386/mpx/field-addr-5-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-6-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-6-nov.c: New.
	* gcc.target/i386/mpx/field-addr-6-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-7-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-7-nov.c: New.
	* gcc.target/i386/mpx/field-addr-7-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-8-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-8-nov.c: New.
	* gcc.target/i386/mpx/field-addr-8-ubv.c: New.
	* gcc.target/i386/mpx/field-addr-9-lbv.c: New.
	* gcc.target/i386/mpx/field-addr-9-nov.c: New.
	* gcc.target/i386/mpx/field-addr-9-ubv.c: New.
	* gcc.target/i386/mpx/frame-address-1-nov.c: New.
	* gcc.target/i386/mpx/hard-reg-1-nov.c: New.
	* gcc.target/i386/mpx/if-stmt-1-lbv.c: New.
	* gcc.target/i386/mpx/if-stmt-1-nov.c: New.
	* gcc.target/i386/mpx/if-stmt-1-ubv.c: New.
	* gcc.target/i386/mpx/if-stmt-2-lbv.c: New.
	* gcc.target/i386/mpx/if-stmt-2-nov.c: New.
	* gcc.target/i386/mpx/if-stmt-2-ubv.c: New.
	* gcc.target/i386/mpx/label-address-1.c: New.
	* gcc.target/i386/mpx/legacy-1-nov.c: New.
	* gcc.target/i386/mpx/macro.c: New.
	* gcc.target/i386/mpx/mpx-check.h: New.
	* gcc.target/i386/mpx/mpx.exp: New.
	* gcc.target/i386/mpx/nested-function-1-lbv.c: New.
	* gcc.target/i386/mpx/nested-function-1-nov.c: New.
	* gcc.target/i386/mpx/nested-function-1-ubv.c: New.
	* gcc.target/i386/mpx/pointer-arg-1-lbv.c: New.
	* gcc.target/i386/mpx/pointer-arg-1-nov.c: New.
	* gcc.target/i386/mpx/pointer-arg-1-ubv.c: New.
	* gcc.target/i386/mpx/pointer-arg-2-lbv.c: New.
	* gcc.target/i386/mpx/pointer-arg-2-nov.c: New.
	* gcc.target/i386/mpx/pointer-arg-2-ubv.c: New.
	* gcc.target/i386/mpx/pointer-arg-3-lbv.c: New.
	* gcc.target/i386/mpx/pointer-arg-3-nov.c: New.
	* gcc.target/i386/mpx/pointer-arg-3-ubv.c: New.
	* gcc.target/i386/mpx/pointer-arg-4-lbv.c: New.
	* gcc.target/i386/mpx/pointer-arg-4-nov.c: New.
	* gcc.target/i386/mpx/pointer-arg-4-ubv.c: New.
	* gcc.target/i386/mpx/pointer-arg-5-lbv.c: New.
	* gcc.target/i386/mpx/pointer-arg-5-nov.c: New.
	* gcc.target/i386/mpx/pointer-arg-5-ubv.c: New.
	* gcc.target/i386/mpx/pointer-store-1-lbv.c: New.
	* gcc.target/i386/mpx/pointer-store-1-nov.c: New.
	* gcc.target/i386/mpx/pointer-store-1-ubv.c: New.
	* gcc.target/i386/mpx/reference-1-lbv.c: New.pp
	* gcc.target/i386/mpx/reference-1-nov.c: New.pp
	* gcc.target/i386/mpx/reference-1-ubv.c: New.pp
	* gcc.target/i386/mpx/reference-2-lbv.c: New.pp
	* gcc.target/i386/mpx/reference-2-nov.c: New.pp
	* gcc.target/i386/mpx/reference-2-ubv.c: New.pp
	* gcc.target/i386/mpx/reference-3-lbv.c: New.pp
	* gcc.target/i386/mpx/reference-3-nov.c: New.pp
	* gcc.target/i386/mpx/reference-3-ubv.c: New.pp
	* gcc.target/i386/mpx/reference-4-lbv.c: New.pp
	* gcc.target/i386/mpx/reference-4-nov.c: New.pp
	* gcc.target/i386/mpx/reference-4-ubv.c: New.pp
	* gcc.target/i386/mpx/return-pointer-1-lbv.c: New.
	* gcc.target/i386/mpx/return-pointer-1-nov.c: New.
	* gcc.target/i386/mpx/return-pointer-1-ubv.c: New.
	* gcc.target/i386/mpx/return-struct-1-lbv.c: New.
	* gcc.target/i386/mpx/return-struct-1-nov.c: New.
	* gcc.target/i386/mpx/return-struct-1-ubv.c: New.
	* gcc.target/i386/mpx/return-struct-2-lbv.c: New.
	* gcc.target/i386/mpx/return-struct-2-nov.c: New.
	* gcc.target/i386/mpx/return-struct-2-ubv.c: New.
	* gcc.target/i386/mpx/return-struct-3-lbv.c: New.
	* gcc.target/i386/mpx/return-struct-3-nov.c: New.
	* gcc.target/i386/mpx/return-struct-3-ubv.c: New.
	* gcc.target/i386/mpx/return-struct-4-lbv.c: New.
	* gcc.target/i386/mpx/return-struct-4-nov.c: New.
	* gcc.target/i386/mpx/return-struct-4-ubv.c: New.
	* gcc.target/i386/mpx/return-struct-5-lbv.c: New.
	* gcc.target/i386/mpx/return-struct-5-nov.c: New.
	* gcc.target/i386/mpx/return-struct-5-ubv.c: New.
	* gcc.target/i386/mpx/return-struct-6-lbv.c: New.
	* gcc.target/i386/mpx/return-struct-6-nov.c: New.
	* gcc.target/i386/mpx/return-struct-6-ubv.c: New.
	* gcc.target/i386/mpx/sincos-1-nov.c: New.
	* gcc.target/i386/mpx/static-array-1-lbv.c: New.
	* gcc.target/i386/mpx/static-array-1-nov.c: New.
	* gcc.target/i386/mpx/static-array-1-ubv.c: New.
	* gcc.target/i386/mpx/static-init-1-lbv.c: New.
	* gcc.target/i386/mpx/static-init-1-nov.c: New.
	* gcc.target/i386/mpx/static-init-1-ubv.c: New.
	* gcc.target/i386/mpx/static-init-2-lbv.c: New.
	* gcc.target/i386/mpx/static-init-2-nov.c: New.
	* gcc.target/i386/mpx/static-init-2-ubv.c: New.
	* gcc.target/i386/mpx/static-init-3-lbv.c: New.
	* gcc.target/i386/mpx/static-init-3-nov.c: New.
	* gcc.target/i386/mpx/static-init-3-ubv.c: New.
	* gcc.target/i386/mpx/static-init-4-lbv.c: New.
	* gcc.target/i386/mpx/static-init-4-nov.c: New.
	* gcc.target/i386/mpx/static-init-4-ubv.c: New.
	* gcc.target/i386/mpx/static-init-5-lbv.c: New.
	* gcc.target/i386/mpx/static-init-5-nov.c: New.
	* gcc.target/i386/mpx/static-init-5-ubv.c: New.
	* gcc.target/i386/mpx/static-init-6-lbv.c: New.
	* gcc.target/i386/mpx/static-init-6-nov.c: New.
	* gcc.target/i386/mpx/static-init-6-ubv.c: New.
	* gcc.target/i386/mpx/static-string-1-lbv.c: New.
	* gcc.target/i386/mpx/static-string-1-nov.c: New.
	* gcc.target/i386/mpx/static-string-1-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-1-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-1-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-1-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-10-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-10-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-10-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-2-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-2-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-2-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-3-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-3-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-3-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-4-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-4-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-4-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-5-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-5-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-5-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-6-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-6-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-6-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-7-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-7-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-7-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-8-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-8-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-8-ubv.c: New.
	* gcc.target/i386/mpx/struct-arg-9-lbv.c: New.
	* gcc.target/i386/mpx/struct-arg-9-nov.c: New.
	* gcc.target/i386/mpx/struct-arg-9-ubv.c: New.
	* gcc.target/i386/mpx/struct-copy-1-lbv.c: New.
	* gcc.target/i386/mpx/struct-copy-1-nov.c: New.
	* gcc.target/i386/mpx/struct-copy-1-ubv.c: New.
	* gcc.target/i386/mpx/struct-copy-2-lbv.c: New.
	* gcc.target/i386/mpx/struct-copy-2-nov.c: New.
	* gcc.target/i386/mpx/struct-copy-2-ubv.c: New.
	* gcc.target/i386/mpx/thread-local-var-1-lbv.c: New.
	* gcc.target/i386/mpx/thread-local-var-1-nov.c: New.
	* gcc.target/i386/mpx/thread-local-var-1-ubv.c: New.
	* gcc.target/i386/mpx/union-arg-1-lbv.c: New.
	* gcc.target/i386/mpx/union-arg-1-nov.c: New.
	* gcc.target/i386/mpx/union-arg-1-ubv.c: New.
	* gcc.target/i386/mpx/va-arg-pack-1-lbv.c: New.
	* gcc.target/i386/mpx/va-arg-pack-1-nov.c: New.
	* gcc.target/i386/mpx/va-arg-pack-1-ubv.c: New.
	* gcc.target/i386/mpx/va-arg-pack-2-lbv.c: New.
	* gcc.target/i386/mpx/va-arg-pack-2-nov.c: New.
	* gcc.target/i386/mpx/va-arg-pack-2-ubv.c: New.
	* gcc.target/i386/mpx/vararg-1-lbv.c: New.
	* gcc.target/i386/mpx/vararg-1-nov.c: New.
	* gcc.target/i386/mpx/vararg-1-ubv.c: New.
	* gcc.target/i386/mpx/vararg-2-lbv.c: New.
	* gcc.target/i386/mpx/vararg-2-nov.c: New.
	* gcc.target/i386/mpx/vararg-2-ubv.c: New.
	* gcc.target/i386/mpx/vararg-3-lbv.c: New.
	* gcc.target/i386/mpx/vararg-3-nov.c: New.
	* gcc.target/i386/mpx/vararg-3-ubv.c: New.
	* gcc.target/i386/mpx/vararg-4-lbv.c: New.
	* gcc.target/i386/mpx/vararg-4-nov.c: New.
	* gcc.target/i386/mpx/vararg-4-ubv.c: New.
	* gcc.target/i386/mpx/vararg-5-lbv.c: New.
	* gcc.target/i386/mpx/vararg-5-nov.c: New.
	* gcc.target/i386/mpx/vararg-5-ubv.c: New.
	* gcc.target/i386/mpx/vararg-6-lbv.c: New.
	* gcc.target/i386/mpx/vararg-6-nov.c: New.
	* gcc.target/i386/mpx/vararg-6-ubv.c: New.
	* gcc.target/i386/mpx/vararg-7-lbv.c: New.
	* gcc.target/i386/mpx/vararg-7-nov.c: New.
	* gcc.target/i386/mpx/vararg-7-ubv.c: New.
	* gcc.target/i386/mpx/vararg-8-lbv.c: New.
	* gcc.target/i386/mpx/vararg-8-nov.c: New.
	* gcc.target/i386/mpx/vararg-8-ubv.c: New.
	* gcc.target/i386/mpx/vla-1-lbv.c: New.
	* gcc.target/i386/mpx/vla-1-nov.c: New.
	* gcc.target/i386/mpx/vla-1-ubv.c: New.
	* gcc.target/i386/mpx/vla-2-lbv.c: New.
	* gcc.target/i386/mpx/vla-2-nov.c: New.
	* gcc.target/i386/mpx/vla-2-ubv.c: New.

Comments

Mike Stump Nov. 11, 2014, 6:42 p.m. UTC | #1
On Nov 11, 2014, at 8:02 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
> This patch adds simple runtime MPX tests.
> 
> Make check shows no fails for mpx.exp suite for x86_64-unknown-linux-gnu{-m32,-mx32,}.  OK for trunk?

Ok with any changes necessary for:

I’m assuming that this won’t break i386 (targets without any mpx) testing.

	* gcc.target/i386/mpx/reference-1-lbv.c: New.pp
	* gcc.target/i386/mpx/reference-1-nov.c: New.pp
	* gcc.target/i386/mpx/reference-1-ubv.c: New.pp
	* gcc.target/i386/mpx/reference-2-lbv.c: New.pp
	* gcc.target/i386/mpx/reference-2-nov.c: New.pp
	* gcc.target/i386/mpx/reference-2-ubv.c: New.pp
	* gcc.target/i386/mpx/reference-3-lbv.c: New.pp
	* gcc.target/i386/mpx/reference-3-nov.c: New.pp
	* gcc.target/i386/mpx/reference-3-ubv.c: New.pp
	* gcc.target/i386/mpx/reference-4-lbv.c: New.pp
	* gcc.target/i386/mpx/reference-4-nov.c: New.pp
	* gcc.target/i386/mpx/reference-4-ubv.c: New.pp

pp?
Jeff Law Nov. 11, 2014, 7:55 p.m. UTC | #2
On 11/11/14 11:42, Mike Stump wrote:
> On Nov 11, 2014, at 8:02 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>> This patch adds simple runtime MPX tests.
>>
>> Make check shows no fails for mpx.exp suite for x86_64-unknown-linux-gnu{-m32,-mx32,}.  OK for trunk?
>
> Ok with any changes necessary for:
>
> I’m assuming that this won’t break i386 (targets without any mpx) testing.
It shouldn't.  There's check in mpx.exp that's supposed to prevent the 
tests from running.  I haven't verified that though.

Ilya, if you could verify the tests aren't going to cause failures on 
x86-64 targets w/o MPX it'd be appreciated.

jeff
Ilya Enkovich Nov. 11, 2014, 8:10 p.m. UTC | #3
2014-11-11 22:55 GMT+03:00 Jeff Law <law@redhat.com>:
> On 11/11/14 11:42, Mike Stump wrote:
>>
>> On Nov 11, 2014, at 8:02 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
>>>
>>> This patch adds simple runtime MPX tests.
>>>
>>> Make check shows no fails for mpx.exp suite for
>>> x86_64-unknown-linux-gnu{-m32,-mx32,}.  OK for trunk?
>>
>>
>> Ok with any changes necessary for:
>>
>> I’m assuming that this won’t break i386 (targets without any mpx) testing.
>
> It shouldn't.  There's check in mpx.exp that's supposed to prevent the tests
> from running.  I haven't verified that though.
>
> Ilya, if you could verify the tests aren't going to cause failures on x86-64
> targets w/o MPX it'd be appreciated.
>
> jeff
>

Hi,

tests are compiled ignoring CPUID, mpx.exp only checks tests may be
compiled (i.e. binutils support MPX, runtime wasn't disabled etc.).
All MPX binaries are supposed to work correctly on hardware without
MPX, we just shouldn't expect any bound violations detected.  Thus all
tests run even on hardware with no MPX.  mpx-check.h is included into
each (or almost each test). It checks CPUID and just exits with
expected code in case MPX is not supported.  I tried it on hardware
with and without MPX and check log is same for both cases.  But in
more detailed gcc.log we may see that tests are SKIPPED when we have
no MPX in hardware.

Thanks,
Ilya
Jeff Law Nov. 11, 2014, 8:16 p.m. UTC | #4
On 11/11/14 13:10, Ilya Enkovich wrote:
> tests are compiled ignoring CPUID, mpx.exp only checks tests may be
> compiled (i.e. binutils support MPX, runtime wasn't disabled etc.).
> All MPX binaries are supposed to work correctly on hardware without
> MPX, we just shouldn't expect any bound violations detected.  Thus all
> tests run even on hardware with no MPX.  mpx-check.h is included into
> each (or almost each test). It checks CPUID and just exits with
> expected code in case MPX is not supported.  I tried it on hardware
> with and without MPX and check log is same for both cases.  But in
> more detailed gcc.log we may see that tests are SKIPPED when we have
> no MPX in hardware.
Ah.  OK.  That sounds even better.

Jeff
diff mbox

Patch

diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index 133e356..bce1dcf 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -72,6 +72,7 @@ 
 #define bit_AVX2	(1 << 5)
 #define bit_BMI2	(1 << 8)
 #define bit_RTM	(1 << 11)
+#define bit_MPX (1 << 14)
 #define bit_AVX512F	(1 << 16)
 #define bit_AVX512DQ	(1 << 17)
 #define bit_RDSEED	(1 << 18)
diff --git a/gcc/testsuite/gcc.target/i386/mpx/alloca-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/alloca-1-lbv.c
new file mode 100644
index 0000000..f81a5e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/alloca-1-lbv.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *buf = (int *)alloca (100 * sizeof(int));
+
+  rd (buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/alloca-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/alloca-1-nov.c
new file mode 100644
index 0000000..162b4d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/alloca-1-nov.c
@@ -0,0 +1,22 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *buf = (int *)alloca (100 * sizeof(int));
+
+  rd (buf, 0);
+  rd (buf, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/alloca-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/alloca-1-ubv.c
new file mode 100644
index 0000000..9af3f11
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/alloca-1-ubv.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *buf = (int *)alloca (100 * sizeof(int));
+
+  rd (buf, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/arg-addr-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/arg-addr-1-lbv.c
new file mode 100644
index 0000000..1fd2036
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/arg-addr-1-lbv.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int foo (int i, int j)
+{
+  return rd(&i, j);
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (1, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/arg-addr-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/arg-addr-1-nov.c
new file mode 100644
index 0000000..4e338c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/arg-addr-1-nov.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int foo (int i, int j)
+{
+  return rd(&i, j);
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (1, 0);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/arg-addr-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/arg-addr-1-ubv.c
new file mode 100644
index 0000000..65cb46b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/arg-addr-1-ubv.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int foo (int i, int j)
+{
+  return rd(&i, j);
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (1, 1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/bitfields-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/bitfields-1-lbv.c
new file mode 100644
index 0000000..deca6fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/bitfields-1-lbv.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s {
+  int a;
+  int b : 10;
+  int c : 1;
+  int e : 10;
+} s;
+
+#define HH (unsigned char)1
+
+int foo (struct s *p)
+{
+  int val = p->b;
+  printf ("%d\n", val);
+  return val == HH;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s buf[100];
+
+  foo (buf - 1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/bitfields-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/bitfields-1-nov.c
new file mode 100644
index 0000000..0a7913a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/bitfields-1-nov.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s {
+  int a;
+  int b : 10;
+  int c : 1;
+  int e : 10;
+} s;
+
+#define HH (unsigned char)1
+
+int foo (struct s *p)
+{
+  int val = p->b;
+  printf ("%d\n", val);
+  return val == HH;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s buf[100];
+
+  foo (buf);
+  foo (buf + 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/bitfields-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/bitfields-1-ubv.c
new file mode 100644
index 0000000..a20a789
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/bitfields-1-ubv.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s {
+  int a;
+  int b : 10;
+  int c : 1;
+  int e : 10;
+} s;
+
+#define HH (unsigned char)1
+
+int foo (struct s *p)
+{
+  int val = p->b;
+  printf ("%d\n", val);
+  return val == HH;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s buf[100];
+
+  foo (buf + 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-lbv.c
new file mode 100644
index 0000000..140848e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-lbv.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_bounds (buf - 1, sizeof (int));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-nov.c
new file mode 100644
index 0000000..055b61d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-nov.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_bounds (buf, sizeof (int) * 100);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-ubv.c
new file mode 100644
index 0000000..f811694
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-1-ubv.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_bounds (buf + 100, sizeof (int));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-2.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-2.c
new file mode 100644
index 0000000..47e62e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-bounds-2.c
@@ -0,0 +1,14 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_bounds (buf - 1, sizeof (int));
+  __bnd_chk_ptr_bounds (buf + 100, sizeof (int));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-1-lbv.c
new file mode 100644
index 0000000..085166f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-1-lbv.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_lbounds (buf - 1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-1-nov.c
new file mode 100644
index 0000000..3a666d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-1-nov.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_lbounds (buf);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-2.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-2.c
new file mode 100644
index 0000000..87b80e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-lbounds-2.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_lbounds (buf - 1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-1-nov.c
new file mode 100644
index 0000000..8a73fe3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-1-nov.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_ubounds (buf + 99);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-1-ubv.c
new file mode 100644
index 0000000..eb22dd1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-1-ubv.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_ubounds (buf + 100);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-2.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-2.c
new file mode 100644
index 0000000..503bd53
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-chk-ptr-ubounds-2.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  __bnd_chk_ptr_ubounds (buf + 100);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-1.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-1.c
new file mode 100644
index 0000000..0949f6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-1.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf + 10 == __bnd_copy_ptr_bounds (buf + 10, buf));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-lbv.c
new file mode 100644
index 0000000..a7317e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-lbv.c
@@ -0,0 +1,18 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  int *p1 = __bnd_copy_ptr_bounds (buf, p);
+  p1[9] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-nov.c
new file mode 100644
index 0000000..6b6423e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-nov.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  int *p1 = __bnd_copy_ptr_bounds (buf, p);
+  p1[10] = argc;
+  p1[19] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-ubv.c
new file mode 100644
index 0000000..2893d9b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-2-ubv.c
@@ -0,0 +1,18 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  int *p1 = __bnd_copy_ptr_bounds (buf, p);
+  p1[20] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-3.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-3.c
new file mode 100644
index 0000000..4d01375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-copy-ptr-bounds-3.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf + 10 == __bnd_copy_ptr_bounds (buf + 10, buf));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-lbound-1.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-lbound-1.c
new file mode 100644
index 0000000..2a7f46f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-lbound-1.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+char buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf == __bnd_get_ptr_lbound (buf));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-lbound-2.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-lbound-2.c
new file mode 100644
index 0000000..70b49e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-lbound-2.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+char buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert ((void *)0 == __bnd_get_ptr_lbound (buf));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-ubound-1.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-ubound-1.c
new file mode 100644
index 0000000..a9111f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-ubound-1.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+char buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf + 99 == __bnd_get_ptr_ubound (buf));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-ubound-2.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-ubound-2.c
new file mode 100644
index 0000000..cf0aca1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-get-ptr-ubound-2.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+char buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert ((void *)-1 == __bnd_get_ptr_ubound (buf));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-1.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-1.c
new file mode 100644
index 0000000..ee259cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-1.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf + 10 == __bnd_init_ptr_bounds (buf + 10));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-2-nov.c
new file mode 100644
index 0000000..da44e7a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-2-nov.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  p = __bnd_init_ptr_bounds (p);
+  p[-1] = argc;
+  p[10] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-3.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-3.c
new file mode 100644
index 0000000..8c15270
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-init-ptr-bounds-3.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf + 10 == __bnd_init_ptr_bounds (buf + 10));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-1.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-1.c
new file mode 100644
index 0000000..4ac49ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-1.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf + 10 == __bnd_narrow_ptr_bounds (buf + 10, buf, 4));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-lbv.c
new file mode 100644
index 0000000..21a8f92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-lbv.c
@@ -0,0 +1,17 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_narrow_ptr_bounds (buf - 10, buf, sizeof (int) * 20);
+  p[9] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-nov.c
new file mode 100644
index 0000000..8182d02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-nov.c
@@ -0,0 +1,15 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_narrow_ptr_bounds (buf - 10, buf, sizeof (int) * 20);
+  p[10] = argc;
+  p[19] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-ubv.c
new file mode 100644
index 0000000..6ff90ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-2-ubv.c
@@ -0,0 +1,17 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_narrow_ptr_bounds (buf - 10, buf, sizeof (int) * 20);
+  p[20] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-lbv.c
new file mode 100644
index 0000000..69b4a51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-lbv.c
@@ -0,0 +1,17 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_narrow_ptr_bounds (buf + 10, buf, sizeof (int) * 100);
+  p[-1] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-nov.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-nov.c
new file mode 100644
index 0000000..0c13b12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-nov.c
@@ -0,0 +1,15 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_narrow_ptr_bounds (buf + 10, buf, sizeof (int) * 100);
+  p[0] = argc;
+  p[89] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-ubv.c
new file mode 100644
index 0000000..445e337
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-3-ubv.c
@@ -0,0 +1,17 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_narrow_ptr_bounds (buf + 10, buf, sizeof (int) * 100);
+  p[90] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-4.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-4.c
new file mode 100644
index 0000000..144855c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-narrow-ptr-bounds-4.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf - 10 == __bnd_narrow_ptr_bounds (buf - 10, buf, 4));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-null-ptr-bounds-1-bbv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-null-ptr-bounds-1-bbv.c
new file mode 100644
index 0000000..5497ef1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-null-ptr-bounds-1-bbv.c
@@ -0,0 +1,17 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_null_ptr_bounds (buf + 10);
+  p[0] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-1.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-1.c
new file mode 100644
index 0000000..8abb257
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-1.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf + 10 == __bnd_set_ptr_bounds (buf + 10, 4));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-lbv.c
new file mode 100644
index 0000000..bbc578a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-lbv.c
@@ -0,0 +1,17 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  p[-1] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-nov.c
new file mode 100644
index 0000000..39df101
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-nov.c
@@ -0,0 +1,15 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  p[0] = argc;
+  p[9] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-ubv.c
new file mode 100644
index 0000000..c2d27e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-2-ubv.c
@@ -0,0 +1,17 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  p[10] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-3.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-3.c
new file mode 100644
index 0000000..811cdb4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-set-ptr-bounds-3.c
@@ -0,0 +1,13 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  assert (buf + 10 == __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-lbv.c
new file mode 100644
index 0000000..af6c8db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-lbv.c
@@ -0,0 +1,20 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p;
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p1 = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  p = buf;
+  __bnd_store_ptr_bounds ((void **)&p, p1 - 10);
+  p[9] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-nov.c
new file mode 100644
index 0000000..9e9ea30
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-nov.c
@@ -0,0 +1,18 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p;
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p1 = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  p = buf;
+  __bnd_store_ptr_bounds ((void **)&p, p1 - 10);
+  p[10] = argc;
+  p[19] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-ubv.c
new file mode 100644
index 0000000..62aca8c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-1-ubv.c
@@ -0,0 +1,20 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p;
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p1 = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  p = buf;
+  __bnd_store_ptr_bounds ((void **)&p, p1 - 10);
+  p[20] = argc;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-2.c b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-2.c
new file mode 100644
index 0000000..a2ca790
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/builtin-bnd-store-ptr-bounds-2.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-options "-fno-check-pointer-bounds" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p;
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p1 = __bnd_set_ptr_bounds (buf + 10, sizeof (int) * 10);
+  p = buf;
+  __bnd_store_ptr_bounds ((void **)&p, p1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/fastcall-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/fastcall-1-lbv.c
new file mode 100644
index 0000000..6f9ba88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/fastcall-1-lbv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+__attribute__((fastcall)) int rd (int *p1, int *p2, int i)
+{
+  int res = p1[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/fastcall-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/fastcall-1-nov.c
new file mode 100644
index 0000000..6a2896e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/fastcall-1-nov.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+__attribute__((fastcall)) int rd (int *p1, int *p2, int i)
+{
+  int res = p1[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, buf, 0);
+  rd (buf1, buf, 9);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/fastcall-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/fastcall-1-ubv.c
new file mode 100644
index 0000000..b5edc43
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/fastcall-1-ubv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+__attribute__((fastcall)) int rd (int *p1, int *p2, int i)
+{
+  int res = p1[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, buf, 10);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/fastcall-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/fastcall-2-lbv.c
new file mode 100644
index 0000000..cbe7343
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/fastcall-2-lbv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+__attribute__((fastcall)) int rd (int *p1, int *p2, int i)
+{
+  int res = p2[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf, buf1, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/fastcall-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/fastcall-2-nov.c
new file mode 100644
index 0000000..83773d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/fastcall-2-nov.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+__attribute__((fastcall)) int rd (int *p1, int *p2, int i)
+{
+  int res = p2[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf, buf1, 0);
+  rd (buf, buf1, 9);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/fastcall-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/fastcall-2-ubv.c
new file mode 100644
index 0000000..1a614fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/fastcall-2-ubv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+__attribute__((fastcall)) int rd (int *p1, int *p2, int i)
+{
+  int res = p2[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf, buf1, 10);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-1-lbv.c
new file mode 100644
index 0000000..46a5812
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-1-lbv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (int *i, int k)
+{
+  printf ("%d\n", i[k]);
+  return i[k];
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S s;
+
+  foo(&s.a, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-1-nov.c
new file mode 100644
index 0000000..b8500ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-1-nov.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (int *i, int k)
+{
+  printf ("%d\n", i[k]);
+  return i[k];
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S s;
+
+  foo(&s.a, 0);
+  foo(&s.a, 101);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-1-ubv.c
new file mode 100644
index 0000000..990adee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-1-ubv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (int *i, int k)
+{
+  printf ("%d\n", i[k]);
+  return i[k];
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S s;
+
+  foo(&s.a, 102);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-10-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-10-lbv.c
new file mode 100644
index 0000000..cd8d59a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-10-lbv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-narrow-to-innermost-array" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int arr[100];
+} S;
+
+struct S sa[10];
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (&sa[argc].arr[0], -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-10-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-10-nov.c
new file mode 100644
index 0000000..90f79a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-10-nov.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-narrow-to-innermost-array" } */
+
+#include "mpx-check.h"
+
+struct S {
+  int arr[100];
+} S;
+
+struct S sa[10];
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (&sa[argc].arr[0], 0);
+  rd (&sa[argc].arr[0], 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-10-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-10-ubv.c
new file mode 100644
index 0000000..b6a9ad0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-10-ubv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-narrow-to-innermost-array" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int arr[100];
+} S;
+
+struct S sa[10];
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (&sa[argc].arr[0], 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-2-lbv.c
new file mode 100644
index 0000000..fdf3967
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-2-lbv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-first-field-has-own-bounds" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (int *i, int k)
+{
+  printf ("%d\n", i[k]);
+  return i[k];
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S s;
+
+  foo(&s.a, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-2-nov.c
new file mode 100644
index 0000000..2a68503
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-2-nov.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-first-field-has-own-bounds" } */
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (int *i, int k)
+{
+  printf ("%d\n", i[k]);
+  return i[k];
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S s;
+
+  foo(&s.a, 0);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-2-ubv.c
new file mode 100644
index 0000000..b07b09f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-2-ubv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-first-field-has-own-bounds" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (int *i, int k)
+{
+  printf ("%d\n", i[k]);
+  return i[k];
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S s;
+
+  foo(&s.a, 1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-3-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-3-lbv.c
new file mode 100644
index 0000000..ea919d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-3-lbv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S s;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&s.b[0], -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-3-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-3-nov.c
new file mode 100644
index 0000000..12f42c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-3-nov.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S s;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&s.b[0], 0);
+  foo (&s.b[0], 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-3-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-3-ubv.c
new file mode 100644
index 0000000..55a8af3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-3-ubv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S s;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&s.b[0], 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-4-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-4-lbv.c
new file mode 100644
index 0000000..23cf71e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-4-lbv.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+struct S1 {
+  int x;
+  struct S a[10];
+  struct S b;
+} S1;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S1 s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&s1.a[0].a, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-4-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-4-nov.c
new file mode 100644
index 0000000..7917532
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-4-nov.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+struct S1 {
+  int x;
+  struct S a[10];
+  struct S b;
+} S1;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S1 s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&s1.a[9].c, 0);
+  foo (&s1.a[0].a, 0);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-4-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-4-ubv.c
new file mode 100644
index 0000000..0d4ac02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-4-ubv.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+struct S1 {
+  int x;
+  struct S a[10];
+  struct S b;
+} S1;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S1 s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&s1.a[9].c, 1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-5-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-5-lbv.c
new file mode 100644
index 0000000..c00d42f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-5-lbv.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+struct S1 {
+  int x;
+  struct S a[10];
+  struct S b;
+} S1;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S1 s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&s1.b.b[0], -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-5-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-5-nov.c
new file mode 100644
index 0000000..b69895e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-5-nov.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+struct S1 {
+  int x;
+  struct S a[10];
+  struct S b;
+} S1;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S1 s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&s1.b.b[0], 0);
+  foo (&s1.b.b[0], 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-5-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-5-ubv.c
new file mode 100644
index 0000000..d00f41e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-5-ubv.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+struct S1 {
+  int x;
+  struct S a[10];
+  struct S b;
+} S1;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S1 s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&s1.b.b[0], 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-6-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-6-lbv.c
new file mode 100644
index 0000000..91b64bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-6-lbv.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+struct S1 {
+  int x;
+  struct S a[10];
+  struct S b;
+} S1;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S1 s1;
+struct S1 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s2->a[0].a), -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-6-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-6-nov.c
new file mode 100644
index 0000000..f837f57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-6-nov.c
@@ -0,0 +1,34 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+struct S1 {
+  int x;
+  struct S a[10];
+  struct S b;
+} S1;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S1 s1;
+struct S1 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s2->a[0].a), 0);
+  foo (&(s2->a[9].a), 101);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-6-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-6-ubv.c
new file mode 100644
index 0000000..97ef911
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-6-ubv.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+struct S1 {
+  int x;
+  struct S a[10];
+  struct S b;
+} S1;
+
+int foo (int *p, int i)
+{
+  printf ("%d\n", p[i]);
+  return p[i];
+}
+
+struct S1 s1;
+struct S1 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s2->a[9].a), 102);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-7-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-7-lbv.c
new file mode 100644
index 0000000..1769711
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-7-lbv.c
@@ -0,0 +1,42 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a[10];
+  int b;
+} S;
+
+struct S1 {
+  int a;
+  struct S b[10];
+  int c;
+} S1;
+
+struct S2 {
+  int x;
+  struct S1 a[10];
+  struct S1 b;
+} S2;
+
+int foo (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+struct S2 s1;
+struct S2 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s2->a[-1].a), 0);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-7-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-7-nov.c
new file mode 100644
index 0000000..19c09b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-7-nov.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct S {
+  int a[10];
+  int b;
+} S;
+
+struct S1 {
+  int a;
+  struct S b[10];
+  int c;
+} S1;
+
+struct S2 {
+  int x;
+  struct S1 a[10];
+  struct S1 b;
+} S2;
+
+int foo (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+struct S2 s1;
+struct S2 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s2->a[0].a), 0);
+  foo (&(s2->a[9].c), 0);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-7-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-7-ubv.c
new file mode 100644
index 0000000..c9e8ae2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-7-ubv.c
@@ -0,0 +1,42 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a[10];
+  int b;
+} S;
+
+struct S1 {
+  int a;
+  struct S b[10];
+  int c;
+} S1;
+
+struct S2 {
+  int x;
+  struct S1 a[10];
+  struct S1 b;
+} S2;
+
+int foo (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+struct S2 s1;
+struct S2 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s2->a[10].a), 0);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-8-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-8-lbv.c
new file mode 100644
index 0000000..cac6784
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-8-lbv.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-narrow-to-innermost-array" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a[10];
+  int b;
+} S;
+
+struct S1 {
+  int a;
+  struct S b[10];
+  int c;
+} S1;
+
+struct S2 {
+  int x;
+  struct S1 a[10];
+  struct S1 b;
+} S2;
+
+int foo (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+struct S2 s1;
+struct S2 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s1.a[argc].b[-1].a[0]), 9);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-8-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-8-nov.c
new file mode 100644
index 0000000..e7243a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-8-nov.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-narrow-to-innermost-array" } */
+
+#include "mpx-check.h"
+
+struct S {
+  int a[10];
+  int b;
+} S;
+
+struct S1 {
+  int a;
+  struct S b[10];
+  int c;
+} S1;
+
+struct S2 {
+  int x;
+  struct S1 a[10];
+  struct S1 b;
+} S2;
+
+int foo (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+struct S2 s1;
+struct S2 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s1.a[argc].b[0].a[0]), 0);
+  foo (&(s1.a[argc].b[0].a[0]), 9);
+  foo (&(s1.a[argc].b[9].a[0]), 0);
+  foo (&(s1.a[argc].b[9].a[0]), 9);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-8-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-8-ubv.c
new file mode 100644
index 0000000..d2792e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-8-ubv.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-narrow-to-innermost-array" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a[10];
+  int b;
+} S;
+
+struct S1 {
+  int a;
+  struct S b[10];
+  int c;
+} S1;
+
+struct S2 {
+  int x;
+  struct S1 a[10];
+  struct S1 b;
+} S2;
+
+int foo (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+struct S2 s1;
+struct S2 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s1.a[argc].b[10].a[0]), 9);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-9-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-9-lbv.c
new file mode 100644
index 0000000..127d096
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-9-lbv.c
@@ -0,0 +1,44 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-narrow-to-innermost-array" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int first;
+  int a[10];
+  int b;
+} S;
+
+struct S1 {
+  int a;
+  struct S b[10];
+  int c;
+} S1;
+
+struct S2 {
+  int x;
+  struct S1 a[10];
+  struct S1 b;
+} S2;
+
+int foo (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+struct S2 s1;
+struct S2 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s2->a[argc].b[5].a[0]), -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-9-nov.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-9-nov.c
new file mode 100644
index 0000000..7f98b01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-9-nov.c
@@ -0,0 +1,42 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-narrow-to-innermost-array" } */
+
+#include "mpx-check.h"
+
+struct S {
+  int first;
+  int a[10];
+  int b;
+} S;
+
+struct S1 {
+  int a;
+  struct S b[10];
+  int c;
+} S1;
+
+struct S2 {
+  int x;
+  struct S1 a[10];
+  struct S1 b;
+} S2;
+
+int foo (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+struct S2 s1;
+struct S2 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s2->a[argc].b[5].a[0]), 0);
+  foo (&(s2->a[argc].b[5].a[0]), 9);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/field-addr-9-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/field-addr-9-ubv.c
new file mode 100644
index 0000000..a65b8f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/field-addr-9-ubv.c
@@ -0,0 +1,44 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-fchkp-narrow-to-innermost-array" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int first;
+  int a[10];
+  int b;
+} S;
+
+struct S1 {
+  int a;
+  struct S b[10];
+  int c;
+} S1;
+
+struct S2 {
+  int x;
+  struct S1 a[10];
+  struct S1 b;
+} S2;
+
+int foo (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+struct S2 s1;
+struct S2 *s2 = &s1;
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (&(s2->a[argc].b[5].a[0]), 10);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/frame-address-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/frame-address-1-nov.c
new file mode 100644
index 0000000..87cc2dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/frame-address-1-nov.c
@@ -0,0 +1,12 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int mpx_test (int argc, const char **argv)
+{
+  void **fa = (void **)__builtin_frame_address (0);
+  printf ("%p\n", *fa);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-1-nov.c
new file mode 100644
index 0000000..8627679
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-1-nov.c
@@ -0,0 +1,20 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  register int *frame __asm__("rsp");
+  rd (frame, 1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/if-stmt-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-1-lbv.c
new file mode 100644
index 0000000..29fa443
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-1-lbv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int rd (int *p1, int *p2, int i)
+{
+  int res;
+
+  if (p1 < p2)
+    p1 = p2;
+
+  res = p1[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 1, 40);
+  rd (buf, p, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/if-stmt-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-1-nov.c
new file mode 100644
index 0000000..576ea84
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-1-nov.c
@@ -0,0 +1,28 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int rd (int *p1, int *p2, int i)
+{
+  int res;
+
+  if (p1 < p2)
+    p1 = p2;
+
+  res = p1[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 1, 40);
+  rd (buf, p, 0);
+  rd (buf, p, 9);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/if-stmt-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-1-ubv.c
new file mode 100644
index 0000000..021a3ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-1-ubv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int rd (int *p1, int *p2, int i)
+{
+  int res;
+
+  if (p1 < p2)
+    p1 = p2;
+
+  res = p1[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 1, 40);
+  rd (buf, p, 10);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/if-stmt-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-2-lbv.c
new file mode 100644
index 0000000..5d7fe62
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-2-lbv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int rd (int *p1, int *p2, int i)
+{
+  int res;
+
+  if (p1 > p2)
+    p1 = p2;
+
+  res = p1[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 1, 40);
+  rd (buf, p, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/if-stmt-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-2-nov.c
new file mode 100644
index 0000000..327c108
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-2-nov.c
@@ -0,0 +1,28 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int rd (int *p1, int *p2, int i)
+{
+  int res;
+
+  if (p1 > p2)
+    p1 = p2;
+
+  res = p1[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 1, 40);
+  rd (buf, p, 0);
+  rd (buf, p, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/if-stmt-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-2-ubv.c
new file mode 100644
index 0000000..3047f7b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/if-stmt-2-ubv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int rd (int *p1, int *p2, int i)
+{
+  int res;
+
+  if (p1 > p2)
+    p1 = p2;
+
+  res = p1[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 1, 40);
+  rd (buf, p, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/label-address-1.c b/gcc/testsuite/gcc.target/i386/mpx/label-address-1.c
new file mode 100644
index 0000000..f4cd360
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/label-address-1.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+void *p;
+int mpx_test (int argc, const char **argv)
+{
+  p = &&label;
+
+ label:
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/legacy-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/legacy-1-nov.c
new file mode 100644
index 0000000..b51ac7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/legacy-1-nov.c
@@ -0,0 +1,25 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+__attribute__((bnd_legacy))
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p = __bnd_set_ptr_bounds (buf + 1, 10);
+
+  rd (p, -1);
+  rd (p, 10);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/macro.c b/gcc/testsuite/gcc.target/i386/mpx/macro.c
new file mode 100644
index 0000000..00d467b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/macro.c
@@ -0,0 +1,18 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+#ifndef __MPX__
+#error -mmpx is required
+#endif
+
+#ifndef __CHKP__
+#error -fcheck-pointer-bounds is required
+#endif
+
+int mpx_test (int argc, const char **argv)
+{
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/mpx-check.h b/gcc/testsuite/gcc.target/i386/mpx/mpx-check.h
new file mode 100644
index 0000000..3afa460
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/mpx-check.h
@@ -0,0 +1,41 @@ 
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "cpuid.h"
+
+static int
+__attribute__ ((noinline))
+mpx_test (int, const char **);
+
+#ifdef SHOULDFAIL
+#define NORUNRES 1
+#else
+#define NORUNRES 0
+#endif
+
+#define DEBUG
+
+int
+main (int argc, const char **argv)
+{
+  unsigned int eax, ebx, ecx, edx;
+
+  if (__get_cpuid_max (0, NULL) < 7)
+    return 0;
+
+  __cpuid_count (7, 0, eax, ebx, ecx, edx);
+
+  /* Run MPX test only if host has MPX support.  */
+  if (ebx & bit_MPX)
+    mpx_test (argc, argv);
+  else
+    {
+#ifdef DEBUG
+      printf ("SKIPPED\n");
+#endif
+      return NORUNRES;
+    }
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/mpx.exp b/gcc/testsuite/gcc.target/i386/mpx/mpx.exp
new file mode 100644
index 0000000..b763c0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/mpx.exp
@@ -0,0 +1,41 @@ 
+# Copyright (C) 2014 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Exit immediately if this isn't a x86 target.
+if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+load_lib mpx-dg.exp
+
+if ![check_effective_target_mpx] {
+  return
+}
+
+# Initialize.
+dg-init
+mpx_init
+
+# Run all tests.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c*]] "" ""
+
+# All done.
+mpx_finish
+dg-finish
diff --git a/gcc/testsuite/gcc.target/i386/mpx/nested-function-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/nested-function-1-lbv.c
new file mode 100644
index 0000000..0e9d657
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/nested-function-1-lbv.c
@@ -0,0 +1,22 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int mpx_test (int argc, const char **argv)
+{
+  int a[100];
+
+  void rd (int i)
+  {
+    printf ("%d\n", a[i]);
+  }
+
+  rd (-1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/nested-function-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/nested-function-1-nov.c
new file mode 100644
index 0000000..dd98546
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/nested-function-1-nov.c
@@ -0,0 +1,20 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int mpx_test (int argc, const char **argv)
+{
+  int a[100];
+
+  void rd (int i)
+  {
+    printf ("%d\n", a[i]);
+  }
+
+  rd (0);
+  rd (99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/nested-function-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/nested-function-1-ubv.c
new file mode 100644
index 0000000..b5cf6cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/nested-function-1-ubv.c
@@ -0,0 +1,22 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int mpx_test (int argc, const char **argv)
+{
+  int a[100];
+
+  void rd (int i)
+  {
+    printf ("%d\n", a[i]);
+  }
+
+  rd (100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-1-lbv.c
new file mode 100644
index 0000000..58692ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-1-lbv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-1-nov.c
new file mode 100644
index 0000000..01279be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-1-nov.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf, 0);
+  rd (buf, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-1-ubv.c
new file mode 100644
index 0000000..c377c57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-1-ubv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-2-lbv.c
new file mode 100644
index 0000000..ebe76cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-2-lbv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int t1, int t2, int t3, int t4, int t5, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (0, 0, 0, 0, 0, buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-2-nov.c
new file mode 100644
index 0000000..8b9fce2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-2-nov.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int t1, int t2, int t3, int t4, int t5, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (0, 0, 0, 0, 0, buf, 0);
+  rd (0, 0, 0, 0, 0, buf, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-2-ubv.c
new file mode 100644
index 0000000..525140e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-2-ubv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int t1, int t2, int t3, int t4, int t5, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (0, 0, 0, 0, 0, buf, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-3-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-3-lbv.c
new file mode 100644
index 0000000..d6571be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-3-lbv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int t1, int t2, int t3, int t4, int t5, int t6, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (0, 0, 0, 0, 0, 0, buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-3-nov.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-3-nov.c
new file mode 100644
index 0000000..e42ecba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-3-nov.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int t1, int t2, int t3, int t4, int t5, int t6, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (0, 0, 0, 0, 0, 0, buf, 0);
+  rd (0, 0, 0, 0, 0, 0, buf, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-3-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-3-ubv.c
new file mode 100644
index 0000000..8da6252
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-3-ubv.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int t1, int t2, int t3, int t4, int t5, int t6, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (0, 0, 0, 0, 0, 0, buf, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-4-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-4-lbv.c
new file mode 100644
index 0000000..5a68425
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-4-lbv.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *t1, int *t2, int *t3, int *t4, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf1, buf1, buf1, buf1, buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-4-nov.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-4-nov.c
new file mode 100644
index 0000000..bb2bc46
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-4-nov.c
@@ -0,0 +1,25 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *t1, int *t2, int *t3, int *t4, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf1, buf1, buf1, buf1, buf, 0);
+  rd (buf1, buf1, buf1, buf1, buf, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-4-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-4-ubv.c
new file mode 100644
index 0000000..cf3a5c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-4-ubv.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *t1, int *t2, int *t3, int *t4, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf1, buf1, buf1, buf1, buf, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-5-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-5-lbv.c
new file mode 100644
index 0000000..7c3bd86
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-5-lbv.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *t1, int *t2, int *t3, int *t4, int *t5, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf1, buf1, buf1, buf1, buf1, buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-5-nov.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-5-nov.c
new file mode 100644
index 0000000..27e4a71
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-5-nov.c
@@ -0,0 +1,25 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *t1, int *t2, int *t3, int *t4, int *t5, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf1, buf1, buf1, buf1, buf1, buf, 0);
+  rd (buf1, buf1, buf1, buf1, buf1, buf, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-5-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-5-ubv.c
new file mode 100644
index 0000000..68e2654
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-arg-5-ubv.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *t1, int *t2, int *t3, int *t4, int *t5, int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf1, buf1, buf1, buf1, buf1, buf, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-store-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-store-1-lbv.c
new file mode 100644
index 0000000..bde8c76
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-store-1-lbv.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int *buf1[100];
+int buf2[100];
+
+void wr (int i)
+{
+  buf1[i] = buf2;
+}
+
+int rd(int i, int j)
+{
+  int res = buf1[i][j];
+  printf("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  wr(10);
+  rd(10, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-store-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-store-1-nov.c
new file mode 100644
index 0000000..269e3af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-store-1-nov.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int *buf1[100];
+int buf2[100];
+
+void wr (int i)
+{
+  buf1[i] = buf2;
+}
+
+int rd(int i, int j)
+{
+  int res = buf1[i][j];
+  printf("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  wr(10);
+  rd(10, 0);
+  rd(10, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pointer-store-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/pointer-store-1-ubv.c
new file mode 100644
index 0000000..4c8d45e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pointer-store-1-ubv.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int *buf1[100];
+int buf2[100];
+
+void wr (int i)
+{
+  buf1[i] = buf2;
+}
+
+int rd(int i, int j)
+{
+  int res = buf1[i][j];
+  printf("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  wr(10);
+  rd(10, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-1-lbv.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-1-lbv.cpp
new file mode 100644
index 0000000..ec5f546
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-1-lbv.cpp
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int __attribute((nothrow))
+rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+void set_p (int *&ref)
+{
+  ref = buf;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  set_p (p);
+  rd (p, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-1-nov.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-1-nov.cpp
new file mode 100644
index 0000000..98f1622
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-1-nov.cpp
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int __attribute((nothrow))
+rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+void set_p (int *&ref)
+{
+  ref = buf;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  set_p (p);
+  rd (p, 0);
+  rd (p, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-1-ubv.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-1-ubv.cpp
new file mode 100644
index 0000000..d2135e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-1-ubv.cpp
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int __attribute((nothrow))
+rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+void set_p (int *&ref)
+{
+  ref = buf;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  set_p (p);
+  rd (p, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-2-lbv.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-2-lbv.cpp
new file mode 100644
index 0000000..907cb06
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-2-lbv.cpp
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int __attribute((nothrow))
+rd (int *&p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+void set_p (int *&ref)
+{
+  ref = buf;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  set_p (p);
+  rd (p, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-2-nov.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-2-nov.cpp
new file mode 100644
index 0000000..cdd927c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-2-nov.cpp
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int __attribute((nothrow))
+rd (int *&p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+void set_p (int *&ref)
+{
+  ref = buf;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  set_p (p);
+  rd (p, 0);
+  rd (p, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-2-ubv.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-2-ubv.cpp
new file mode 100644
index 0000000..2f75375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-2-ubv.cpp
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int __attribute((nothrow))
+rd (int *&p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+void set_p (int *&ref)
+{
+  ref = buf;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  set_p (p);
+  rd (p, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-3-lbv.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-3-lbv.cpp
new file mode 100644
index 0000000..1330359
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-3-lbv.cpp
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int (&p)[100], int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-3-nov.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-3-nov.cpp
new file mode 100644
index 0000000..9a55193
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-3-nov.cpp
@@ -0,0 +1,25 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int (&p)[100], int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf, 0);
+  rd (buf, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-3-ubv.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-3-ubv.cpp
new file mode 100644
index 0000000..0a874fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-3-ubv.cpp
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int (&p)[100], int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (buf, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-4-lbv.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-4-lbv.cpp
new file mode 100644
index 0000000..2442c6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-4-lbv.cpp
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int (&p)[100], int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int (&get_buf ()) [100]
+{
+  return buf;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (get_buf (), -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-4-nov.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-4-nov.cpp
new file mode 100644
index 0000000..9646cc0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-4-nov.cpp
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int (&p)[100], int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int (&get_buf ()) [100]
+{
+  return buf;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (get_buf (), 0);
+  rd (get_buf (), 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/reference-4-ubv.cpp b/gcc/testsuite/gcc.target/i386/mpx/reference-4-ubv.cpp
new file mode 100644
index 0000000..da33823
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/reference-4-ubv.cpp
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int rd (int (&p)[100], int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int (&get_buf ()) [100]
+{
+  return buf;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int *p;
+
+  rd (get_buf (), 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-pointer-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/return-pointer-1-lbv.c
new file mode 100644
index 0000000..9a209b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-pointer-1-lbv.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int *_buf1[100];
+int _buf2[100];
+
+int **get_buf1 ()
+{
+  return _buf1;
+}
+
+int *get_buf2 ()
+{
+  return _buf2;
+}
+
+void wr (int i, int **buf1, int *buf2)
+{
+  buf1[i] = buf2;
+}
+
+int rd (int i, int j, int **buf)
+{
+  int res = buf[i][j];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int **buf1 = get_buf1 ();
+  int *buf2 = get_buf2 ();
+  wr(10, buf1, buf2);
+  rd(10, -1, buf1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-pointer-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/return-pointer-1-nov.c
new file mode 100644
index 0000000..62d0501
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-pointer-1-nov.c
@@ -0,0 +1,41 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int *_buf1[100];
+int _buf2[100];
+
+int **get_buf1 ()
+{
+  return _buf1;
+}
+
+int *get_buf2 ()
+{
+  return _buf2;
+}
+
+void wr (int i, int **buf1, int *buf2)
+{
+  buf1[i] = buf2;
+}
+
+int rd (int i, int j, int **buf)
+{
+  int res = buf[i][j];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int **buf1 = get_buf1 ();
+  int *buf2 = get_buf2 ();
+  wr(10, buf1, buf2);
+  rd(10, 0, buf1);
+  rd(10, 99, buf1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-pointer-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/return-pointer-1-ubv.c
new file mode 100644
index 0000000..4658aef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-pointer-1-ubv.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int *_buf1[100];
+int _buf2[100];
+
+int **get_buf1 ()
+{
+  return _buf1;
+}
+
+int *get_buf2 ()
+{
+  return _buf2;
+}
+
+void wr (int i, int **buf1, int *buf2)
+{
+  buf1[i] = buf2;
+}
+
+int rd (int i, int j, int **buf)
+{
+  int res = buf[i][j];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  int **buf1 = get_buf1 ();
+  int *buf2 = get_buf2 ();
+  wr(10, buf1, buf2);
+  rd(10, 100, buf1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-1-lbv.c
new file mode 100644
index 0000000..ef29427
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-1-lbv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-1-nov.c
new file mode 100644
index 0000000..12e1edd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-1-nov.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 0);
+  rd (s, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-1-ubv.c
new file mode 100644
index 0000000..dda908b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-1-ubv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-2-lbv.c
new file mode 100644
index 0000000..bf37066
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-2-lbv.c
@@ -0,0 +1,41 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int *p1;
+} s1;
+
+int buf[100];
+int buf1[10];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  s.p1 = buf1;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-2-nov.c
new file mode 100644
index 0000000..577e3ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-2-nov.c
@@ -0,0 +1,39 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int *p1;
+} s1;
+
+int buf[100];
+int buf1[10];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  s.p1 = buf1;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 0);
+  rd (s, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-2-ubv.c
new file mode 100644
index 0000000..c5a7ad0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-2-ubv.c
@@ -0,0 +1,41 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int *p1;
+} s1;
+
+int buf[100];
+int buf1[10];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  s.p1 = buf1;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-3-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-3-lbv.c
new file mode 100644
index 0000000..1802ca8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-3-lbv.c
@@ -0,0 +1,41 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p1;
+  int *p;
+} s1;
+
+int buf[100];
+int buf1[10];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  s.p1 = buf1;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-3-nov.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-3-nov.c
new file mode 100644
index 0000000..2e5214a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-3-nov.c
@@ -0,0 +1,39 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p1;
+  int *p;
+} s1;
+
+int buf[100];
+int buf1[10];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  s.p1 = buf1;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 0);
+  rd (s, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-3-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-3-ubv.c
new file mode 100644
index 0000000..83b81da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-3-ubv.c
@@ -0,0 +1,41 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p1;
+  int *p;
+} s1;
+
+int buf[100];
+int buf1[10];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  s.p1 = buf1;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-4-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-4-lbv.c
new file mode 100644
index 0000000..7937514
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-4-lbv.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-4-nov.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-4-nov.c
new file mode 100644
index 0000000..352b572
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-4-nov.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 0);
+  rd (s, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-4-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-4-ubv.c
new file mode 100644
index 0000000..14ba0bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-4-ubv.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-5-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-5-lbv.c
new file mode 100644
index 0000000..2bd871a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-5-lbv.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int i1;
+  int i2;
+  int *p;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-5-nov.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-5-nov.c
new file mode 100644
index 0000000..978b493
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-5-nov.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int i1;
+  int i2;
+  int *p;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 0);
+  rd (s, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-5-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-5-ubv.c
new file mode 100644
index 0000000..633e15d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-5-ubv.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int i1;
+  int i2;
+  int *p;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-6-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-6-lbv.c
new file mode 100644
index 0000000..9e2cf2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-6-lbv.c
@@ -0,0 +1,42 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int i1;
+  int i2;
+  int *p;
+  int i3;
+  int i4;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-6-nov.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-6-nov.c
new file mode 100644
index 0000000..f2d60f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-6-nov.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int i1;
+  int i2;
+  int *p;
+  int i3;
+  int i4;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 0);
+  rd (s, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/return-struct-6-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/return-struct-6-ubv.c
new file mode 100644
index 0000000..6370512
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/return-struct-6-ubv.c
@@ -0,0 +1,42 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int i1;
+  int i2;
+  int *p;
+  int i3;
+  int i4;
+} s1;
+
+int buf[100];
+
+struct s1 __attribute__((noinline)) get ()
+{
+  struct s1 s;
+  s.p = buf;
+  return s;
+}
+
+int __attribute__((noinline)) rd (struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = get ();
+
+  rd (s, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/sincos-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/sincos-1-nov.c
new file mode 100644
index 0000000..da5f301a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/sincos-1-nov.c
@@ -0,0 +1,18 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+/* { dg-additional-options "-lm" } */
+
+
+#include "mpx-check.h"
+#include "math.h"
+
+int mpx_test (int argc, const char **argv)
+{
+  double d1, d2;
+  d1 = sin(argc);
+  d2 = cos(argc);
+
+  printf ("%f %f\n", d1, d2);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-array-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/static-array-1-lbv.c
new file mode 100644
index 0000000..cc1cf8d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-array-1-lbv.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  printf("%d\n", buf[-1]);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-array-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/static-array-1-nov.c
new file mode 100644
index 0000000..13d30c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-array-1-nov.c
@@ -0,0 +1,14 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  printf("%d\n", buf[0]);
+  printf("%d\n", buf[99]);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-array-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/static-array-1-ubv.c
new file mode 100644
index 0000000..e3cac3c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-array-1-ubv.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  printf("%d\n", buf[100]);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-1-lbv.c
new file mode 100644
index 0000000..7c0367e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-1-lbv.c
@@ -0,0 +1,18 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p = buf;
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", p[-1]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-1-nov.c
new file mode 100644
index 0000000..0c91615
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-1-nov.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p = buf;
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", p[0]);
+  printf ("%d\n", p[99]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-1-ubv.c
new file mode 100644
index 0000000..a19d927
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-1-ubv.c
@@ -0,0 +1,18 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p = buf;
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", p[100]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-2-lbv.c
new file mode 100644
index 0000000..1ad3be8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-2-lbv.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s {
+  int a;
+  int *p;
+} s;
+
+int buf[100];
+
+struct s s1 = {0, buf};
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", s1.p[-1]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-2-nov.c
new file mode 100644
index 0000000..6ef755f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-2-nov.c
@@ -0,0 +1,22 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s {
+  int a;
+  int *p;
+} s;
+
+int buf[100];
+
+struct s s1 = {0, buf};
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", s1.p[0]);
+  printf ("%d\n", s1.p[99]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-2-ubv.c
new file mode 100644
index 0000000..3681ebe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-2-ubv.c
@@ -0,0 +1,24 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s {
+  int a;
+  int *p;
+} s;
+
+int buf[100];
+
+struct s s1 = {0, buf};
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", s1.p[100]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-3-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-3-lbv.c
new file mode 100644
index 0000000..3aa21ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-3-lbv.c
@@ -0,0 +1,25 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p = buf;
+
+int foo (int i)
+{
+  static int **pp = &p;
+
+  return (*pp)[i];
+}
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", foo (-1));
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-3-nov.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-3-nov.c
new file mode 100644
index 0000000..7bdc5af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-3-nov.c
@@ -0,0 +1,23 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p = buf;
+
+int foo (int i)
+{
+  static int **pp = &p;
+
+  return (*pp)[i];
+}
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", foo (0));
+  printf ("%d\n", foo (99));
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-3-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-3-ubv.c
new file mode 100644
index 0000000..fb8411a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-3-ubv.c
@@ -0,0 +1,25 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p = buf;
+
+int foo (int i)
+{
+  static int **pp = &p;
+
+  return (*pp)[i];
+}
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", foo (100));
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-4-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-4-lbv.c
new file mode 100644
index 0000000..896838e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-4-lbv.c
@@ -0,0 +1,18 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p[1] = { buf };
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", p[0][-1]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-4-nov.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-4-nov.c
new file mode 100644
index 0000000..3bdb5ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-4-nov.c
@@ -0,0 +1,16 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p[1] = { buf };
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", p[0][0]);
+  printf ("%d\n", p[0][99]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-4-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-4-ubv.c
new file mode 100644
index 0000000..47bca2f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-4-ubv.c
@@ -0,0 +1,18 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf[100];
+int *p[1] = { buf };
+
+int mpx_test (int argc, const char *argv[])
+{
+  printf ("%d\n", p[0][100]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-5-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-5-lbv.c
new file mode 100644
index 0000000..bd47a4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-5-lbv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf1[100];
+int buf2[200];
+
+struct s1 {
+  int a;
+  int *p[2];
+} s1;
+
+struct s2 {
+  int a;
+  struct s1 b[2];
+} s2;
+
+struct s2 s = { 1, { {1, { buf1, buf2 }}, {2, { buf2, buf1} } } };
+
+int mpx_test (int argc, const char **argv)
+{
+  printf ("%d\n", s.b[0].p[0][-1]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-5-nov.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-5-nov.c
new file mode 100644
index 0000000..87fe35d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-5-nov.c
@@ -0,0 +1,34 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf1[100];
+int buf2[200];
+
+struct s1 {
+  int a;
+  int *p[2];
+} s1;
+
+struct s2 {
+  int a;
+  struct s1 b[2];
+} s2;
+
+struct s2 s = { 1, { {1, { buf1, buf2 }}, {2, { buf2, buf1} } } };
+
+int mpx_test (int argc, const char **argv)
+{
+  printf ("%d\n", s.b[0].p[0][0]);
+  printf ("%d\n", s.b[0].p[0][99]);
+  printf ("%d\n", s.b[0].p[1][0]);
+  printf ("%d\n", s.b[0].p[1][199]);
+  printf ("%d\n", s.b[1].p[0][0]);
+  printf ("%d\n", s.b[1].p[0][199]);
+  printf ("%d\n", s.b[1].p[1][0]);
+  printf ("%d\n", s.b[1].p[1][99]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-5-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-5-ubv.c
new file mode 100644
index 0000000..7f13625
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-5-ubv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf1[100];
+int buf2[200];
+
+struct s1 {
+  int a;
+  int *p[2];
+} s1;
+
+struct s2 {
+  int a;
+  struct s1 b[2];
+} s2;
+
+struct s2 s = { 1, { {1, { buf1, buf2 }}, {2, { buf2, buf1} } } };
+
+int mpx_test (int argc, const char **argv)
+{
+  printf ("%d\n", s.b[0].p[0][100]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-6-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-6-lbv.c
new file mode 100644
index 0000000..9b90cee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-6-lbv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf1[100];
+int buf2[200];
+
+struct s1 {
+  int a;
+  int *p[2];
+} s1;
+
+struct s2 {
+  int a;
+  struct s1 b[2];
+} s2;
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s2 s = { 1, { {1, { buf1, buf2 }}, {2, { buf2, buf1} } } };
+
+  printf ("%d\n", s.b[0].p[0][-1]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-6-nov.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-6-nov.c
new file mode 100644
index 0000000..a125024
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-6-nov.c
@@ -0,0 +1,28 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf1[100];
+int buf2[200];
+
+struct s1 {
+  int a;
+  int *p[2];
+} s1;
+
+struct s2 {
+  int a;
+  struct s1 b[2];
+} s2;
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s2 s = { 1, { {1, { buf1, buf2 }}, {2, { buf2, buf1} } } };
+
+  printf ("%d\n", s.b[0].p[0][0]);
+  printf ("%d\n", s.b[0].p[0][99]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-init-6-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/static-init-6-ubv.c
new file mode 100644
index 0000000..a60c4e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-init-6-ubv.c
@@ -0,0 +1,30 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf1[100];
+int buf2[200];
+
+struct s1 {
+  int a;
+  int *p[2];
+} s1;
+
+struct s2 {
+  int a;
+  struct s1 b[2];
+} s2;
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s2 s = { 1, { {1, { buf1, buf2 }}, {2, { buf2, buf1} } } };
+
+  printf ("%d\n", s.b[0].p[0][100]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-string-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/static-string-1-lbv.c
new file mode 100644
index 0000000..e244380
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-string-1-lbv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+char *str="dddd";
+
+int foo1 (char** ptr)
+{
+  *ptr=str;
+}
+
+int foo (char *ptr)
+{
+  char *tmp = 0;
+  foo1 (&ptr);
+  tmp = ptr;
+  return tmp[-1];
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  printf ("%d\n", foo ("ddddd"));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-string-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/static-string-1-nov.c
new file mode 100644
index 0000000..d513638
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-string-1-nov.c
@@ -0,0 +1,26 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+char *str="dddd";
+
+int foo1 (char** ptr)
+{
+  *ptr=str;
+}
+
+int foo (char *ptr)
+{
+  char *tmp = 0;
+  foo1 (&ptr);
+  tmp = ptr;
+  return tmp[0] + tmp[4];
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  printf ("%d\n", foo ("ddddd"));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/static-string-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/static-string-1-ubv.c
new file mode 100644
index 0000000..e0f3634
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/static-string-1-ubv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+char *str="dddd";
+
+int foo1 (char** ptr)
+{
+  *ptr=str;
+}
+
+int foo (char *ptr)
+{
+  char *tmp = 0;
+  foo1 (&ptr);
+  tmp = ptr;
+  return tmp[5];
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  printf ("%d\n", foo ("ddddd"));
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-1-lbv.c
new file mode 100644
index 0000000..a9e1890
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-1-lbv.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -51;
+
+  rd (s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-1-nov.c
new file mode 100644
index 0000000..b1cfeac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-1-nov.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -50;
+
+  rd (s);
+
+  s.i1 = 50;
+  s.i2 = 49;
+
+  rd (s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-1-ubv.c
new file mode 100644
index 0000000..c4ca68d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-1-ubv.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = 51;
+
+  rd (s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-10-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-10-lbv.c
new file mode 100644
index 0000000..8375aa1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-10-lbv.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, int *p4, int *p5, int *p6, struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+
+  rd (buf1, buf1, buf1, buf1, buf1, buf1, s, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-10-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-10-nov.c
new file mode 100644
index 0000000..b246448
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-10-nov.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, int *p4, int *p5, int *p6, struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+
+  rd (buf1, buf1, buf1, buf1, buf1, buf1, s, 0);
+  rd (buf1, buf1, buf1, buf1, buf1, buf1, s, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-10-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-10-ubv.c
new file mode 100644
index 0000000..b3b13f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-10-ubv.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, int *p4, int *p5, int *p6, struct s1 s, int i)
+{
+  int res = s.p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+
+  rd (buf1, buf1, buf1, buf1, buf1, buf1, s, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-2-lbv.c
new file mode 100644
index 0000000..d796ced
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-2-lbv.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int i1;
+  int i2;
+  int *p;
+} s1;
+
+int rd (struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -51;
+
+  rd (s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-2-nov.c
new file mode 100644
index 0000000..6a1a087
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-2-nov.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int i1;
+  int i2;
+  int *p;
+} s1;
+
+int rd (struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -50;
+
+  rd (s);
+
+  s.i1 = 50;
+  s.i2 = 49;
+
+  rd (s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-2-ubv.c
new file mode 100644
index 0000000..b285cbc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-2-ubv.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int i1;
+  int i2;
+  int *p;
+} s1;
+
+int rd (struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = 51;
+
+  rd (s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-3-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-3-lbv.c
new file mode 100644
index 0000000..34d4ab1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-3-lbv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -51;
+
+  rd (buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-3-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-3-nov.c
new file mode 100644
index 0000000..8e238ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-3-nov.c
@@ -0,0 +1,39 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -50;
+
+  rd (buf1, s);
+
+  s.i1 = 50;
+  s.i2 = 49;
+
+  rd (buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-3-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-3-ubv.c
new file mode 100644
index 0000000..bd947e5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-3-ubv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = 50;
+
+  rd (buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-4-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-4-lbv.c
new file mode 100644
index 0000000..c0666d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-4-lbv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -51;
+
+  rd (buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-4-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-4-nov.c
new file mode 100644
index 0000000..17366c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-4-nov.c
@@ -0,0 +1,39 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -50;
+
+  rd (buf1, buf1, s);
+
+  s.i1 = 50;
+  s.i2 = 49;
+
+  rd (buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-4-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-4-ubv.c
new file mode 100644
index 0000000..f2f8281
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-4-ubv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = 50;
+
+  rd (buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-5-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-5-lbv.c
new file mode 100644
index 0000000..357bb6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-5-lbv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -51;
+
+  rd (buf1, buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-5-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-5-nov.c
new file mode 100644
index 0000000..a4acd38
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-5-nov.c
@@ -0,0 +1,39 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -50;
+
+  rd (buf1, buf1, buf1, s);
+
+  s.i1 = 50;
+  s.i2 = 49;
+
+  rd (buf1, buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-5-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-5-ubv.c
new file mode 100644
index 0000000..c94ae1c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-5-ubv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = 50;
+
+  rd (buf1, buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-6-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-6-lbv.c
new file mode 100644
index 0000000..ceee8d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-6-lbv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, int *p4, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -51;
+
+  rd (buf1, buf1, buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-6-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-6-nov.c
new file mode 100644
index 0000000..913f5a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-6-nov.c
@@ -0,0 +1,39 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, int *p4, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -50;
+
+  rd (buf1, buf1, buf1, buf1, s);
+
+  s.i1 = 50;
+  s.i2 = 49;
+
+  rd (buf1, buf1, buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-6-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-6-ubv.c
new file mode 100644
index 0000000..f92476a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-6-ubv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, int *p4, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = 50;
+
+  rd (buf1, buf1, buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-7-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-7-lbv.c
new file mode 100644
index 0000000..b0ecc17
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-7-lbv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, int *p4, int *p5, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -51;
+
+  rd (buf1, buf1, buf1, buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-7-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-7-nov.c
new file mode 100644
index 0000000..ec63dc7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-7-nov.c
@@ -0,0 +1,39 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, int *p4, int *p5, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = -50;
+
+  rd (buf1, buf1, buf1, buf1, buf1, s);
+
+  s.i1 = 50;
+  s.i2 = 49;
+
+  rd (buf1, buf1, buf1, buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-7-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-7-ubv.c
new file mode 100644
index 0000000..c9e6822
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-7-ubv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  int *p;
+  int i1;
+  int i2;
+} s1;
+
+int rd (int *p1, int *p2, int *p3, int *p4, int *p5, struct s1 s)
+{
+  int res = s.p[s.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.p = buf;
+  s.i1 = 50;
+  s.i2 = 50;
+
+  rd (buf1, buf1, buf1, buf1, buf1, s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-8-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-8-lbv.c
new file mode 100644
index 0000000..58d03e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-8-lbv.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1 {
+  int *p[2];
+} s1;
+
+int rd (struct s1 s, int i)
+{
+  int res = s.p[0][i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = { {buf, buf1} };
+
+  rd (s, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-8-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-8-nov.c
new file mode 100644
index 0000000..d9072ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-8-nov.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1 {
+  int *p[2];
+} s1;
+
+int rd (struct s1 s, int i)
+{
+  int res = s.p[0][i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = { {buf, buf1} };
+
+  rd (s, 0);
+  rd (s, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-8-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-8-ubv.c
new file mode 100644
index 0000000..fdcfc9f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-8-ubv.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1 {
+  int *p[2];
+} s1;
+
+int rd (struct s1 s, int i)
+{
+  int res = s.p[0][i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = { {buf, buf1} };
+
+  rd (s, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-9-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-9-lbv.c
new file mode 100644
index 0000000..acce183
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-9-lbv.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1 {
+  int *p[2];
+} s1;
+
+int rd (struct s1 s, int i)
+{
+  int res = s.p[1][i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = { {buf, buf1} };
+
+  rd (s, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-9-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-9-nov.c
new file mode 100644
index 0000000..03ce668
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-9-nov.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1 {
+  int *p[2];
+} s1;
+
+int rd (struct s1 s, int i)
+{
+  int res = s.p[1][i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = { {buf, buf1} };
+
+  rd (s, 0);
+  rd (s, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-arg-9-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-9-ubv.c
new file mode 100644
index 0000000..449b2c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-arg-9-ubv.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1 {
+  int *p[2];
+} s1;
+
+int rd (struct s1 s, int i)
+{
+  int res = s.p[1][i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s = { {buf, buf1} };
+
+  rd (s, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-copy-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-1-lbv.c
new file mode 100644
index 0000000..3f1ac74
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-1-lbv.c
@@ -0,0 +1,32 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf1[100];
+int buf2[200];
+
+struct s1 {
+  int a;
+  int *p[2];
+} s1;
+
+struct s2 {
+  int a;
+  struct s1 b[2];
+} s2;
+
+struct s2 s = { 1, { {1, { buf1, buf2 }}, {2, { buf2, buf1} } } };
+
+int mpx_test (int argc, const char *argv[])
+{
+  struct s2 ss = s;
+
+  printf ("%d\n", ss.b[0].p[0][-1]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-copy-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-1-nov.c
new file mode 100644
index 0000000..5a709bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-1-nov.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+int buf1[100];
+int buf2[200];
+
+struct s1 {
+  int a;
+  int *p[2];
+} s1;
+
+struct s2 {
+  int a;
+  struct s1 b[2];
+} s2;
+
+struct s2 s = { 1, { {1, { buf1, buf2 }}, {2, { buf2, buf1} } } };
+
+int mpx_test (int argc, const char *argv[])
+{
+  struct s2 ss = s;
+
+  printf("%d\n", ss.b[0].p[0][0]);
+  printf("%d\n", ss.b[0].p[0][99]);
+  printf("%d\n", ss.b[0].p[1][0]);
+  printf("%d\n", ss.b[0].p[1][199]);
+  printf("%d\n", ss.b[1].p[0][0]);
+  printf("%d\n", ss.b[1].p[0][199]);
+  printf("%d\n", ss.b[1].p[1][0]);
+  printf("%d\n", ss.b[1].p[1][99]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-copy-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-1-ubv.c
new file mode 100644
index 0000000..b0fe8f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-1-ubv.c
@@ -0,0 +1,32 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+int buf1[100];
+int buf2[200];
+
+struct s1 {
+  int a;
+  int *p[2];
+} s1;
+
+struct s2 {
+  int a;
+  struct s1 b[2];
+} s2;
+
+struct s2 s = { 1, { {1, { buf1, buf2 }}, {2, { buf2, buf1} } } };
+
+int mpx_test (int argc, const char *argv[])
+{
+  struct s2 ss = s;
+
+  printf ("%d\n", ss.b[0].p[0][100]);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-copy-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-2-lbv.c
new file mode 100644
index 0000000..0cb6440
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-2-lbv.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (void *p, int k)
+{
+  struct S *s = (struct S*)p;
+  int res = s->b[k];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S s;
+
+  foo (&s.a, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-copy-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-2-nov.c
new file mode 100644
index 0000000..01f5b67
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-2-nov.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (void *p, int k)
+{
+  struct S *s = (struct S*)p;
+  int res = s->b[k];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S s;
+
+  foo (&s.a, 0);
+  foo (&s.a, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/struct-copy-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-2-ubv.c
new file mode 100644
index 0000000..c500bb4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/struct-copy-2-ubv.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S {
+  int a;
+  int b[100];
+  int c;
+} S;
+
+int foo (void *p, int k)
+{
+  struct S *s = (struct S*)p;
+  int res = s->b[k];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S s;
+
+  foo (&s.a, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/thread-local-var-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/thread-local-var-1-lbv.c
new file mode 100644
index 0000000..3275fe0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/thread-local-var-1-lbv.c
@@ -0,0 +1,34 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-lpthread" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "pthread.h"
+
+__thread int prebuf[100];
+__thread int buf[100];
+__thread int postbuf[100];
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf("%d\n", res);
+  return res;
+}
+
+void *thred_func (void *ptr)
+{
+  rd (buf, -1);
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  pthread_t thread;
+  pthread_create (&thread, NULL, thred_func, 0);
+  pthread_join (thread, NULL);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/thread-local-var-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/thread-local-var-1-nov.c
new file mode 100644
index 0000000..2e0483b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/thread-local-var-1-nov.c
@@ -0,0 +1,33 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-lpthread" } */
+
+
+#include "mpx-check.h"
+#include "pthread.h"
+
+__thread int prebuf[100];
+__thread int buf[100];
+__thread int postbuf[100];
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf("%d\n", res);
+  return res;
+}
+
+void *thred_func (void *ptr)
+{
+  rd (buf, 0);
+  rd (buf, 99);
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  pthread_t thread;
+  pthread_create (&thread, NULL, thred_func, 0);
+  pthread_join (thread, NULL);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/thread-local-var-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/thread-local-var-1-ubv.c
new file mode 100644
index 0000000..86116e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/thread-local-var-1-ubv.c
@@ -0,0 +1,34 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-lpthread" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "pthread.h"
+
+__thread int prebuf[100];
+__thread int buf[100];
+__thread int postbuf[100];
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf("%d\n", res);
+  return res;
+}
+
+void *thred_func (void *ptr)
+{
+  rd (buf, 100);
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  pthread_t thread;
+  pthread_create (&thread, NULL, thred_func, 0);
+  pthread_join (thread, NULL);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/union-arg-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/union-arg-1-lbv.c
new file mode 100644
index 0000000..c255982
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/union-arg-1-lbv.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  union {
+    int i1;
+    int i3;
+  } v;
+  int i2;
+  union {
+    int *p;
+    int p2;
+  } u;
+} s1;
+
+int rd (struct s1 s)
+{
+  int res = s.u.p[s.v.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.u.p = buf;
+  s.v.i1 = 50;
+  s.i2 = -51;
+
+  rd (s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/union-arg-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/union-arg-1-nov.c
new file mode 100644
index 0000000..f96689f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/union-arg-1-nov.c
@@ -0,0 +1,45 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct s1
+{
+  union {
+    int i1;
+    int i3;
+  } v;
+  int i2;
+  union {
+    int *p;
+    int p2;
+  } u;
+} s1;
+
+int rd (struct s1 s)
+{
+  int res = s.u.p[s.v.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.u.p = buf;
+  s.v.i1 = 50;
+  s.i2 = -50;
+
+  rd (s);
+
+  s.v.i1 = 50;
+  s.i2 = 49;
+
+  rd (s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/union-arg-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/union-arg-1-ubv.c
new file mode 100644
index 0000000..6d65e5a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/union-arg-1-ubv.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct s1
+{
+  union {
+    int i1;
+    int i3;
+  } v;
+  int i2;
+  union {
+    int *p;
+    int p2;
+  } u;
+} s1;
+
+int rd (struct s1 s)
+{
+  int res = s.u.p[s.v.i1 + s.i2];
+  printf ("%d\n", res);
+  return res;
+}
+
+int buf[100];
+int buf1[10];
+
+int mpx_test (int argc, const char **argv)
+{
+  struct s1 s;
+  s.u.p = buf;
+  s.v.i1 = 50;
+  s.i2 = 50;
+
+  rd (s);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-1-lbv.c
new file mode 100644
index 0000000..5aa6007
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-1-lbv.c
@@ -0,0 +1,42 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-Wno-attributes" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include <stdarg.h>
+
+int
+foo2 (int i1, int *p1, ...)
+{
+  va_list argp;
+  int i;
+  int res;
+
+  va_start(argp, p1);
+  i = va_arg(argp, int);
+
+  res = p1[i + i1];
+  printf("%d\n", res);
+
+  return res;
+}
+
+static __attribute__((always_inline)) int
+foo1 (int *p1, ...)
+{
+  return foo2 (10, p1, __va_arg_pack ());
+}
+
+int prebuf[100];
+int buf[100];
+int postbuf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  foo1 (buf, -11);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-1-nov.c
new file mode 100644
index 0000000..55c65d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-1-nov.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-Wno-attributes" } */
+
+#include "mpx-check.h"
+#include <stdarg.h>
+
+int
+foo2 (int i1, int *p1, ...)
+{
+  va_list argp;
+  int i;
+  int res;
+
+  va_start(argp, p1);
+  i = va_arg(argp, int);
+
+  res = p1[i + i1];
+  printf("%d\n", res);
+
+  return res;
+}
+
+static __attribute__((always_inline)) int
+foo1 (int *p1, ...)
+{
+  return foo2 (10, p1, __va_arg_pack ());
+}
+
+int prebuf[100];
+int buf[100];
+int postbuf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  foo1 (buf, 89);
+  foo1 (buf, -9);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-1-ubv.c
new file mode 100644
index 0000000..11b498e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-1-ubv.c
@@ -0,0 +1,42 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-Wno-attributes" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include <stdarg.h>
+
+int
+foo2 (int i1, int *p1, ...)
+{
+  va_list argp;
+  int i;
+  int res;
+
+  va_start(argp, p1);
+  i = va_arg(argp, int);
+
+  res = p1[i + i1];
+  printf("%d\n", res);
+
+  return res;
+}
+
+static __attribute__((always_inline)) int
+foo1 (int *p1, ...)
+{
+  return foo2 (10, p1, __va_arg_pack ());
+}
+
+int prebuf[100];
+int buf[100];
+int postbuf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  foo1 (buf, 90);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-2-lbv.c
new file mode 100644
index 0000000..9f1941d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-2-lbv.c
@@ -0,0 +1,45 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-Wno-attributes" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include <stdarg.h>
+
+int
+foo2 (int i1, int *p1, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start(argp, p1);
+  p = va_arg(argp, int *);
+  i = va_arg(argp, int);
+
+  res = p[i + i1];
+  printf("%d\n", res);
+
+  return res;
+}
+
+static __attribute__((always_inline)) int
+foo1 (int *p1, ...)
+{
+  return foo2 (10, p1, __va_arg_pack ());
+}
+
+int prebuf[100];
+int buf[100];
+int buf1[100];
+int postbuf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  foo1 (buf, buf1, -11);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-2-nov.c
new file mode 100644
index 0000000..903afbc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-2-nov.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-Wno-attributes" } */
+
+#include "mpx-check.h"
+#include <stdarg.h>
+
+int
+foo2 (int i1, int *p1, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start(argp, p1);
+  p = va_arg(argp, int *);
+  i = va_arg(argp, int);
+
+  res = p[i + i1];
+  printf("%d\n", res);
+
+  return res;
+}
+
+static __attribute__((always_inline)) int
+foo1 (int *p1, ...)
+{
+  return foo2 (10, p1, __va_arg_pack ());
+}
+
+int prebuf[100];
+int buf[100];
+int buf1[100];
+int postbuf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  foo1 (buf, buf1, 89);
+  foo1 (buf, buf1, -9);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-2-ubv.c
new file mode 100644
index 0000000..f5d842a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/va-arg-pack-2-ubv.c
@@ -0,0 +1,45 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+/* { dg-additional-options "-Wno-attributes" } */
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include <stdarg.h>
+
+int
+foo2 (int i1, int *p1, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start(argp, p1);
+  p = va_arg(argp, int *);
+  i = va_arg(argp, int);
+
+  res = p[i + i1];
+  printf("%d\n", res);
+
+  return res;
+}
+
+static __attribute__((always_inline)) int
+foo1 (int *p1, ...)
+{
+  return foo2 (10, p1, __va_arg_pack ());
+}
+
+int prebuf[100];
+int buf[100];
+int buf1[100];
+int postbuf[100];
+
+int mpx_test (int argc, const char **argv)
+{
+  foo1 (buf, buf1, 90);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-1-lbv.c
new file mode 100644
index 0000000..89faa92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-1-lbv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 0, buf, -1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-1-nov.c
new file mode 100644
index 0000000..e1e12a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-1-nov.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 0, buf, 0);
+  rd (buf1, 0, buf, 99);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-1-ubv.c
new file mode 100644
index 0000000..14206a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-1-ubv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 0, buf, 100);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-2-lbv.c
new file mode 100644
index 0000000..8af925f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-2-lbv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 1, buf1, buf, -1, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-2-nov.c
new file mode 100644
index 0000000..5c2f422
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-2-nov.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 1, buf1, buf, 0, buf1);
+  rd (buf1, 1, buf1, buf, 99, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-2-ubv.c
new file mode 100644
index 0000000..b446371
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-2-ubv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 1, buf1, buf, 100, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-3-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-3-lbv.c
new file mode 100644
index 0000000..b1f9f24
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-3-lbv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 2, buf1, buf1, buf, -1, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-3-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-3-nov.c
new file mode 100644
index 0000000..93f9eb8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-3-nov.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 2, buf1, buf1, buf, 0, buf1);
+  rd (buf1, 2, buf1, buf1, buf, 99, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-3-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-3-ubv.c
new file mode 100644
index 0000000..dddf356
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-3-ubv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 2, buf1, buf1, buf, 100, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-4-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-4-lbv.c
new file mode 100644
index 0000000..274ccc2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-4-lbv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 3, buf1, buf1, buf1, buf, -1, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-4-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-4-nov.c
new file mode 100644
index 0000000..5412d11
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-4-nov.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 3, buf1, buf1, buf1, buf, 0, buf1);
+  rd (buf1, 3, buf1, buf1, buf1, buf, 99, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-4-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-4-ubv.c
new file mode 100644
index 0000000..e8f06e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-4-ubv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 3, buf1, buf1, buf1, buf, 100, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-5-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-5-lbv.c
new file mode 100644
index 0000000..1dae013
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-5-lbv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 4, buf1, buf1, buf1, buf1, buf, -1, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-5-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-5-nov.c
new file mode 100644
index 0000000..bd15e0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-5-nov.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 4, buf1, buf1, buf1, buf1, buf, 0, buf1);
+  rd (buf1, 4, buf1, buf1, buf1, buf1, buf, 99, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-5-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-5-ubv.c
new file mode 100644
index 0000000..de3721d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-5-ubv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int
+rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 4, buf1, buf1, buf1, buf1, buf, 100, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-6-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-6-lbv.c
new file mode 100644
index 0000000..822d32a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-6-lbv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pp, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+  int n = 4;
+
+  va_start (argp, pp);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, buf1, buf1, buf1, buf1, buf, -1, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-6-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-6-nov.c
new file mode 100644
index 0000000..c5c4b12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-6-nov.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pp, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+  int n = 4;
+
+  va_start (argp, pp);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, buf1, buf1, buf1, buf1, buf, 0, buf1);
+  rd (buf1, buf1, buf1, buf1, buf1, buf, 99, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-6-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-6-ubv.c
new file mode 100644
index 0000000..635a48f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-6-ubv.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pp, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+  int n = 4;
+
+  va_start (argp, pp);
+  for (; n > 0; n--)
+    va_arg (argp, int *);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, buf1, buf1, buf1, buf1, buf, 100, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-7-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-7-lbv.c
new file mode 100644
index 0000000..1121577
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-7-lbv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, double);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 2, 10.0d, 10.0d, buf, -1, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-7-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-7-nov.c
new file mode 100644
index 0000000..525a93d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-7-nov.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, double);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 2, 10.0d, 10.0d, buf, 0, buf1);
+  rd (buf1, 2, 10.0d, 10.0d, buf, 99, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-7-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-7-ubv.c
new file mode 100644
index 0000000..0e8d21e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-7-ubv.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pppp, int n, ...)
+{
+  va_list argp;
+  int *p;
+  int i;
+  int res;
+
+  va_start (argp, n);
+  for (; n > 0; n--)
+    va_arg (argp, double);
+  p = va_arg (argp, int *);
+  i = va_arg (argp, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  rd (buf1, 2, 10.0d, 10.0d, buf, 100, buf1);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-8-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-8-lbv.c
new file mode 100644
index 0000000..bb58ac5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-8-lbv.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include <stdarg.h>
+
+int buf[100];
+int buf1[10];
+
+void vararg (int *p, va_list al)
+{
+  int i;
+  int res;
+
+  p = va_arg (al, int *);
+  i = va_arg (al, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+}
+
+void foo (int *p, ...)
+{
+  va_list args;
+
+  va_start (args, p);
+  vararg (p, args);
+  va_end (args);
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (buf1, buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-8-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-8-nov.c
new file mode 100644
index 0000000..59596f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-8-nov.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+#include <stdarg.h>
+
+int buf[100];
+int buf1[10];
+
+void vararg (int *p, va_list al)
+{
+  int i;
+  int res;
+
+  p = va_arg (al, int *);
+  i = va_arg (al, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+}
+
+void foo (int *p, ...)
+{
+  va_list args;
+
+  va_start (args, p);
+  vararg (p, args);
+  va_end (args);
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (buf1, buf, 0);
+  foo (buf1, buf, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vararg-8-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vararg-8-ubv.c
new file mode 100644
index 0000000..c03bcef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vararg-8-ubv.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+#include <stdarg.h>
+
+int buf[100];
+int buf1[10];
+
+void vararg (int *p, va_list al)
+{
+  int i;
+  int res;
+
+  p = va_arg (al, int *);
+  i = va_arg (al, int);
+
+  res = p[i];
+  printf ("%d\n", res);
+}
+
+void foo (int *p, ...)
+{
+  va_list args;
+
+  va_start (args, p);
+  vararg (p, args);
+  va_end (args);
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  foo (buf1, buf, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vla-1-lbv.c
new file mode 100644
index 0000000..1994df9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vla-1-lbv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S
+{
+  int a;
+  int p[0];
+};
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
+  rd (s->p, -2);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vla-1-nov.c
new file mode 100644
index 0000000..1a82849
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vla-1-nov.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct S
+{
+  int a;
+  int p[0];
+};
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
+  rd (s->p, 0);
+  rd (s->p, 99);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vla-1-ubv.c
new file mode 100644
index 0000000..b0f6d45
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vla-1-ubv.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct S
+{
+  int a;
+  int p[0];
+};
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+  struct S *s = (struct S *)alloca (sizeof(struct S) + sizeof (int)*100);
+  rd (s->p, 100);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/vla-2-lbv.c
new file mode 100644
index 0000000..128f139
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vla-2-lbv.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct Foo {
+  int buf[10] __attribute__((bnd_variable_size));
+};
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv) {
+  struct Foo *foo = (struct Foo *) alloca (20 * sizeof(int));
+
+  rd (foo->buf, -1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/vla-2-nov.c
new file mode 100644
index 0000000..2469b7d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vla-2-nov.c
@@ -0,0 +1,25 @@ 
+/* { dg-do run } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#include "mpx-check.h"
+
+struct Foo {
+  int buf[10] __attribute__((bnd_variable_size));
+};
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv) {
+  struct Foo *foo = (struct Foo *) alloca (20 * sizeof(int));
+
+  rd (foo->buf, 0);
+  rd (foo->buf, 19);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/vla-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/vla-2-ubv.c
new file mode 100644
index 0000000..63a6b27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/vla-2-ubv.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-shouldfail "bounds violation" } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+
+#define SHOULDFAIL
+
+#include "mpx-check.h"
+
+struct Foo {
+  int buf[10] __attribute__((bnd_variable_size));
+};
+
+int rd (int *p, int i)
+{
+  int res = p[i];
+  printf ("%d\n", res);
+  return res;
+}
+
+int mpx_test (int argc, const char **argv) {
+  struct Foo *foo = (struct Foo *) alloca (20 * sizeof(int));
+
+  rd (foo->buf, 20);
+
+  return 0;
+}
diff --git a/gcc/testsuite/lib/mpx-dg.exp b/gcc/testsuite/lib/mpx-dg.exp
index de7eba8..ddedf09 100644
--- a/gcc/testsuite/lib/mpx-dg.exp
+++ b/gcc/testsuite/lib/mpx-dg.exp
@@ -22,3 +22,103 @@  proc check_effective_target_mpx {} {
 	int *foo (int *arg) { return arg; }
     } "-fcheck-pointer-bounds -mmpx"]
 }
+
+#
+# mpx_link_flags -- compute library path and flags to find libmpx.
+#
+
+proc mpx_link_flags { paths } {
+    global srcdir
+    global ld_library_path
+    global shlib_ext
+    global mpx_saved_library_path
+
+    set gccpath ${paths}
+    set flags ""
+
+    set shlib_ext [get_shlib_extension]
+    set mpx_saved_library_path $ld_library_path
+
+    if { $gccpath != "" } {
+      if { [file exists "${gccpath}/libmpx/mpxrt/.libs/libmpx.a"]
+	   || [file exists "${gccpath}/libmpx/mpxrt/.libs/libmpx.${shlib_ext}"] } {
+	  append flags " -B${gccpath}/libmpx/ "
+	  append flags " -B${gccpath}/libmpx/mpxrt "
+	  append flags " -L${gccpath}/libmpx/mpxrt/.libs "
+	  append ld_library_path ":${gccpath}/libmpx/mpxrt/.libs"
+      }
+    } else {
+      global tool_root_dir
+
+      set libmpx [lookfor_file ${tool_root_dir} libmpx]
+      if { $libmpx != "" } {
+	  append flags "-L${libmpx} "
+	  append ld_library_path ":${libmpx}"
+      }
+    }
+
+    set_ld_library_path_env_vars
+
+    return "$flags"
+}
+
+#
+# mpx_init -- called at the start of each subdir of tests
+#
+
+proc mpx_init { args } {
+    global TEST_ALWAYS_FLAGS
+    global ALWAYS_CXXFLAGS
+    global TOOL_OPTIONS
+    global mpx_saved_TEST_ALWAYS_FLAGS
+    global mpx_saved_ALWAYS_CXXFLAGS
+
+    setenv CHKP_RT_MODE "stop"
+
+    set link_flags ""
+    if ![is_remote host] {
+	if [info exists TOOL_OPTIONS] {
+	    set link_flags "[mpx_link_flags [get_multilibs ${TOOL_OPTIONS}]]"
+	} else {
+	    set link_flags "[mpx_link_flags [get_multilibs]]"
+	}
+    }
+
+    if [info exists TEST_ALWAYS_FLAGS] {
+	set mpx_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
+    }
+    if [info exists ALWAYS_CXXFLAGS] {
+	set mpx_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS
+	set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
+    } else {
+	if [info exists TEST_ALWAYS_FLAGS] {
+	    set TEST_ALWAYS_FLAGS "$link_flags $TEST_ALWAYS_FLAGS"
+	} else {
+	    set TEST_ALWAYS_FLAGS "$link_flags"
+	}
+    }
+}
+
+#
+# mpx_finish -- called at the end of each subdir of tests
+#
+
+proc mpx_finish { args } {
+    global TEST_ALWAYS_FLAGS
+    global mpx_saved_TEST_ALWAYS_FLAGS
+    global mpx_saved_ALWAYS_CXXFLAGS
+    global mpx_saved_library_path
+    global ld_library_path
+
+    if [info exists mpx_saved_ALWAYS_CXXFLAGS ] {
+	set ALWAYS_CXXFLAGS $mpx_saved_ALWAYS_CXXFLAGS
+    } else {
+	if [info exists mpx_saved_TEST_ALWAYS_FLAGS] {
+	    set TEST_ALWAYS_FLAGS $mpx_saved_TEST_ALWAYS_FLAGS
+	} else {
+	    unset TEST_ALWAYS_FLAGS
+	}
+    }
+    set ld_library_path $mpx_saved_library_path
+    set_ld_library_path_env_vars
+}