The underlying element type has always a size of 32B, so that the pointer is always at least 16B aligned. Clang uses this to upgrade the (inlined) memset to aligned stores. GCC doesn't (it does it only when the alignment hint is provided via __builtin_assume_aligned).
Showing the changes to libavcodec (1 of 1 file). Show all
Unified · Split
| @@ -504,11 +504,13 @@ void ff_clean_intra_table_entries(MpegEncContext *s) · 503 unmodified lines | ||
| 504 | 504 | dc_val[uxy] = |
| 505 | 505 | dc_val[vxy] = 1024; |
| 506 | 506 | /* ac pred */ |
| 507 | − memset(s->ac_val[0][xy ], 0, 32 * sizeof(int16_t)); | |
| 508 | − memset(s->ac_val[0][xy + wrap], 0, 32 * sizeof(int16_t)); | |
| 507 | + int16_t (*ac_val)[16] = s->ac_val[0]; | |
| 508 | + av_assume(!((uintptr_t)ac_val & 0xF)); | |
| 509 | + memset(ac_val[xy ], 0, 2 * sizeof(*ac_val)); | |
| 510 | + memset(ac_val[xy + wrap], 0, 2 * sizeof(*ac_val)); | |
| 509 | 511 | /* ac pred */ |
| 510 | − memset(s->ac_val[0][uxy], 0, 16 * sizeof(int16_t)); | |
| 511 | − memset(s->ac_val[0][vxy], 0, 16 * sizeof(int16_t)); | |
| 512 | + memset(ac_val[uxy], 0, sizeof(*ac_val)); | |
| 513 | + memset(ac_val[vxy], 0, sizeof(*ac_val)); | |
| 512 | 514 | } |
| 513 | 515 | |
| 514 | 516 | void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename |