[AArch64] Use unspecs for SVE conversions involving floats
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 14 Aug 2019 08:34:12 +0000 (08:34 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 14 Aug 2019 08:34:12 +0000 (08:34 +0000)
This patch changes the SVE FP<->FP and FP<->INT patterns so that
they use unspecs rather than rtx codes, continuing the series
to make the patterns work with predicates that might not be all-true.

2019-08-14  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* config/aarch64/aarch64.md (UNSPEC_FLOAT_CONVERT): Delete.
* config/aarch64/iterators.md (UNSPEC_COND_FCVT, UNSPEC_COND_FCVTZS)
(UNSPEC_COND_FCVTZU, UNSPEC_COND_SCVTF, UNSPEC_COND_UCVTF): New
unspecs.
(optab, su): Handle them.
(SVE_COND_FCVTI, SVE_COND_ICVTF): New int iterators.
* config/aarch64/aarch64-sve.md
(<fix_trunc_optab><SVE_F:mode><v_int_equiv>2): Replace with...
(<SVE_COND_FCVTI:optab><SVE_F:mode><v_int_equiv>2): ...this.
(*<fix_trunc_optab>v16hsf<:SVE_HSDImode>2): Replace with...
(*<SVE_COND_FCVTI:optab>v16hsf<SVE_F:mode>2): ...this.
(*<fix_trunc_optab>vnx4sf<SVE_SDI:mode>2): Replace with...
(*<SVE_COND_FCVTI:optab>vnx4sf<SVE_SDI:mode>2): ...this.
(*<fix_trunc_optab>vnx2df<SVE_SDI:mode>2): Replace with...
(*<SVE_COND_FCVTI:optab>vnx2df<SVE_SDI:mode>2): ...this.
(vec_pack_<su>fix_trunc_vnx2df): Use SVE_COND_FCVTI instead of
FIXUORS.
(<FLOATUORS:optab><v_int_equiv><SVE_F:mode>2): Replace with...
(<SVE_COND_ICVTF:optab><v_int_equiv><SVE_F:mode>2): ...this.
(*<FLOATUORS:optab><SVE_HSDI:mode>vnx8hf2): Replace with...
(*<SVE_COND_ICVTF:optab><SVE_HSDI:mode>vnx8hf2): ...this.
(*<FLOATUORS:optab><SVE_SDI:mode>vnx4sf2): Replace with...
(*<SVE_COND_ICVTF:optab><SVE_SDI:mode>vnx4sf2): ...this.
(aarch64_sve_<FLOATUORS:optab><SVE_SDI:mode>vnx2df2): Replace with...
(aarch64_sve_<SVE_COND_ICVTF:optab><SVE_SDI:mode>vnx2df2): ...this.
(vec_unpack<su_optab>_float_<perm_hilo>_vnx4si): Pass a GP strictness
operand to aarch64_sve_<SVE_COND_ICVTF:optab><SVE_SDI:mode>vnx2df2.
(vec_pack_trunc_<SVE_HSF:Vwide>, *trunc<Vwide><SVE_HSF:mode>2)
(aarch64_sve_extend<mode><Vwide>2): Use UNSPEC_COND_FCVT instead
of UNSPEC_FLOAT_CONVERT.
(vec_unpacks_<perm_hilo>_<mode>): Pass a GP strictness operand to
aarch64_sve_extend<mode><Vwide>2.

From-SVN: r274423

gcc/ChangeLog
gcc/config/aarch64/aarch64-sve.md
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/iterators.md

index 1dee72251e68d338b7f6dda12de682a40f02a92e..2f2a8a44f6b5864d8009a90a9d73a4ae144f1a48 100644 (file)
@@ -1,3 +1,38 @@
+2019-08-14  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * config/aarch64/aarch64.md (UNSPEC_FLOAT_CONVERT): Delete.
+       * config/aarch64/iterators.md (UNSPEC_COND_FCVT, UNSPEC_COND_FCVTZS)
+       (UNSPEC_COND_FCVTZU, UNSPEC_COND_SCVTF, UNSPEC_COND_UCVTF): New
+       unspecs.
+       (optab, su): Handle them.
+       (SVE_COND_FCVTI, SVE_COND_ICVTF): New int iterators.
+       * config/aarch64/aarch64-sve.md
+       (<fix_trunc_optab><SVE_F:mode><v_int_equiv>2): Replace with...
+       (<SVE_COND_FCVTI:optab><SVE_F:mode><v_int_equiv>2): ...this.
+       (*<fix_trunc_optab>v16hsf<:SVE_HSDImode>2): Replace with...
+       (*<SVE_COND_FCVTI:optab>v16hsf<SVE_F:mode>2): ...this.
+       (*<fix_trunc_optab>vnx4sf<SVE_SDI:mode>2): Replace with...
+       (*<SVE_COND_FCVTI:optab>vnx4sf<SVE_SDI:mode>2): ...this.
+       (*<fix_trunc_optab>vnx2df<SVE_SDI:mode>2): Replace with...
+       (*<SVE_COND_FCVTI:optab>vnx2df<SVE_SDI:mode>2): ...this.
+       (vec_pack_<su>fix_trunc_vnx2df): Use SVE_COND_FCVTI instead of
+       FIXUORS.
+       (<FLOATUORS:optab><v_int_equiv><SVE_F:mode>2): Replace with...
+       (<SVE_COND_ICVTF:optab><v_int_equiv><SVE_F:mode>2): ...this.
+       (*<FLOATUORS:optab><SVE_HSDI:mode>vnx8hf2): Replace with...
+       (*<SVE_COND_ICVTF:optab><SVE_HSDI:mode>vnx8hf2): ...this.
+       (*<FLOATUORS:optab><SVE_SDI:mode>vnx4sf2): Replace with...
+       (*<SVE_COND_ICVTF:optab><SVE_SDI:mode>vnx4sf2): ...this.
+       (aarch64_sve_<FLOATUORS:optab><SVE_SDI:mode>vnx2df2): Replace with...
+       (aarch64_sve_<SVE_COND_ICVTF:optab><SVE_SDI:mode>vnx2df2): ...this.
+       (vec_unpack<su_optab>_float_<perm_hilo>_vnx4si): Pass a GP strictness
+       operand to aarch64_sve_<SVE_COND_ICVTF:optab><SVE_SDI:mode>vnx2df2.
+       (vec_pack_trunc_<SVE_HSF:Vwide>, *trunc<Vwide><SVE_HSF:mode>2)
+       (aarch64_sve_extend<mode><Vwide>2): Use UNSPEC_COND_FCVT instead
+       of UNSPEC_FLOAT_CONVERT.
+       (vec_unpacks_<perm_hilo>_<mode>): Pass a GP strictness operand to
+       aarch64_sve_extend<mode><Vwide>2.
+
 2019-08-14  Richard Biener  <rguenther@suse.de>
 
        PR target/91154
index 7cbd690932e6dcf74c8c3c995c489e41bfd497f4..0c9d4c596f9ec810ae9533acb554d038b61031b4 100644 (file)
 
 ;; Unpredicated conversion of floats to integers of the same size (HF to HI,
 ;; SF to SI or DF to DI).
-(define_expand "<fix_trunc_optab><mode><v_int_equiv>2"
+(define_expand "<optab><mode><v_int_equiv>2"
   [(set (match_operand:<V_INT_EQUIV> 0 "register_operand")
        (unspec:<V_INT_EQUIV>
          [(match_dup 2)
-          (FIXUORS:<V_INT_EQUIV>
-            (match_operand:SVE_F 1 "register_operand"))]
-         UNSPEC_MERGE_PTRUE))]
+          (const_int SVE_RELAXED_GP)
+          (match_operand:SVE_F 1 "register_operand")]
+         SVE_COND_FCVTI))]
   "TARGET_SVE"
   {
     operands[2] = aarch64_ptrue_reg (<VPRED>mode);
 )
 
 ;; Conversion of SF to DI, SI or HI, predicated with a PTRUE.
-(define_insn "*<fix_trunc_optab>v16hsf<mode>2"
+(define_insn "*<optab>v16hsf<mode>2"
   [(set (match_operand:SVE_HSDI 0 "register_operand" "=w")
        (unspec:SVE_HSDI
          [(match_operand:<VPRED> 1 "register_operand" "Upl")
-          (FIXUORS:SVE_HSDI
-            (match_operand:VNx8HF 2 "register_operand" "w"))]
-         UNSPEC_MERGE_PTRUE))]
+          (match_operand:SI 3 "aarch64_sve_gp_strictness")
+          (match_operand:VNx8HF 2 "register_operand" "w")]
+         SVE_COND_FCVTI))]
   "TARGET_SVE"
   "fcvtz<su>\t%0.<Vetype>, %1/m, %2.h"
 )
 
 ;; Conversion of SF to DI or SI, predicated with a PTRUE.
-(define_insn "*<fix_trunc_optab>vnx4sf<mode>2"
+(define_insn "*<optab>vnx4sf<mode>2"
   [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
        (unspec:SVE_SDI
          [(match_operand:<VPRED> 1 "register_operand" "Upl")
-          (FIXUORS:SVE_SDI
-            (match_operand:VNx4SF 2 "register_operand" "w"))]
-         UNSPEC_MERGE_PTRUE))]
+          (match_operand:SI 3 "aarch64_sve_gp_strictness")
+          (match_operand:VNx4SF 2 "register_operand" "w")]
+         SVE_COND_FCVTI))]
   "TARGET_SVE"
   "fcvtz<su>\t%0.<Vetype>, %1/m, %2.s"
 )
 
 ;; Conversion of DF to DI or SI, predicated with a PTRUE.
-(define_insn "*<fix_trunc_optab>vnx2df<mode>2"
+(define_insn "*<optab>vnx2df<mode>2"
   [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
        (unspec:SVE_SDI
          [(match_operand:VNx2BI 1 "register_operand" "Upl")
-          (FIXUORS:SVE_SDI
-            (match_operand:VNx2DF 2 "register_operand" "w"))]
-         UNSPEC_MERGE_PTRUE))]
+          (match_operand:SI 3 "aarch64_sve_gp_strictness")
+          (match_operand:VNx2DF 2 "register_operand" "w")]
+         SVE_COND_FCVTI))]
   "TARGET_SVE"
   "fcvtz<su>\t%0.<Vetype>, %1/m, %2.d"
 )
   [(set (match_dup 4)
        (unspec:VNx4SI
          [(match_dup 3)
-          (FIXUORS:VNx4SI (match_operand:VNx2DF 1 "register_operand"))]
-         UNSPEC_MERGE_PTRUE))
+          (const_int SVE_RELAXED_GP)
+          (match_operand:VNx2DF 1 "register_operand")]
+         SVE_COND_FCVTI))
    (set (match_dup 5)
        (unspec:VNx4SI
          [(match_dup 3)
-          (FIXUORS:VNx4SI (match_operand:VNx2DF 2 "register_operand"))]
-         UNSPEC_MERGE_PTRUE))
+          (const_int SVE_RELAXED_GP)
+          (match_operand:VNx2DF 2 "register_operand")]
+         SVE_COND_FCVTI))
    (set (match_operand:VNx4SI 0 "register_operand")
        (unspec:VNx4SI [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
   "TARGET_SVE"
   [(set (match_operand:SVE_F 0 "register_operand")
        (unspec:SVE_F
          [(match_dup 2)
-          (FLOATUORS:SVE_F
-            (match_operand:<V_INT_EQUIV> 1 "register_operand"))]
-         UNSPEC_MERGE_PTRUE))]
+          (const_int SVE_RELAXED_GP)
+          (match_operand:<V_INT_EQUIV> 1 "register_operand")]
+         SVE_COND_ICVTF))]
   "TARGET_SVE"
   {
     operands[2] = aarch64_ptrue_reg (<VPRED>mode);
   [(set (match_operand:VNx8HF 0 "register_operand" "=w")
        (unspec:VNx8HF
          [(match_operand:<VPRED> 1 "register_operand" "Upl")
-          (FLOATUORS:VNx8HF
-            (match_operand:SVE_HSDI 2 "register_operand" "w"))]
-         UNSPEC_MERGE_PTRUE))]
+          (match_operand:SI 3 "aarch64_sve_gp_strictness")
+          (match_operand:SVE_HSDI 2 "register_operand" "w")]
+         SVE_COND_ICVTF))]
   "TARGET_SVE"
-  "<su_optab>cvtf\t%0.h, %1/m, %2.<Vetype>"
+  "<su>cvtf\t%0.h, %1/m, %2.<Vetype>"
 )
 
 ;; Conversion of DI or SI to the same number of SFs, predicated with a PTRUE.
   [(set (match_operand:VNx4SF 0 "register_operand" "=w")
        (unspec:VNx4SF
          [(match_operand:<VPRED> 1 "register_operand" "Upl")
-          (FLOATUORS:VNx4SF
-            (match_operand:SVE_SDI 2 "register_operand" "w"))]
-         UNSPEC_MERGE_PTRUE))]
+          (match_operand:SI 3 "aarch64_sve_gp_strictness")
+          (match_operand:SVE_SDI 2 "register_operand" "w")]
+         SVE_COND_ICVTF))]
   "TARGET_SVE"
-  "<su_optab>cvtf\t%0.s, %1/m, %2.<Vetype>"
+  "<su>cvtf\t%0.s, %1/m, %2.<Vetype>"
 )
 
 ;; Conversion of DI or SI to DF, predicated with a PTRUE.
   [(set (match_operand:VNx2DF 0 "register_operand" "=w")
        (unspec:VNx2DF
          [(match_operand:VNx2BI 1 "register_operand" "Upl")
-          (FLOATUORS:VNx2DF
-            (match_operand:SVE_SDI 2 "register_operand" "w"))]
-         UNSPEC_MERGE_PTRUE))]
+          (match_operand:SI 3 "aarch64_sve_gp_strictness")
+          (match_operand:SVE_SDI 2 "register_operand" "w")]
+         SVE_COND_ICVTF))]
   "TARGET_SVE"
-  "<su_optab>cvtf\t%0.d, %1/m, %2.<Vetype>"
+  "<su>cvtf\t%0.d, %1/m, %2.<Vetype>"
 )
 
 ;; -------------------------------------------------------------------------
                : gen_aarch64_sve_zip1vnx4si)
               (temp, operands[1], operands[1]));
     rtx ptrue = aarch64_ptrue_reg (VNx2BImode);
-    emit_insn (gen_aarch64_sve_<FLOATUORS:optab>vnx4sivnx2df2 (operands[0],
-                                                              ptrue, temp));
+    rtx strictness = gen_int_mode (SVE_RELAXED_GP, SImode);
+    emit_insn (gen_aarch64_sve_<FLOATUORS:optab>vnx4sivnx2df2
+              (operands[0], ptrue, temp, strictness));
     DONE;
   }
 )
   [(set (match_dup 4)
        (unspec:SVE_HSF
          [(match_dup 3)
-          (unspec:SVE_HSF [(match_operand:<VWIDE> 1 "register_operand")]
-                          UNSPEC_FLOAT_CONVERT)]
-         UNSPEC_MERGE_PTRUE))
+          (const_int SVE_RELAXED_GP)
+          (match_operand:<VWIDE> 1 "register_operand")]
+         UNSPEC_COND_FCVT))
    (set (match_dup 5)
        (unspec:SVE_HSF
          [(match_dup 3)
-          (unspec:SVE_HSF [(match_operand:<VWIDE> 2 "register_operand")]
-                          UNSPEC_FLOAT_CONVERT)]
-         UNSPEC_MERGE_PTRUE))
+          (const_int SVE_RELAXED_GP)
+          (match_operand:<VWIDE> 2 "register_operand")]
+         UNSPEC_COND_FCVT))
    (set (match_operand:SVE_HSF 0 "register_operand")
        (unspec:SVE_HSF [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
   "TARGET_SVE"
   [(set (match_operand:SVE_HSF 0 "register_operand" "=w")
        (unspec:SVE_HSF
          [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
-          (unspec:SVE_HSF
-            [(match_operand:<VWIDE> 2 "register_operand" "w")]
-            UNSPEC_FLOAT_CONVERT)]
-         UNSPEC_MERGE_PTRUE))]
+          (match_operand:SI 3 "aarch64_sve_gp_strictness")
+          (match_operand:<VWIDE> 2 "register_operand" "w")]
+         UNSPEC_COND_FCVT))]
   "TARGET_SVE"
   "fcvt\t%0.<Vetype>, %1/m, %2.<Vewtype>"
 )
                : gen_aarch64_sve_zip1<mode>)
                (temp, operands[1], operands[1]));
     rtx ptrue = aarch64_ptrue_reg (<VWIDE_PRED>mode);
-    emit_insn (gen_aarch64_sve_extend<mode><Vwide>2 (operands[0],
-                                                    ptrue, temp));
+    rtx strictness = gen_int_mode (SVE_RELAXED_GP, SImode);
+    emit_insn (gen_aarch64_sve_extend<mode><Vwide>2
+              (operands[0], ptrue, temp, strictness));
     DONE;
   }
 )
   [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
        (unspec:<VWIDE>
          [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
-          (unspec:<VWIDE>
-            [(match_operand:SVE_HSF 2 "register_operand" "w")]
-            UNSPEC_FLOAT_CONVERT)]
-         UNSPEC_MERGE_PTRUE))]
+          (match_operand:SI 3 "aarch64_sve_gp_strictness")
+          (match_operand:SVE_HSF 2 "register_operand" "w")]
+         UNSPEC_COND_FCVT))]
   "TARGET_SVE"
   "fcvt\t%0.<Vewtype>, %1/m, %2.<Vetype>"
 )
index f910166bfba6f56e26a6fd55b69beba7b1ce7662..850c6ada2a5ef7b58a927281cc39202534034b57 100644 (file)
     UNSPEC_UNPACKSLO
     UNSPEC_UNPACKULO
     UNSPEC_PACK
-    UNSPEC_FLOAT_CONVERT
     UNSPEC_WHILE_LO
     UNSPEC_LDN
     UNSPEC_STN
index 6bf3638ed1aabecb4aaad7fd0b43d93d61ef88ee..05adbba9f16433ede22ef419c36522b19b5e350e 100644 (file)
     UNSPEC_COND_FCMLT  ; Used in aarch64-sve.md.
     UNSPEC_COND_FCMNE  ; Used in aarch64-sve.md.
     UNSPEC_COND_FCMUO  ; Used in aarch64-sve.md.
+    UNSPEC_COND_FCVT   ; Used in aarch64-sve.md.
+    UNSPEC_COND_FCVTZS ; Used in aarch64-sve.md.
+    UNSPEC_COND_FCVTZU ; Used in aarch64-sve.md.
     UNSPEC_COND_FDIV   ; Used in aarch64-sve.md.
     UNSPEC_COND_FMAXNM ; Used in aarch64-sve.md.
     UNSPEC_COND_FMINNM ; Used in aarch64-sve.md.
     UNSPEC_COND_FRINTZ ; Used in aarch64-sve.md.
     UNSPEC_COND_FSQRT  ; Used in aarch64-sve.md.
     UNSPEC_COND_FSUB   ; Used in aarch64-sve.md.
+    UNSPEC_COND_SCVTF  ; Used in aarch64-sve.md.
+    UNSPEC_COND_UCVTF  ; Used in aarch64-sve.md.
     UNSPEC_LASTB       ; Used in aarch64-sve.md.
     UNSPEC_FCADD90     ; Used in aarch64-simd.md.
     UNSPEC_FCADD270    ; Used in aarch64-simd.md.
                                        UNSPEC_COND_FRINTZ
                                        UNSPEC_COND_FSQRT])
 
+(define_int_iterator SVE_COND_FCVTI [UNSPEC_COND_FCVTZS UNSPEC_COND_FCVTZU])
+(define_int_iterator SVE_COND_ICVTF [UNSPEC_COND_SCVTF UNSPEC_COND_UCVTF])
+
 (define_int_iterator SVE_COND_FP_BINARY [UNSPEC_COND_FADD
                                         UNSPEC_COND_FDIV
                                         UNSPEC_COND_FMAXNM
                        (UNSPEC_FMINV "smin_nan")
                        (UNSPEC_COND_FABS "abs")
                        (UNSPEC_COND_FADD "add")
+                       (UNSPEC_COND_FCVT "fcvt")
+                       (UNSPEC_COND_FCVTZS "fix_trunc")
+                       (UNSPEC_COND_FCVTZU "fixuns_trunc")
                        (UNSPEC_COND_FDIV "div")
                        (UNSPEC_COND_FMAXNM "smax")
                        (UNSPEC_COND_FMINNM "smin")
                        (UNSPEC_COND_FRINTX "rint")
                        (UNSPEC_COND_FRINTZ "btrunc")
                        (UNSPEC_COND_FSQRT "sqrt")
-                       (UNSPEC_COND_FSUB "sub")])
+                       (UNSPEC_COND_FSUB "sub")
+                       (UNSPEC_COND_SCVTF "float")
+                       (UNSPEC_COND_UCVTF "floatuns")])
 
 (define_int_attr  maxmin_uns [(UNSPEC_UMAXV "umax")
                              (UNSPEC_UMINV "umin")
                     (UNSPEC_UNPACKSLO "s")
                     (UNSPEC_UNPACKULO "u")
                     (UNSPEC_SMUL_HIGHPART "s")
-                    (UNSPEC_UMUL_HIGHPART "u")])
+                    (UNSPEC_UMUL_HIGHPART "u")
+                    (UNSPEC_COND_FCVTZS "s")
+                    (UNSPEC_COND_FCVTZU "u")
+                    (UNSPEC_COND_SCVTF "s")
+                    (UNSPEC_COND_UCVTF "u")])
 
 (define_int_attr sur [(UNSPEC_SHADD "s") (UNSPEC_UHADD "u")
                      (UNSPEC_SRHADD "sr") (UNSPEC_URHADD "ur")