diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e9dca619baa..c57f46eac80 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-12-10 Eric Botcazou + + PR target/34403 + * config/i386/i386.c (ix86_expand_movmem): Punt if the count is large. + (ix86_expand_setmem): Likewise. + 2007-12-10 Kenneth Zadeck PR rtl-optimization/34302 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9d2c14438a9..ebbf48957ba 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -15282,7 +15282,7 @@ smallest_pow2_greater_than (int val) } /* Expand string move (memcpy) operation. Use i386 string operations when - profitable. expand_clrmem contains similar code. The code depends upon + profitable. expand_setmem contains similar code. The code depends upon architecture, block size and alignment, but always has the same overall structure: @@ -15333,6 +15333,10 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp, if (CONST_INT_P (expected_size_exp) && count == 0) expected_size = INTVAL (expected_size_exp); + /* Make sure we don't need to care about overflow later on. */ + if (count > ((unsigned HOST_WIDE_INT) 1 << 30)) + return 0; + /* Step 0: Decide on preferred algorithm, desired alignment and size of chunks to be copied by main loop. */ @@ -15657,6 +15661,10 @@ ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp, rtx align_exp, if (CONST_INT_P (expected_size_exp) && count == 0) expected_size = INTVAL (expected_size_exp); + /* Make sure we don't need to care about overflow later on. */ + if (count > ((unsigned HOST_WIDE_INT) 1 << 30)) + return 0; + /* Step 0: Decide on preferred algorithm, desired alignment and size of chunks to be copied by main loop. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2f438dae809..8ff13b4fb12 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-12-10 Eric Botcazou + + * g++.dg/opt/memcpy1.C: New test. + 2007-12-10 Tobias Burnus PR fortran/34425 diff --git a/gcc/testsuite/g++.dg/opt/memcpy1.C b/gcc/testsuite/g++.dg/opt/memcpy1.C new file mode 100644 index 00000000000..f9887ee2314 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/memcpy1.C @@ -0,0 +1,79 @@ +// PR target/34403 +// Origin: Martin Michlmayr + +// { dg-do compile } +// { dg-options "-O" } + +typedef unsigned char uint8_t; +typedef uint8_t uint8; +typedef long unsigned int size_t; +class csVector2 +{ +public:float x; +}; +class csBox2 +{ +}; +struct iBase +{ +}; +struct iClipper2D:public virtual iBase +{ +}; +template < class Class > class scfImplementation:public virtual iBase +{ +}; +template < class Class, class I1 > class scfImplementation1:public +scfImplementation < Class >, + public I1 +{ +}; +class csClipper:public scfImplementation1 < csClipper, iClipper2D > +{ +}; +class csBoxClipper:public csClipper +{ + csBox2 region; + virtual uint8 Clip (csVector2 * InPolygon, size_t InCount, + csVector2 * OutPolygon, size_t & OutCount); +}; +struct StatusOutputNone +{ +}; +namespace CS +{ + template < typename BoxTest, typename StatusOutput > class BoxClipper + { + BoxTest boxTest; + StatusOutput statOut; + const csBox2 & region; + csVector2 *InP; + size_t InV; + csVector2 *OutP; + size_t OutV; + public: BoxClipper (const BoxTest & boxTest, const StatusOutput & statOut, + const csBox2 & region, csVector2 * InP, size_t InV, + csVector2 * OutP):boxTest (boxTest), statOut (statOut), + region (region), InP (InP), InV (InV), OutP (OutP), OutV (-1) + { + } + uint8 Clip () + { + __builtin_memcpy (this->OutP, InP, OutV * sizeof (csVector2)); + } + }; +} +struct BoxTestAll +{ +}; +uint8 +csBoxClipper::Clip (csVector2 * InPolygon, size_t InCount, + csVector2 * OutPolygon, size_t & OutCount) +{ + BoxTestAll b; + StatusOutputNone n; + CS::BoxClipper < BoxTestAll, StatusOutputNone > boxClip (b, n, region, + InPolygon, InCount, + OutPolygon); + uint8 Clipped = boxClip.Clip (); +}