From 3c6aeaacbb6380ef4d69eefdb58ec47ee1ad1ed5 Mon Sep 17 00:00:00 2001 From: Frank Barchard Date: Mon, 12 Oct 2026 19:27:07 -0700 Subject: [PATCH] Fix remaining inline asm input/output constraints and clobbers Mark modified inline asm operands as read-write (+r / +c) and add missing volatile/memory clobbers so compilers and LTO do not assume modified registers remain unchanged across asm blocks: - HashDjb2_NEON (compare_neon64.cc): [src] "+r"(src) for post-increment ldr - FixedDiv1_X86 (scale_gcc.cc): "+c"(div) for sub $0x1, %1 - P410ToARGBRow_SVE_SC & P410ToAR30Row_SVE_SC (row_sve.h): [vl] "+r"(vl) for tail cntw %x[vl] - SwapUVRow_RVV & ARGBMultiplyRow_RVV (row_rvv.cc): use asm volatile and "memory" clobber instead of VLA memory operands on mutated pointers R=rrwinterton@gmail.com Bug: b/571179207 Test: libyuv_unittest Change-Id: I3c2475d1e5bdab13e74643a028eebc350edcc1bb --- include/libyuv/row_sve.h | 12 ++++++------ source/compare_neon64.cc | 6 +++--- source/row_rvv.cc | 30 ++++++++++++------------------ source/scale_gcc.cc | 5 +++-- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/include/libyuv/row_sve.h b/include/libyuv/row_sve.h index 00364e9c8..467ec199b 100644 --- a/include/libyuv/row_sve.h +++ b/include/libyuv/row_sve.h @@ -1767,9 +1767,9 @@ static inline void P410ToARGBRow_SVE_SC(const uint16_t* src_y, : [src_y] "+r"(src_y), // %[src_y] [src_uv] "+r"(src_uv), // %[src_uv] [dst_argb] "+r"(dst_argb), // %[dst_argb] - [width] "+r"(width) // %[width] - : [vl] "r"(vl), // %[vl] - [kUVCoeff] "r"(&yuvconstants->kUVCoeff), // %[kUVCoeff] + [width] "+r"(width), // %[width] + [vl] "+r"(vl) // %[vl] + : [kUVCoeff] "r"(&yuvconstants->kUVCoeff), // %[kUVCoeff] [kRGBCoeffBias] "r"(&yuvconstants->kRGBCoeffBias), // %[kRGBCoeffBias] [width_last_y] "r"(width_last_y) // %[width_last_y] : "cc", "memory", YUVTORGB_SVE_REGS); @@ -1818,9 +1818,9 @@ static inline void P410ToAR30Row_SVE_SC(const uint16_t* src_y, : [src_y] "+r"(src_y), // %[src_y] [src_uv] "+r"(src_uv), // %[src_uv] [dst_ar30] "+r"(dst_ar30), // %[dst_ar30] - [width] "+r"(width) // %[width] - : [vl] "r"(vl), // %[vl] - [kUVCoeff] "r"(&yuvconstants->kUVCoeff), // %[kUVCoeff] + [width] "+r"(width), // %[width] + [vl] "+r"(vl) // %[vl] + : [kUVCoeff] "r"(&yuvconstants->kUVCoeff), // %[kUVCoeff] [kRGBCoeffBias] "r"(&yuvconstants->kRGBCoeffBias), // %[kRGBCoeffBias] [width_last_y] "r"(width_last_y), // %[width_last_y] [limit] "r"(limit) // %[limit] diff --git a/source/compare_neon64.cc b/source/compare_neon64.cc index a91a7e7b4..89dba1ba0 100644 --- a/source/compare_neon64.cc +++ b/source/compare_neon64.cc @@ -145,12 +145,12 @@ uint32_t HashDjb2_NEON(const uint8_t* src, int count, uint32_t seed) { "add %w[tmp], %w[tmp], %w[tmp2] \n" "madd %w[hash], %w[hash], %w[c16], %w[tmp] \n" "b.gt 1b \n" - : [hash] "+r"(hash), // %[hash] + : [src] "+r"(src), // %[src] + [hash] "+r"(hash), // %[hash] [count] "+r"(count), // %[count] [tmp] "=&r"(tmp), // %[tmp] [tmp2] "=&r"(tmp2) // %[tmp2] - : [src] "r"(src), // %[src] - [kMuls] "r"(kDjb2Multiplicands), // %[kMuls] + : [kMuls] "r"(kDjb2Multiplicands), // %[kMuls] [kIdx] "r"(kDjb2WidenIndices), // %[kIdx] [c16] "r"(c16) // %[c16] : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16", diff --git a/source/row_rvv.cc b/source/row_rvv.cc index d7898ea18..ca87e4603 100644 --- a/source/row_rvv.cc +++ b/source/row_rvv.cc @@ -1711,10 +1711,9 @@ void MergeUVRow_RVV(const uint8_t* src_u, #ifdef HAS_SWAPUVROW_RVV void SwapUVRow_RVV(const uint8_t* src_uv, uint8_t* dst_vu, int width) { assert(width != 0); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wvla" size_t vl; - asm("1: \n" + asm volatile( + "1: \n" "vsetvli %[vl], %[w], e16, m4, ta, ma \n" "vle16.v v8, (%[src_uv]) \n" "vsrl.vi v12, v8, 8 \n" @@ -1729,11 +1728,10 @@ void SwapUVRow_RVV(const uint8_t* src_uv, uint8_t* dst_vu, int width) { : [src_uv] "+r"(src_uv), // %[src_uv] [dst_vu] "+r"(dst_vu), // %[dst_vu] [w] "+r"(width), // %[w] - [vl] "=&r"(vl), // %[vl] - "=m"(*(uint8_t (*)[width * 2]) dst_vu) - : "m"(*(const uint8_t (*)[width * 2]) src_uv) - : RVV_VL_CLOBBER "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15"); -#pragma GCC diagnostic pop + [vl] "=&r"(vl) // %[vl] + : + : RVV_VL_CLOBBER "memory", "v8", "v9", "v10", "v11", "v12", "v13", "v14", + "v15"); } #endif @@ -2330,10 +2328,9 @@ void ARGBMultiplyRow_RVV(const uint8_t* src_argb, int width) { assert(width != 0); size_t w = (size_t)width * 4; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wvla" size_t vl; - asm("1: \n" + asm volatile( + "1: \n" "vsetvli %[vl], %[w], e8, m2, ta, ma \n" "vle8.v v8, (%[src0]) \n" "vle8.v v10, (%[src1]) \n" @@ -2350,13 +2347,10 @@ void ARGBMultiplyRow_RVV(const uint8_t* src_argb, [src1] "+r"(src_argb1), // %[src1] [dst] "+r"(dst_argb), // %[dst] [w] "+r"(w), // %[w] - [vl] "=&r"(vl), // %[vl] - "=m"(*(uint8_t (*)[w])dst_argb) - : [k128] "r"(128), // %[k128] - "m"(*(const uint8_t (*)[w])src_argb), - "m"(*(const uint8_t (*)[w])src_argb1) - : RVV_VL_CLOBBER "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15"); -#pragma GCC diagnostic pop + [vl] "=&r"(vl) // %[vl] + : [k128] "r"(128) // %[k128] + : RVV_VL_CLOBBER "memory", "v8", "v9", "v10", "v11", "v12", "v13", "v14", + "v15"); } #endif diff --git a/source/scale_gcc.cc b/source/scale_gcc.cc index a26e00380..835665ee0 100644 --- a/source/scale_gcc.cc +++ b/source/scale_gcc.cc @@ -3084,8 +3084,9 @@ int FixedDiv1_X86(int num, int div) { "sub $0x1,%1 \n" "idiv %1 \n" "mov %0, %%eax \n" - : "+a"(num) // %0 - : "c"(div) // %1 + : "+a"(num), // %0 + "+c"(div) // %1 + : : "memory", "cc", "edx"); return num; }