https://gcc.gnu.org/g:86e4ac2fc31e504d0b0556a34aa702a98ddbf94f

commit r14-12250-g86e4ac2fc31e504d0b0556a34aa702a98ddbf94f
Author: Lulu Cheng <[email protected]>
Date:   Sat Jan 17 15:12:46 2026 +0800

    LoongArch: Fix bug117575.
    
    In the template "vec_set<mode>", a call is made to
    "lasx_xvinsve0_<lasxfmt_f>_scalar", but there is an issue due to
    the different ranges of operand1 between the two templates.
    The range of operand1 in the template
    "lasx_xvinsve0_<lasxfmt_f>_scalar" is now set to be the same as
    that in "vec_set<mode>".
    
            PR target/117575
    
    gcc/ChangeLog:
    
            * config/loongarch/lasx.md: Modify the range of operand1.
    
    gcc/testsuite/ChangeLog:
    
            * g++.target/loongarch/pr117575.C: New test.
    
    (cherry picked from commit 27f040591aeb611030c990944731f84485887f97)

Diff:
---
 gcc/config/loongarch/lasx.md                  |  2 +-
 gcc/testsuite/g++.target/loongarch/pr117575.C | 81 +++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index 37d5a1f978fd..f3013b220518 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -4535,7 +4535,7 @@
   [(set (match_operand:FLASX 0 "register_operand" "=f")
     (vec_merge:FLASX
       (vec_duplicate:FLASX
-        (match_operand:<UNITMODE> 1 "register_operand" "f"))
+        (match_operand:<UNITMODE> 1 "reg_or_0_operand" "f"))
       (match_operand:FLASX 2 "register_operand" "0")
       (match_operand 3 "const_<bitmask256>_operand" "")))]
   "ISA_HAS_LASX"
diff --git a/gcc/testsuite/g++.target/loongarch/pr117575.C 
b/gcc/testsuite/g++.target/loongarch/pr117575.C
new file mode 100644
index 000000000000..1870d4c890af
--- /dev/null
+++ b/gcc/testsuite/g++.target/loongarch/pr117575.C
@@ -0,0 +1,81 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mlasx" } */
+
+typedef long unsigned int size_t;
+typedef unsigned char simde__mmask8;
+typedef double simde_float64;
+typedef simde_float64 simde__m512d __attribute__ ((__aligned__ ((64))))
+__attribute__ ((__vector_size__ (64))) __attribute__ ((__may_alias__));
+typedef simde_float64 simde__m256d __attribute__ ((__aligned__ ((32))))
+__attribute__ ((__vector_size__ (32))) __attribute__ ((__may_alias__));
+simde__m512d simde_mm512_set_pd (simde_float64 e7, simde_float64 e6,
+                                 simde_float64 e5, simde_float64 e4,
+                                 simde_float64 e3, simde_float64 e2,
+                                 simde_float64 e1, simde_float64 e0);
+simde__m256d simde_mm256_maskz_mov_pd (simde__mmask8 k, simde__m256d a);
+int simde_test_x86_assert_equal_f64x4_ (simde__m256d a, simde__m256d b);
+
+typedef union
+{
+
+  __attribute__ ((__aligned__ ((32)))) simde_float64 f64
+      __attribute__ ((__vector_size__ (32))) __attribute__ ((__may_alias__));
+} simde__m256d_private;
+__attribute__ ((__always_inline__)) inline static simde__m256d
+simde__m256d_from_private (simde__m256d_private v)
+{
+  simde__m256d r;
+  __builtin_memcpy (&r, &v, sizeof (r));
+  return r;
+}
+simde__m256d
+simde_mm256_set_pd (simde_float64 e3, simde_float64 e2, simde_float64 e1,
+                    simde_float64 e0)
+{
+
+  simde__m256d_private r_;
+
+  r_.f64[0] = e0;
+  r_.f64[1] = e1;
+  r_.f64[2] = e2;
+  r_.f64[3] = e3;
+
+  return simde__m256d_from_private (r_);
+}
+
+simde__m256d simde_mm512_extractf64x4_pd (simde__m512d a, int imm8);
+int
+test_simde_mm512_maskz_extractf64x4_pd (void)
+{
+  const struct
+  {
+    simde__mmask8 k;
+    simde__m512d a;
+    simde__m256d r0;
+    simde__m256d r1;
+  } test_vec[2] = {
+    { 21,
+      simde_mm512_set_pd (-139.11, -172.36, -268.86, 393.53, -71.72, 36.69,
+                          98.47, -135.52),
+      simde_mm256_set_pd (0.00, 36.69, 0.00, -135.52),
+      simde_mm256_set_pd (0.00, -172.36, 0.00, 393.53) },
+    { 150,
+      simde_mm512_set_pd (-556.90, 522.06, 160.98, -932.28, 391.82, 600.12,
+                          -569.99, -491.12),
+      simde_mm256_set_pd (0.00, 600.12, -569.99, 0.00),
+      simde_mm256_set_pd (0.00, 522.06, 160.98, 0.00) },
+  };
+
+  for (size_t i = 0; i < (sizeof (test_vec) / sizeof (test_vec[0])); i++)
+    {
+      simde__m256d r;
+      r = simde_mm256_maskz_mov_pd (
+          test_vec[i].k, simde_mm512_extractf64x4_pd (test_vec[i].a, 0));
+      if (simde_test_x86_assert_equal_f64x4_ (r, test_vec[i].r0))
+        {
+          return 1;
+        }
+    }
+
+  return 0;
+}

Reply via email to