| .. | .. |
|---|
| 127 | 127 | * Shared functions to include for inlining |
|---|
| 128 | 128 | *********************************************/ |
|---|
| 129 | 129 | ZSTD_STATIC void ZSTD_copy8(void *dst, const void *src) { |
|---|
| 130 | | - memcpy(dst, src, 8); |
|---|
| 130 | + /* |
|---|
| 131 | + * zstd relies heavily on gcc being able to analyze and inline this |
|---|
| 132 | + * memcpy() call, since it is called in a tight loop. Preboot mode |
|---|
| 133 | + * is compiled in freestanding mode, which stops gcc from analyzing |
|---|
| 134 | + * memcpy(). Use __builtin_memcpy() to tell gcc to analyze this as a |
|---|
| 135 | + * regular memcpy(). |
|---|
| 136 | + */ |
|---|
| 137 | + __builtin_memcpy(dst, src, 8); |
|---|
| 131 | 138 | } |
|---|
| 132 | 139 | /*! ZSTD_wildcopy() : |
|---|
| 133 | 140 | * custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */ |
|---|
| .. | .. |
|---|
| 137 | 144 | const BYTE* ip = (const BYTE*)src; |
|---|
| 138 | 145 | BYTE* op = (BYTE*)dst; |
|---|
| 139 | 146 | BYTE* const oend = op + length; |
|---|
| 140 | | - /* Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81388. |
|---|
| 147 | +#if defined(GCC_VERSION) && GCC_VERSION >= 70000 && GCC_VERSION < 70200 |
|---|
| 148 | + /* |
|---|
| 149 | + * Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81388. |
|---|
| 141 | 150 | * Avoid the bad case where the loop only runs once by handling the |
|---|
| 142 | 151 | * special case separately. This doesn't trigger the bug because it |
|---|
| 143 | 152 | * doesn't involve pointer/integer overflow. |
|---|
| 144 | 153 | */ |
|---|
| 145 | 154 | if (length <= 8) |
|---|
| 146 | 155 | return ZSTD_copy8(dst, src); |
|---|
| 156 | +#endif |
|---|
| 147 | 157 | do { |
|---|
| 148 | 158 | ZSTD_copy8(op, ip); |
|---|
| 149 | 159 | op += 8; |
|---|