Skip to content

New instance of -Wframe-larger-than with sanitizers enabled after commit d2408c417cfa #111903

Open
@nathanchance

Description

@nathanchance

I see a new instance of -Wframe-larger-than when building the Linux kernel's allmodconfig target (which enables several sanitizers) for arm64, which I bisected to commit d2408c417cfa ("[InstCombine] Canonicalize more geps with constant gep bases and constant offsets. (#110033)") (also reported on our mailing list by the Linaro toolchain test infrastructure):

$ make -skj"$(nproc)" ARCH=arm64 LLVM=1 mrproper allmodconfig drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.o
drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c:1526:12: error: stack frame size (2176) exceeds limit (2048) in 'vdec_vp9_slice_update_prob' [-Werror,-Wframe-larger-than]
 1526 | static int vdec_vp9_slice_update_prob(struct vdec_vp9_slice_instance *instance,
      |            ^
1 error generated.
...

At the parent commit 45b526afa26e ("[LV] Honor uniform-after-vectorization in setVectorizedCallDecision."), the usage is much lower.

$ make -skj"$(nproc)" ARCH=arm64 LLVM=1 KCFLAGS=-Wframe-larger-than=700 mrproper allmodconfig drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.o
drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c:1526:12: error: stack frame size (864) exceeds limit (700) in 'vdec_vp9_slice_update_prob' [-Werror,-Wframe-larger-than]
 1526 | static int vdec_vp9_slice_update_prob(struct vdec_vp9_slice_instance *instance,
      |            ^
1 error generated.
...

I reduced this file with cvise:

struct v4l2_vp9_frame_symbol_counts {
  int (*coeff[4][2][2][6][6])[];
  int *eob[][2][2][6][6][2];
} *vdec_vp9_slice_update_prob_counts_helper;
struct vdec_vp9_slice_frame_counts {
  struct {
    int band_1_5[5][6];
  } eob_branch[4][2][2];
  struct {
    int band_1_5[5][6][4];
  } coef_probs[4][2][2];
  int class0_fp;
} vdec_vp9_slice_counts_map_helper_counts;
struct {
  int frame_ctx_helper;
  struct v4l2_vp9_frame_symbol_counts counts_helper;
} *vdec_vp9_slice_update_prob_instance;
static void vdec_vp9_slice_map_counts_eob_coef(
    int i, int j, int k, struct vdec_vp9_slice_frame_counts *counts,
    struct v4l2_vp9_frame_symbol_counts *counts_helper) {
  int l, m;
  for (l = 1; l < 6; l++)
    for (m = 0; m < 6; m++) {
      counts_helper->coeff[i][j][k][l][m] = (int(*)[])counts;
      counts_helper->eob[i][j][k][l][m][0] =
          &counts->eob_branch[i][j][k].band_1_5[1][m];
      counts_helper->eob[i][j][k][l][m][1] =
          &counts->coef_probs[i][j][k].band_1_5[1][m][3];
    }
}
static void vdec_vp9_slice_counts_map_helper(
    struct v4l2_vp9_frame_symbol_counts *counts_helper) {
  int i, j, k;
  for (i = 0; i < 4; i++)
    for (j = 0; j < 2; j++)
      for (k = 0; k < 2; k++)
        vdec_vp9_slice_map_counts_eob_coef(
            i, j, k, &vdec_vp9_slice_counts_map_helper_counts, counts_helper);
}
int vdec_vp9_slice_update_prob() {
  vdec_vp9_slice_update_prob_counts_helper =
      &vdec_vp9_slice_update_prob_instance->counts_helper;
  vdec_vp9_slice_counts_map_helper(vdec_vp9_slice_update_prob_counts_helper);
  return 0;
}

which results in the following behavior with GCC 14.2.0 and clang at the revisions mentioned above.

$ aarch64-linux-gcc -O2 -Wall -c -o /dev/null vdec_vp9_req_lat_if.i -Wframe-larger-than=1 -fsanitize=bounds -fsanitize=thread
vdec_vp9_req_lat_if.i: In function 'vdec_vp9_slice_update_prob':
vdec_vp9_req_lat_if.i:45:1: warning: the frame size of 112 bytes is larger than 1 bytes [-Wframe-larger-than=]
   45 | }
      | ^

$ good-clang --target=aarch64-linux-gnu -O2 -Wall -c -o /dev/null vdec_vp9_req_lat_if.i -Wframe-larger-than=1
vdec_vp9_req_lat_if.i:40:5: warning: stack frame size (128) exceeds limit (1) in 'vdec_vp9_slice_update_prob' [-Wframe-larger-than]
   40 | int vdec_vp9_slice_update_prob() {
      |     ^
1 warning generated.

$ good-clang --target=aarch64-linux-gnu -O2 -Wall -c -o /dev/null vdec_vp9_req_lat_if.i -Wframe-larger-than=1 -fsanitize=bounds -fsanitize=thread
vdec_vp9_req_lat_if.i:40:5: warning: stack frame size (336) exceeds limit (1) in 'vdec_vp9_slice_update_prob' [-Wframe-larger-than]
   40 | int vdec_vp9_slice_update_prob() {
      |     ^
1 warning generated.

$ bad-clang --target=aarch64-linux-gnu -O2 -Wall -c -o /dev/null vdec_vp9_req_lat_if.i -Wframe-larger-than=1
vdec_vp9_req_lat_if.i:40:5: warning: stack frame size (688) exceeds limit (1) in 'vdec_vp9_slice_update_prob' [-Wframe-larger-than]
   40 | int vdec_vp9_slice_update_prob() {
      |     ^
1 warning generated.

$ bad-clang --target=aarch64-linux-gnu -O2 -Wall -c -o /dev/null vdec_vp9_req_lat_if.i -Wframe-larger-than=1 -fsanitize=bounds -fsanitize=thread
vdec_vp9_req_lat_if.i:40:5: warning: stack frame size (2176) exceeds limit (1) in 'vdec_vp9_slice_update_prob' [-Wframe-larger-than]
   40 | int vdec_vp9_slice_update_prob() {
      |     ^
1 warning generated.

This is reminiscent of a downstream issue I filed for a warning in the same code with ARCH=loongarch (ClangBuiltLinux/linux#2014), which resulted in some fixes in the LoongArch backend (0822780, 8e4b089). Perhaps AArch64 needs similar changes?

cc @davemgreen @nikic

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions