Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

英雄帖: Support #pragma GCC target in GCC #82

Open
xen0n opened this issue Feb 11, 2025 · 6 comments
Open

英雄帖: Support #pragma GCC target in GCC #82

xen0n opened this issue Feb 11, 2025 · 6 comments
Labels
AREA: Toolchain 英雄帖 Volunteers welcome!

Comments

@xen0n
Copy link
Member

xen0n commented Feb 11, 2025

We should have this feature implemented in GCC, complete with automatic insertion/deletion of respective preprocessor macros.

Example:

// gcc -march=la64v1.0 -mlsx -mno-lasx

#ifdef __loongarch_asx
#error LASX shouldn't be available here
#endif

#pragma GCC push_options
#pragma GCC target("lasx")
#ifndef __loongarch_asx
#error LASX should be available here
#endif
#pragma GCC pop_options

#ifdef __loongarch_asx
#error LASX should become unavailable again
#endif

Exact details of the target option string is up to the Hero picking up this 英雄帖, but discussion and broad community consensus is expected before anything is to be upstreamed.

Background

When building Skia currently there are some warnings when building with -mlasx (or equivalent, such as -march=la464) in CFLAGS:

In file included from ../../src/core/SkSwizzler_opts_lasx.cpp:25:
../../src/opts/SkOpts_RestoreTarget.h:27:17: warning: ‘#pragma GCC pop_options’ without a corresponding ‘#pragma GCC push_options’ [-Wpragmas]
   27 |         #pragma GCC pop_options
      |                 ^~~
../../src/opts/SkOpts_RestoreTarget.h:27:17: warning: ‘#pragma GCC pop_options’ without a corresponding ‘#pragma GCC push_options’ [-Wpragmas]

While the direct cause is that the SkOpts_SetTarget.h is lacking a #pragma GCC push_options, ultimately it is because GCC lacks #pragma GCC target() support for LoongArch. When this patch is applied to Skia:

diff --git a/src/opts/SkOpts_SetTarget.h b/src/opts/SkOpts_SetTarget.h
index 525cfcb862..a377e79690 100644
--- a/src/opts/SkOpts_SetTarget.h
+++ b/src/opts/SkOpts_SetTarget.h
@@ -138,6 +138,9 @@
 
         #if defined(__clang__)
           #pragma clang attribute push(__attribute__((target("lasx"))), apply_to=function)
+        #elif defined(__GNUC__)
+            // #pragma GCC push_options
+            // #pragma GCC target("lsx,lasx")
         #endif
 
     #else

We instead get:

In file included from ../../src/core/SkSwizzler_opts_lasx.cpp:21:
../../src/opts/SkOpts_SetTarget.h:137:17: warning: "__loongarch_asx" redefined                                                                                
  137 |         #define __loongarch_asx                          
      |                 ^~~~~~~~~~~~~~~ 
<built-in>: note: this is the location of the previous definition
../../src/opts/SkOpts_SetTarget.h:143:42: warning: ‘#pragma GCC target’ is not supported for this machine [-Wpragmas]
  143 |             #pragma GCC target("lsx,lasx")
      |                                          ^
../../src/opts/SkOpts_SetTarget.h:143:42: warning: ‘#pragma GCC target’ is not supported for this machine [-Wpragmas]

Which brings us to this issue.

In fact: even if __loongarch_asx is manually defined, it's not enough for GCC to allow LASX usage, because the LASX builtins' availability is not gated on the presence of the symbol. If one builds with -mlsx -mno-lasx errors will be raised:

In function ‘__m256i __lasx_xvpickev_b(__m256i, __m256i)’,
    inlined from ‘void lasx::S32_alpha_D32_filter_DX(const SkBitmapProcState&, const uint32_t*, int, uint32_t*)’ at ../../src/opts/SkBitmapProcState_opts.h:342:25:
/usr/lib/gcc/loongarch64-unknown-linux-gnu/14/include/lasxintrin.h:1783:45: error: built-in function ‘__vector(32) signed char __builtin_lasx_xvpickev_b(__vector(32) signed char, __vector(32) signed char)’ is not enabled
 1783 |   return (__m256i)__builtin_lasx_xvpickev_b ((v32i8)_1, (v32i8)_2);
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
../../src/opts/SkBitmapProcState_opts.h: In function ‘void lasx::S32_alpha_D32_filter_DX(const SkBitmapProcState&, const uint32_t*, int, uint32_t*)’:
../../src/opts/SkBitmapProcState_opts.h:342:25: error: built-in function ‘int __builtin_lasx_xvpickve2gr_w(__vector(8) int, unsigned char)’ is not enabled
  342 |             *colors++ = __lasx_xvpickve2gr_w(__lasx_xvpickev_b(__lasx_xvldi(0),
      |                         ^~~~~~~~~~~~~~~~~~~~
../../src/opts/SkBitmapProcState_opts.h:342: confused by earlier errors, bailing out

So it's a really important feature for any code that wants to provide multiple optimized codepaths AND without complicated CFLAGS manipulation and/or forced splitting into different compilation units.

@xen0n xen0n added AREA: Toolchain 英雄帖 Volunteers welcome! labels Feb 11, 2025
@xen0n
Copy link
Member Author

xen0n commented Feb 11, 2025

cc @xry111 (you may bring in the Loongson folks for discussion, I have forgotten how to at-mention them)

@xry111
Copy link
Member

xry111 commented Feb 11, 2025

The pragma is already implemented in https://gcc.gnu.org/r15-7093.

@xen0n
Copy link
Member Author

xen0n commented Feb 11, 2025

The pragma is already implemented in https://gcc.gnu.org/r15-7093.

Oh that's nice to know! (I haven't reached that mail in my backlog yet, sad me)

@xry111
Copy link
Member

xry111 commented Feb 11, 2025

https://gcc.gnu.org/PR118828

@xen0n
Copy link
Member Author

xen0n commented Feb 11, 2025

I have looked at https://gcc.gnu.org/r15-7093 but unfortunately it doesn't seem to include handling of preprocessor symbols.

@xen0n
Copy link
Member Author

xen0n commented Feb 14, 2025

PR118828 and PR118843 are resolved since r15-7524.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AREA: Toolchain 英雄帖 Volunteers welcome!
Projects
None yet
Development

No branches or pull requests

2 participants