diff mbox series

[committed] i386: Fix unwanted fwprop to 3dNOW! insn [PR117926]

Message ID CAFULd4Zf+8CmR+WX2a_4-uSu=SnF9Y09T21ExP+JK68juocbXQ@mail.gmail.com
State New
Headers show
Series [committed] i386: Fix unwanted fwprop to 3dNOW! insn [PR117926] | expand

Commit Message

Uros Bizjak Dec. 6, 2024, 5:24 p.m. UTC
The compiler is able to forward propagate a partial vector V4SF instruction
using XMM registers to a 3dNOW! V2SF instruction using MM registers.  Prevent
unwanted transformation by tagging 3dNOW! V2SF instructions using generic
RTXes with "(unspec [(const_int 0)] UNSPEC_3DNOW)" tag.

    PR target/117926

gcc/ChangeLog:

    * config/i386/mmx.md (UNSPEC_3DNOW): New unspec.
    (mmx_addv2sf3): Tag insn with UNSPEC_3DNOW tag.
    (*mmx_addv2sf3): Ditto.
    (mmx_sub2vsf3): Ditto.
    (mmx_subrv2sf3): Ditto.
    (*mmx_subv2sf3): Ditto.
    (mmx_mulv2sf3): Ditto.
    (mmx_<smaxmin:code>v2sf3): Ditto.
    (*mmx_<smaxmin:code>v2sf3): Ditto.
    (mmx_ieee_<ieee_maxmin>v2sf3): Ditto.
    (mmx_eqv2sf3): Ditto.
    (*mmx_eqv2sf3): Ditto.
    (mmx_gtv2sf3): Ditto.
    (mmx_gev2sf3): Ditto.
    (mmx_fix_truncv2sfv2si2): Ditto.
    (mmx_floatv2siv2sf2): Ditto.

gcc/testsuite/ChangeLog:

    * gcc.target/i386/pr117926.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Uros.
diff mbox series

Patch

diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 61a4f4d21ea..8a980ce069d 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -30,6 +30,8 @@ 
 ;; direction of the user via a builtin.
 
 (define_c_enum "unspec" [
+  UNSPEC_3DNOW
+
   UNSPEC_MOVNTQ
   UNSPEC_PFRCP
   UNSPEC_PFRCPIT1
@@ -727,17 +729,20 @@  (define_expand "<insn>v2sf3"
 })
 
 (define_expand "mmx_addv2sf3"
-  [(set (match_operand:V2SF 0 "register_operand")
-	(plus:V2SF
-	  (match_operand:V2SF 1 "nonimmediate_operand")
-	  (match_operand:V2SF 2 "nonimmediate_operand")))]
+  [(parallel
+     [(set (match_operand:V2SF 0 "register_operand")
+	   (plus:V2SF
+	     (match_operand:V2SF 1 "nonimmediate_operand")
+	     (match_operand:V2SF 2 "nonimmediate_operand")))
+      (unspec [(const_int 0)] UNSPEC_3DNOW)])]
   "TARGET_3DNOW"
   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
 
 (define_insn "*mmx_addv2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
 	(plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
-		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
+		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
   "pfadd\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
@@ -745,21 +750,26 @@  (define_insn "*mmx_addv2sf3"
    (set_attr "mode" "V2SF")])
 
 (define_expand "mmx_subv2sf3"
-  [(set (match_operand:V2SF 0 "register_operand")
-        (minus:V2SF (match_operand:V2SF 1 "register_operand")
-		    (match_operand:V2SF 2 "nonimmediate_operand")))]
+  [(parallel
+     [(set (match_operand:V2SF 0 "register_operand")
+	   (minus:V2SF (match_operand:V2SF 1 "register_operand")
+		       (match_operand:V2SF 2 "nonimmediate_operand")))
+      (unspec [(const_int 0)] UNSPEC_3DNOW)])]
   "TARGET_3DNOW")
 
 (define_expand "mmx_subrv2sf3"
-  [(set (match_operand:V2SF 0 "register_operand")
-        (minus:V2SF (match_operand:V2SF 2 "register_operand")
-		    (match_operand:V2SF 1 "nonimmediate_operand")))]
+  [(parallel
+     [(set (match_operand:V2SF 0 "register_operand")
+	   (minus:V2SF (match_operand:V2SF 2 "register_operand")
+		       (match_operand:V2SF 1 "nonimmediate_operand")))
+      (unspec [(const_int 0)] UNSPEC_3DNOW)])]
   "TARGET_3DNOW")
 
 (define_insn "*mmx_subv2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
-		    (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
+		    (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
   "@
    pfsub\t{%2, %0|%0, %2}
@@ -769,16 +779,19 @@  (define_insn "*mmx_subv2sf3"
    (set_attr "mode" "V2SF")])
 
 (define_expand "mmx_mulv2sf3"
-  [(set (match_operand:V2SF 0 "register_operand")
-	(mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
-		   (match_operand:V2SF 2 "nonimmediate_operand")))]
+  [(parallel
+     [(set (match_operand:V2SF 0 "register_operand")
+	   (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
+		      (match_operand:V2SF 2 "nonimmediate_operand")))
+      (unspec [(const_int 0)] UNSPEC_3DNOW)])]
   "TARGET_3DNOW"
   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
 
 (define_insn "*mmx_mulv2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
 	(mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
-		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
+		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
   "pfmul\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxmul")
@@ -827,10 +840,11 @@  (define_expand "<code>v2sf3"
 })
 
 (define_expand "mmx_<code>v2sf3"
-  [(set (match_operand:V2SF 0 "register_operand")
-        (smaxmin:V2SF
-	  (match_operand:V2SF 1 "nonimmediate_operand")
-	  (match_operand:V2SF 2 "nonimmediate_operand")))]
+  [(parallel
+     [(set (match_operand:V2SF 0 "register_operand")
+	   (smaxmin:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
+			 (match_operand:V2SF 2 "nonimmediate_operand")))
+      (unspec [(const_int 0)] UNSPEC_3DNOW)])]
   "TARGET_3DNOW"
 {
   if (!flag_finite_math_only || flag_signed_zeros)
@@ -851,9 +865,9 @@  (define_expand "mmx_<code>v2sf3"
 
 (define_insn "*mmx_<code>v2sf3"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
-        (smaxmin:V2SF
-	  (match_operand:V2SF 1 "nonimmediate_operand" "%0")
-	  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
+        (smaxmin:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
+		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
   "pf<maxmin_float>\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
@@ -871,7 +885,8 @@  (define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
         (unspec:V2SF
 	  [(match_operand:V2SF 1 "register_operand" "0")
 	   (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
-	  IEEE_MAXMIN))]
+	  IEEE_MAXMIN))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW"
   "pf<ieee_maxmin>\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
@@ -1124,16 +1139,19 @@  (define_expand "vec_addsubv2sf3"
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (define_expand "mmx_eqv2sf3"
-  [(set (match_operand:V2SI 0 "register_operand")
-	(eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
-		 (match_operand:V2SF 2 "nonimmediate_operand")))]
-  "TARGET_3DNOW"
+  [(parallel
+     [(set (match_operand:V2SI 0 "register_operand")
+	   (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
+		    (match_operand:V2SF 2 "nonimmediate_operand")))
+      (unspec [(const_int 0)] UNSPEC_3DNOW)])]
+"TARGET_3DNOW"
   "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
 
 (define_insn "*mmx_eqv2sf3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
 	(eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
-		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
+		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
   "pfcmpeq\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxcmp")
@@ -1143,7 +1161,8 @@  (define_insn "*mmx_eqv2sf3"
 (define_insn "mmx_gtv2sf3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
 	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
-		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
+		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW"
   "pfcmpgt\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxcmp")
@@ -1153,7 +1172,8 @@  (define_insn "mmx_gtv2sf3"
 (define_insn "mmx_gev2sf3"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
 	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
-		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
+		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW"
   "pfcmpge\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxcmp")
@@ -1485,7 +1505,8 @@  (define_expand "fixuns_truncv2sfv2si2"
 
 (define_insn "mmx_fix_truncv2sfv2si2"
   [(set (match_operand:V2SI 0 "register_operand" "=y")
-	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
+	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW"
   "pf2id\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmxcvt")
@@ -1526,7 +1547,8 @@  (define_expand "floatunsv2siv2sf2"
 
 (define_insn "mmx_floatv2siv2sf2"
   [(set (match_operand:V2SF 0 "register_operand" "=y")
-	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
+	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))
+   (unspec [(const_int 0)] UNSPEC_3DNOW)]
   "TARGET_3DNOW"
   "pi2fd\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmxcvt")
diff --git a/gcc/testsuite/gcc.target/i386/pr117926.c b/gcc/testsuite/gcc.target/i386/pr117926.c
new file mode 100644
index 00000000000..6b7aca3726d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr117926.c
@@ -0,0 +1,18 @@ 
+/* PR target/117926 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -m3dnow" } */
+
+struct s
+{
+  int i[2];
+  float f[2];
+  double d;
+};
+
+void f (struct s *s)
+{
+  s->f[0] = s->i[0];
+  s->f[1] = s->i[1];
+}
+
+/* { dg-final { scan-assembler-not "pi2fd" } } */