[2/2] LoongArch: Implement target pragma.

Message ID 20250107113803.25633-3-chenglulu@loongson.cn
State New
Headers
Series Implement target attribute and pragma. |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed

Commit Message

Lulu Cheng Jan. 7, 2025, 11:38 a.m. UTC
  The target pragmas defined correspond to the target function attributes.

This implementation is derived from AArch64.

gcc/ChangeLog:

	* config/loongarch/loongarch-protos.h
	(loongarch_reset_previous_fndecl):  Add function declaration.
	(loongarch_save_restore_target_globals): Likewise.
	(loongarch_register_pragmas): Likewise.
	* config/loongarch/loongarch-target-attr.cc
	(loongarch_option_valid_attribute_p): Optimize the processing
	of attributes.
	(loongarch_pragma_target_parse): New functions.
	(loongarch_register_pragmas): Likewise.
	* config/loongarch/loongarch.cc
	(loongarch_reset_previous_fndecl): New functions.
	(loongarch_set_current_function): When the old_tree is the same
	as the new_tree, the rules for using registers, etc.,
	are set according to the option values to ensure that the
	pragma can be processed correctly.
	* config/loongarch/loongarch.h (REGISTER_TARGET_PRAGMAS):
	Define macro.
	* doc/extend.texi: Supplemental Documentation.

gcc/testsuite/ChangeLog:

	* gcc.target/loongarch/arch-func-attr-1.c: Add '#pragma'.
	* gcc.target/loongarch/cmodel-func-attr-1.c: Likewise.
	* gcc.target/loongarch/lasx-func-attr-1.c: Likewise.
	* gcc.target/loongarch/lsx-func-attr-1.c: Likewise.
	* gcc.target/loongarch/strict_align-func-attr-1.c: Likewise.
	* gcc.target/loongarch/strict_align-func-attr-2.c: Likewise.
	* gcc.target/loongarch/vector-func-attr-1.c: Likewise.
	* gcc.target/loongarch/arch-pragma-attr-1.c: Likewise.
	* gcc.target/loongarch/cmodel-pragma-attr-1.c: New test.
	* gcc.target/loongarch/lasx-pragma-attr-1.c: New test.
	* gcc.target/loongarch/lasx-pragma-attr-2.c: New test.
	* gcc.target/loongarch/lsx-pragma-attr-1.c: New test.
	* gcc.target/loongarch/lsx-pragma-attr-2.c: New test.
	* gcc.target/loongarch/strict_align-pragma-attr-1.c: New test.
	* gcc.target/loongarch/strict_align-pragma-attr-2.c: New test.
	* gcc.target/loongarch/vector-pragma-attr-1.c: New test.
	* gcc.target/loongarch/pragma-push-pop.c: New test.

---
 gcc/config/loongarch/loongarch-protos.h       |  3 +
 gcc/config/loongarch/loongarch-target-attr.cc | 59 +++++++++++++++++++
 gcc/config/loongarch/loongarch.cc             | 19 +++---
 gcc/config/loongarch/loongarch.h              |  2 +
 gcc/doc/extend.texi                           | 13 ++++
 .../gcc.target/loongarch/arch-func-attr-1.c   |  6 +-
 .../gcc.target/loongarch/arch-pragma-attr-1.c |  7 +++
 .../gcc.target/loongarch/cmodel-func-attr-1.c |  4 ++
 .../loongarch/cmodel-pragma-attr-1.c          |  7 +++
 .../gcc.target/loongarch/lasx-func-attr-1.c   |  4 ++
 .../gcc.target/loongarch/lasx-pragma-attr-1.c |  7 +++
 .../gcc.target/loongarch/lasx-pragma-attr-2.c | 12 ++++
 .../gcc.target/loongarch/lsx-func-attr-1.c    |  4 ++
 .../gcc.target/loongarch/lsx-pragma-attr-1.c  |  7 +++
 .../gcc.target/loongarch/lsx-pragma-attr-2.c  | 12 ++++
 .../gcc.target/loongarch/pragma-push-pop.c    | 22 +++++++
 .../loongarch/strict_align-func-attr-1.c      |  4 ++
 .../loongarch/strict_align-func-attr-2.c      |  4 ++
 .../loongarch/strict_align-pragma-attr-1.c    |  7 +++
 .../loongarch/strict_align-pragma-attr-2.c    |  7 +++
 .../gcc.target/loongarch/vector-func-attr-1.c |  4 ++
 .../loongarch/vector-pragma-attr-1.c          |  7 +++
 22 files changed, 213 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/arch-pragma-attr-1.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/cmodel-pragma-attr-1.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-1.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-2.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-1.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-2.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/pragma-push-pop.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-1.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-2.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/vector-pragma-attr-1.c
  

Patch

diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h
index 531b0bcb636..967f1633ae6 100644
--- a/gcc/config/loongarch/loongarch-protos.h
+++ b/gcc/config/loongarch/loongarch-protos.h
@@ -214,4 +214,7 @@  extern bool loongarch_explicit_relocs_p (enum loongarch_symbol_type);
 extern bool loongarch_symbol_extreme_p (enum loongarch_symbol_type);
 extern bool loongarch_option_valid_attribute_p (tree, tree, tree, int);
 extern void loongarch_option_override_internal (struct loongarch_target *, struct gcc_options *, struct gcc_options *);
+extern void loongarch_reset_previous_fndecl (void);
+extern void loongarch_save_restore_target_globals (tree new_tree);
+extern void loongarch_register_pragmas (void);
 #endif /* ! GCC_LOONGARCH_PROTOS_H */
diff --git a/gcc/config/loongarch/loongarch-target-attr.cc b/gcc/config/loongarch/loongarch-target-attr.cc
index 1fafd4c4466..61d5c85c680 100644
--- a/gcc/config/loongarch/loongarch-target-attr.cc
+++ b/gcc/config/loongarch/loongarch-target-attr.cc
@@ -349,6 +349,16 @@  loongarch_option_valid_attribute_p (tree fndecl, tree, tree args, int)
   tree new_target, new_optimize;
   tree existing_target = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
 
+  /* If what we're processing is the current pragma string then the
+     target option node is already stored in target_option_current_node
+     by loongarch_pragma_target_parse in loongarch-target-attr.cc.
+     Use that to avoid having to re-parse the string.  */
+  if (!existing_target && args == current_target_pragma)
+    {
+      DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = target_option_current_node;
+      return true;
+    }
+
   tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
 
   old_optimize
@@ -411,3 +421,52 @@  loongarch_option_valid_attribute_p (tree fndecl, tree, tree args, int)
 			     TREE_OPTIMIZATION (old_optimize));
   return ret;
 }
+
+/* Hook to validate the current #pragma GCC target and set the state, and
+   update the macros based on what was changed.  If ARGS is NULL, then
+   POP_TARGET is used to reset the options.  */
+
+static bool
+loongarch_pragma_target_parse (tree args, tree pop_target)
+{
+  /* If args is not NULL then process it and setup the target-specific
+     information that it specifies.  */
+  if (args)
+    {
+      if (!loongarch_process_target_attr (args, NULL))
+	return false;
+
+      loongarch_option_override_internal (&la_target,
+					  &global_options,
+					  &global_options_set);
+    }
+
+  /* args is NULL, restore to the state described in pop_target.  */
+  else
+    {
+      pop_target = pop_target ? pop_target : target_option_default_node;
+      cl_target_option_restore (&global_options, &global_options_set,
+				TREE_TARGET_OPTION (pop_target));
+    }
+
+  target_option_current_node
+    = build_target_option_node (&global_options, &global_options_set);
+
+  loongarch_reset_previous_fndecl ();
+
+  /* If we're popping or reseting make sure to update the globals so that
+     the optab availability predicates get recomputed.  */
+  if (pop_target)
+    loongarch_save_restore_target_globals (pop_target);
+
+  return true;
+}
+
+/* Implement REGISTER_TARGET_PRAGMAS.  */
+
+void
+loongarch_register_pragmas (void)
+{
+  /* Update pragma hook to allow parsing #pragma GCC target.  */
+  targetm.target_option.pragma_parse = loongarch_pragma_target_parse;
+}
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index f3514073cea..5b73e2a9f85 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -7677,11 +7677,17 @@  loongarch_option_override_internal (struct loongarch_target *target,
 
 static GTY(()) tree loongarch_previous_fndecl;
 
+void
+loongarch_reset_previous_fndecl (void)
+{
+  loongarch_previous_fndecl = NULL;
+}
+
 /* Restore or save the TREE_TARGET_GLOBALS from or to new_tree.
    Used by loongarch_set_current_function to
    make sure optab availability predicates are recomputed when necessary.  */
 
-static void
+void
 loongarch_save_restore_target_globals (tree new_tree)
 {
   if (TREE_TARGET_GLOBALS (new_tree))
@@ -7734,13 +7740,12 @@  loongarch_set_current_function (tree fndecl)
 
   loongarch_previous_fndecl = fndecl;
 
-  if (new_tree == old_tree)
-    return;
+  if (new_tree != old_tree)
+    /* According to the settings of the functions attribute and pragma,
+       the options is corrected.  */
+    cl_target_option_restore (&global_options, &global_options_set,
+			      TREE_TARGET_OPTION (new_tree));
 
-  /* According to the settings of the functions attribute and pragma,
-     the options is corrected.  */
-  cl_target_option_restore (&global_options, &global_options_set,
-			    TREE_TARGET_OPTION (new_tree));
 
   /* After correcting the value of options, we need to update the
      rules for using the hardware registers to ensure that the
diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
index 4ee01618de1..42a38a44efe 100644
--- a/gcc/config/loongarch/loongarch.h
+++ b/gcc/config/loongarch/loongarch.h
@@ -26,6 +26,8 @@  along with GCC; see the file COPYING3.  If not see
 
 #define SWITCHABLE_TARGET 1
 
+#define REGISTER_TARGET_PRAGMAS() loongarch_register_pragmas ()
+
 #define TARGET_SUPPORTS_WIDE_INT 1
 
 /* Macros to silence warnings about numbers being signed in traditional
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index d896677fd3a..d72fa0764f6 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -28413,6 +28413,7 @@  option is specified.  @xref{OpenMP}, and @ref{OpenACC}.
 @menu
 * AArch64 Pragmas::
 * ARM Pragmas::
+* LoongArch Pragmas::
 * M32C Pragmas::
 * PRU Pragmas::
 * RS/6000 and PowerPC Pragmas::
@@ -28465,6 +28466,18 @@  Do not affect the @code{long_call} or @code{short_call} attributes of
 subsequent functions.
 @end table
 
+@node LoongArch Pragmas
+@subsection LoongArch Pragmas
+
+The list of attributes supported by Pragma is the same as that of target
+function attributres.  @xref{LoongArch Function Attributes}.
+
+Example:
+
+@smallexample
+#pragma GCC target("strict-align")
+@end smallexample
+
 @node M32C Pragmas
 @subsection M32C Pragmas
 
diff --git a/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c
index 98cc7e577e3..b8e51e6d9e1 100644
--- a/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/arch-func-attr-1.c
@@ -1,10 +1,14 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -march=loongarch64 -mno-lsx" } */
+/* { dg-options "-O2 -march=loongarch64 -mno-lsx -std=gnu11" } */
 
 extern char a[64];
 extern char b[64];
 
+#ifndef TEST_TARGET_PRAGMA
 __attribute__ ((target ("arch=la64v1.1")))
+#else
+#pragma GCC target ("arch=la64v1.1")
+#endif
 void
 test (void)
 {
diff --git a/gcc/testsuite/gcc.target/loongarch/arch-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/arch-pragma-attr-1.c
new file mode 100644
index 00000000000..bd918e70926
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/arch-pragma-attr-1.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=loongarch64 -mno-lsx -std=gnu11" } */
+
+#define TEST_TARGET_PRAGMA 1
+#include "./arch-func-attr-1.c"
+
+/* { dg-final { scan-assembler "vld" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c
index 119cd0e1646..9f44dc66bfd 100644
--- a/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/cmodel-func-attr-1.c
@@ -4,7 +4,11 @@ 
 extern char a[8];
 extern char b[8];
 
+#ifndef TEST_TARGET_PRAGMA
 __attribute__ ((target ("cmodel=extreme")))
+#else
+#pragma GCC target ("cmodel=extreme")
+#endif
 void
 test (void)
 {
diff --git a/gcc/testsuite/gcc.target/loongarch/cmodel-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/cmodel-pragma-attr-1.c
new file mode 100644
index 00000000000..b522891487c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/cmodel-pragma-attr-1.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcmodel=normal -mexplicit-relocs=none" } */
+
+#define TEST_TARGET_PRAGMA 1
+#include "./cmodel-func-attr-1.c"
+
+/* { dg-final { scan-assembler "la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,a" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c
index 5dad9821f03..720719e80b8 100644
--- a/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/lasx-func-attr-1.c
@@ -4,7 +4,11 @@ 
 typedef int v8i32 __attribute__ ((vector_size(32), aligned(32)));
 extern v8i32 a, b, c;
 
+#ifndef TEST_TARGET_PRAGMA
 __attribute__ ((target ("lasx")))
+#else
+#pragma GCC target ("lasx")
+#endif
 void
 test (void)
 {
diff --git a/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-1.c
new file mode 100644
index 00000000000..d5bc68f1cb8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-1.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-lsx" } */
+
+#define TEST_TARGET_PRAGMA 1
+#include "./lasx-func-attr-1.c"
+
+/* { dg-final { scan-assembler "xvadd.w" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-2.c b/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-2.c
new file mode 100644
index 00000000000..67e4f7179fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/lasx-pragma-attr-2.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlasx" } */
+
+typedef int v8i32 __attribute__ ((vector_size(32), aligned(32)));
+extern v8i32 a, b, c;
+
+#pragma GCC target ("no-lasx")
+void
+test (void)
+{
+  a = __builtin_lasx_xvadd_w (b, c); /* { dg-error "built-in function '__builtin_lasx_xvadd_w' is not enabled" } */
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c
index 3e2c1dc3359..3558898d353 100644
--- a/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/lsx-func-attr-1.c
@@ -4,7 +4,11 @@ 
 typedef int v4i32 __attribute__ ((vector_size(16), aligned(16)));
 extern v4i32 a, b, c;
 
+#ifndef TEST_TARGET_PRAGMA
 __attribute__ ((target ("lsx")))
+#else
+#pragma GCC target ("lsx")
+#endif
 void
 test (void)
 {
diff --git a/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-1.c
new file mode 100644
index 00000000000..c499f18fc42
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-1.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-lsx" } */
+
+#define TEST_TARGET_PRAGMA 1
+#include "./lsx-func-attr-1.c"
+
+/* { dg-final { scan-assembler "vadd.w" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-2.c b/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-2.c
new file mode 100644
index 00000000000..40314d026eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/lsx-pragma-attr-2.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlsx" } */
+
+typedef int v4i32 __attribute__ ((vector_size(16), aligned(16)));
+extern v4i32 a, b, c;
+
+#pragma GCC target ("no-lsx")
+void
+test (void)
+{
+  a = __builtin_lsx_vadd_w (b, c); /* { dg-error "built-in function '__builtin_lsx_vadd_w' is not enabled" } */
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/pragma-push-pop.c b/gcc/testsuite/gcc.target/loongarch/pragma-push-pop.c
new file mode 100644
index 00000000000..a2bcdcb10d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pragma-push-pop.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlasx" } */
+/* { dg-final { scan-assembler-not "xvadd\\\.w" } } */
+/* { dg-final { scan-assembler "xvsll\\\.w" } } */
+
+#include <lasxintrin.h>
+
+extern v8i32 a, b, c;
+#pragma GCC push_options
+#pragma GCC target ("no-lasx")
+void
+test (void)
+{
+  a = b + c;
+}
+#pragma GCC pop_options
+
+void
+test1 (void)
+{
+   c = __builtin_lasx_xvsll_w (a, b);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c
index 04893746de8..c1ed6515ccf 100644
--- a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-1.c
@@ -3,7 +3,11 @@ 
 extern char a[8];
 extern char b[8];
 
+#ifndef TEST_TARGET_PRAGMA
 __attribute__ ((target ("no-strict-align")))
+#else
+#pragma GCC target ("no-strict-align")
+#endif
 void
 test (void)
 {
diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c
index 0e81486cd53..70bf810037e 100644
--- a/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c
+++ b/gcc/testsuite/gcc.target/loongarch/strict_align-func-attr-2.c
@@ -3,7 +3,11 @@ 
 extern char a[8];
 extern char b[8];
 
+#ifndef TEST_TARGET_PRAGMA
 __attribute__ ((target ("strict-align")))
+#else
+#pragma GCC target ("strict-align")
+#endif
 void
 test (void)
 {
diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-1.c
new file mode 100644
index 00000000000..a95d0b97282
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-1.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mstrict-align" } */
+
+#define TEST_TARGET_PRAGMA 1
+#include "./strict_align-func-attr-1.c"
+
+/* { dg-final { scan-assembler-not "ld.bu" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-2.c b/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-2.c
new file mode 100644
index 00000000000..93b76c59b6c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/strict_align-pragma-attr-2.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-strict-align" } */
+
+#define TEST_TARGET_PRAGMA 1
+#include "./strict_align-func-attr-2.c"
+
+/* { dg-final { scan-assembler-not "ld.w" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c b/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c
index 655ca234be0..4e00606b1c6 100644
--- a/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/vector-func-attr-1.c
@@ -4,7 +4,11 @@ 
 typedef int v4i32 __attribute__ ((vector_size(16), aligned(16)));
 extern v4i32 a, b, c;
 
+#ifndef TEST_TARGET_PRAGMA
 __attribute__ ((target ("no-lasx")))
+#else
+#pragma GCC target ("no-lasx")
+#endif
 void
 test (void)
 {
diff --git a/gcc/testsuite/gcc.target/loongarch/vector-pragma-attr-1.c b/gcc/testsuite/gcc.target/loongarch/vector-pragma-attr-1.c
new file mode 100644
index 00000000000..7bbb1690113
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/vector-pragma-attr-1.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlsx" } */
+
+#define TEST_TARGET_PRAGMA 1
+#include "./vector-func-attr-1.c"
+
+/* { dg-final { scan-assembler "vadd.w" } } */