diff --git a/src/common/pg_lzcompress.c b/src/common/pg_lzcompress.c
index 97b0e40e40..b4d0f255bc 100644
--- a/src/common/pg_lzcompress.c
+++ b/src/common/pg_lzcompress.c
@@ -731,15 +731,30 @@ pglz_decompress(const char *source, int32 slen, char *dest,
 
 				/*
 				 * Now we copy the bytes specified by the tag from OUTPUT to
-				 * OUTPUT. It is dangerous and platform dependent to use
-				 * memcpy() here, because the copied areas could overlap
-				 * extremely!
+				 * OUTPUT. The copied areas could overlap, to preven possible
+				 * uncertanity, we copy only non-overlapping regions.
 				 */
 				len = Min(len, destend - dp);
-				while (len--)
+				if (len > 8)
 				{
-					*dp = dp[-off];
-					dp++;
+					while (off <= len)
+					{
+						memcpy(dp, dp - off, off);
+						len -= off;
+						dp+=off;
+						off *= 2;
+					}
+					memcpy(dp, dp - off, len);
+					dp+=len;
+				}
+				else
+				{
+					/* use byte-loop for small matches */
+					while (len--)
+					{
+						*dp = dp[-off];
+						dp++;
+					}
 				}
 			}
 			else
