]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LoongArch: Standard instruction template fnmam4 correction
authorGuo Jie <guojie@loongson.cn>
Wed, 29 Oct 2025 08:38:54 +0000 (16:38 +0800)
committerLulu Cheng <chenglulu@loongson.cn>
Thu, 30 Oct 2025 07:25:33 +0000 (15:25 +0800)
The current implementation of the fnmam4 instruction template requires
the third source operand to be assigned the same hard register as the
target operand, but the constraint is not documented in the instruction
manual or standard template definitions. The current constraint will
generate additional data dependencies and extra instructions.

gcc/ChangeLog:

* config/loongarch/lasx.md (fnma<mode>4): Remove.
* config/loongarch/lsx.md (fnma<mode>4): Remove.
* config/loongarch/simd.md (fnma<mode>4): Simplify and correct.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/fnmam4-vec.c: New test.

(cherry picked from commit 7811fb6fa35fd3c3694eba34fbfc992eed1d3e67)

gcc/config/loongarch/lasx.md
gcc/config/loongarch/lsx.md
gcc/config/loongarch/simd.md
gcc/testsuite/gcc.target/loongarch/fnmam4-vec.c [new file with mode: 0644]

index 3d71f30a54be83ff936e0bbf8fbb8eb744d6c4ad..9df572beb9e1c324b5e7085af465f79c6548e37e 100644 (file)
   [(set_attr "type" "simd_fmadd")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "fnma<mode>4"
-  [(set (match_operand:FLASX 0 "register_operand" "=f")
-       (fma:FLASX (neg:FLASX (match_operand:FLASX 1 "register_operand" "f"))
-                  (match_operand:FLASX 2 "register_operand" "f")
-                  (match_operand:FLASX 3 "register_operand" "0")))]
-  "ISA_HAS_LASX"
-  "xvfnmsub.<flasxfmt>\t%u0,%u1,%u2,%u0"
-  [(set_attr "type" "simd_fmadd")
-   (set_attr "mode" "<MODE>")])
-
 (define_expand "sqrt<mode>2"
   [(set (match_operand:FLASX 0 "register_operand")
     (sqrt:FLASX (match_operand:FLASX 1 "register_operand")))]
index fb0236ba0f1b4191e715b9d04e52fbf93d0aec11..cf48a16b69ea0a50959e7b1f5745bb871eaa8d11 100644 (file)
   [(set_attr "type" "simd_fmadd")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "fnma<mode>4"
-  [(set (match_operand:FLSX 0 "register_operand" "=f")
-       (fma:FLSX (neg:FLSX (match_operand:FLSX 1 "register_operand" "f"))
-                 (match_operand:FLSX 2 "register_operand" "f")
-                 (match_operand:FLSX 3 "register_operand" "0")))]
-  "ISA_HAS_LSX"
-  "vfnmsub.<flsxfmt>\t%w0,%w1,%w2,%w0"
-  [(set_attr "type" "simd_fmadd")
-   (set_attr "mode" "<MODE>")])
-
 (define_expand "sqrt<mode>2"
   [(set (match_operand:FLSX 0 "register_operand")
     (sqrt:FLSX (match_operand:FLSX 1 "register_operand")))]
index 4156b269f9adbd0bd3966849cdb3e9196601aa28..88ab138a8c6608d3da58afeb1c157997bf967427 100644 (file)
   [(set_attr "type" "simd_int_arith")
    (set_attr "mode" "<MODE>")])
 
+;; <x>vfnmsub.{s/d}
+(define_insn "fnma<mode>4"
+  [(set (match_operand:FVEC 0 "register_operand" "=f")
+       (fma:FVEC (neg:FVEC (match_operand:FVEC 1 "register_operand" "f"))
+                 (match_operand:FVEC 2 "register_operand" "f")
+                 (match_operand:FVEC 3 "register_operand" "f")))]
+  "!HONOR_SIGNED_ZEROS (<MODE>mode)"
+  "<x>vfnmsub.<simdfmt>\t%<wu>0,%<wu>1,%<wu>2,%<wu>3"
+  [(set_attr "type" "simd_fmadd")
+   (set_attr "mode" "<MODE>")])
+
 ;; <x>vfcmp.*.{s/d} with defined RTX code
 ;; There are no fcmp.{sugt/suge/cgt/cge}.{s/d} menmonics in GAS, so we have
 ;; to reverse the operands ourselves :(.
diff --git a/gcc/testsuite/gcc.target/loongarch/fnmam4-vec.c b/gcc/testsuite/gcc.target/loongarch/fnmam4-vec.c
new file mode 100644 (file)
index 0000000..0969303
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -mlasx -ftree-vectorize" } */
+/* { dg-require-effective-target loongarch_asx } */
+
+void
+foo (float *u, float x, float *y, float z)
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    *(u++) = (x - y[i] * z);
+}
+
+/* { dg-final { scan-assembler-not "\tvori.b"} } */
+/* { dg-final { scan-assembler-not "\txvori.b"} } */