PR #24107 opened by mkver
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24107
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24107.patch

encode_blocks() in svq1enc.c triggers a bug in several versions
of GCC: GCC tries to create eight clones of recursive functions
to inline some parameters when it deems this worth it.
Yet encode_blocks() only has a recursion depth of six and
the last two clones contained out-of-bounds array accesses,
triggering -Warray-bounds warnings.

This has already caused problems in the past, see
894191e7e1 which disabled
the creation of clones for GCC < 12; GCC 12 itself got better
at not creating unnecessary clones and therefore was not targetted
by this.

Yet since GCC 16 (commit 3fd5a1e76bbf1bc031934a9d96f284a22a5f307f),
it again fails at discarding unneeded clones and emits warnings
again.

This patch fixes this by simply telling the compiler the proper
range via an av_assume(); this also allows to remove the old
workaround for GCC 11.

Furthermore, GCC 12-15 still produced insane output: Six clones
for encode_block() and a general function without inlined parameters
that is not referenced by anything. The av_assume() eliminates
this function, too.


>From d4c25099817ad46ba970c28b7a51c0c4630a8752 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 12 Aug 2026 13:22:19 +0200
Subject: [PATCH 1/2] avcodec/svq1enc: Workaround GCC bug 102513

encode_blocks() in svq1enc.c triggers a bug in several versions
of GCC: GCC tries to create eight clones of recursive functions
to inline some parameters when it deems this worth it.
Yet encode_blocks() only has a recursion depth of six and
the last two clones contained out-of-bounds array accesses,
triggering -Warray-bounds warnings.

This has already caused problems in the past, see
894191e7e10520109db983032d1cd8d45c85af6d which disabled
the creation of clones for GCC < 12; GCC 12 itself got better
at not creating unnecessary clones and therefore was not targetted
by this.

Yet since GCC 16 (commit 3fd5a1e76bbf1bc031934a9d96f284a22a5f307f),
it again fails at discarding unneeded clones and emits warnings
again.

This patch fixes this by simply telling the compiler the proper
range via an av_assume(); this also allows to remove the old
workaround for GCC 11.

Furthermore, GCC 12-15 still produced insane output: Six clones
for encode_block() and a general function without inlined parameters
that is not referenced by anything. The av_assume() eliminates
this function, too.

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/svq1enc.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 4855bed188..953e235b13 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -48,12 +48,6 @@
 #include "libavutil/frame.h"
 #include "libavutil/mem_internal.h"
 
-// Workaround for GCC bug 102513
-#if AV_GCC_VERSION_AT_LEAST(10, 0) && AV_GCC_VERSION_AT_MOST(12, 0) \
-    && !defined(__clang__) && !defined(__INTEL_COMPILER)
-#pragma GCC optimize ("no-ipa-cp-clone")
-#endif
-
 typedef struct SVQ1EncContext {
     /* FIXME: Needed for motion estimation, should not be used for anything
      * else, the idea is to make the motion estimation eventually independent
@@ -134,6 +128,8 @@ static int encode_block(SVQ1EncContext *s, uint8_t *src, 
uint8_t *ref,
                         uint8_t *decoded, int stride, unsigned level,
                         int threshold, int lambda, int intra)
 {
+    av_assume(level <= 5U); // Workaround for GCC bug 102513
+
     int count, y, x, i, j, split, best_mean, best_score, best_count;
     int best_vector[6];
     int block_sum[7] = { 0, 0, 0, 0, 0, 0 };
-- 
2.52.0


>From 777e978902a42f655f36da27624583f5c016d366 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <[email protected]>
Date: Wed, 12 Aug 2026 13:54:57 +0200
Subject: [PATCH 2/2] avcodec/svq1enc: Fix shadowing

Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/svq1enc.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 953e235b13..d720b143ab 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -645,14 +645,14 @@ static int svq1_encode_frame(AVCodecContext *avctx, 
AVPacket *pkt,
     init_put_bits(&pb, pkt->data, pkt->size);
     svq1_write_header(s, &pb, s->pict_type);
     for (i = 0; i < 3; i++) {
-        int ret = svq1_encode_plane(s, i, &pb,
-                              pict->data[i],
-                              s->last_picture->data[i],
-                              s->current_picture->data[i],
-                              s->frame_width  / (i ? 4 : 1),
-                              s->frame_height / (i ? 4 : 1),
-                              pict->linesize[i],
-                              s->current_picture->linesize[i]);
+        ret = svq1_encode_plane(s, i, &pb,
+                                pict->data[i],
+                                s->last_picture->data[i],
+                                s->current_picture->data[i],
+                                s->frame_width  / (i ? 4 : 1),
+                                s->frame_height / (i ? 4 : 1),
+                                pict->linesize[i],
+                                s->current_picture->linesize[i]);
         emms_c();
         if (ret < 0)
             return ret;
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to