]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR target/90075 Prefer bsl/bit/bif for copysignf. (backport GCC-7)
authorSrinath Parvathaneni <srinath.parvathaneni@arm.com>
Tue, 30 Apr 2019 09:31:04 +0000 (09:31 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Tue, 30 Apr 2019 09:31:04 +0000 (09:31 +0000)
This patch is to fix the ICE caused by expand pattern of copysignf
builtin. This is a back port to r267019 of trunk.

gcc:

2019-04-30  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

PR target/90075
* config/aarch64/iterators.md (V_INT_EQUIV): Add mode for
integer equivalent of floating point values.

Backport from mainline
2018-12-11  Richard Earnshaw  <Richard.Earnshaw@arm.com>

PR target/37369
* config/aarch64/iterators.md (sizem1): Add sizes for
SFmode and DFmode.
(Vbtype): Add SFmode mapping.
* config/aarch64/aarch64.md (copysigndf3, copysignsf3): Delete.
(copysign<GPF:mode>3): New expand pattern.
(copysign<GPF:mode>3_insn): New insn pattern.

testsuite:

2019-04-30  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

PR target/90075
* gcc.target/aarch64/pr90075.c: New test.

From-SVN: r270684

gcc/ChangeLog
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/iterators.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/pr90075.c [new file with mode: 0644]

index cdec6b41c72e3d7eade678f9394c686a919465d1..d8bb38f6fb83f8a8c8a43df1954abe1fab8832c5 100644 (file)
@@ -1,3 +1,20 @@
+2019-04-30  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>
+
+       PR target/90075
+       * config/aarch64/iterators.md (V_INT_EQUIV): Add mode for
+       integer equivalent of floating point values.
+
+       Backport from mainline
+       2018-12-11  Richard Earnshaw  <Richard.Earnshaw@arm.com>
+
+       PR target/37369
+       * config/aarch64/iterators.md (sizem1): Add sizes for
+       SFmode and DFmode.
+       (Vbtype): Add SFmode mapping.
+       * config/aarch64/aarch64.md (copysigndf3, copysignsf3): Delete.
+       (copysign<GPF:mode>3): New expand pattern.
+       (copysign<GPF:mode>3_insn): New insn pattern.
+
 2019-04-22  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        Backport from mainline
index 4c4e144587e6daa8e577477460594ebd66dbdf33..90f9ee658c5cc2eb0477502b3f9e2f60b7b23efd 100644 (file)
     UNSPEC_RSQRTS
     UNSPEC_NZCV
     UNSPEC_XPACLRI
+    UNSPEC_COPYSIGN
 ])
 
 (define_c_enum "unspecv" [
 ;;   LDR d2, #(1 << 63)
 ;;   BSL v2.8b, [y], [x]
 ;;
-;; or another, equivalent, sequence using one of BSL/BIT/BIF.
-;; aarch64_simd_bsldf will select the best suited of these instructions
-;; to generate based on register allocation, and knows how to partially
-;; constant fold based on the values of X and Y, so expand through that.
-
-(define_expand "copysigndf3"
-  [(match_operand:DF 0 "register_operand")
-   (match_operand:DF 1 "register_operand")
-   (match_operand:DF 2 "register_operand")]
+;; or another, equivalent, sequence using one of BSL/BIT/BIF.  Because
+;; we expect these operations to nearly always operate on
+;; floating-point values, we do not want the operation to be
+;; simplified into a bit-field insert operation that operates on the
+;; integer side, since typically that would involve three inter-bank
+;; register copies.  As we do not expect copysign to be followed by
+;; other logical operations on the result, it seems preferable to keep
+;; this as an unspec operation, rather than exposing the underlying
+;; logic to the compiler.
+
+(define_expand "copysign<GPF:mode>3"
+  [(match_operand:GPF 0 "register_operand")
+   (match_operand:GPF 1 "register_operand")
+   (match_operand:GPF 2 "register_operand")]
   "TARGET_FLOAT && TARGET_SIMD"
 {
-  rtx mask = gen_reg_rtx (DImode);
-  emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 63));
-  emit_insn (gen_aarch64_simd_bsldf (operands[0], mask,
-                                    operands[2], operands[1]));
+  rtx bitmask = gen_reg_rtx (<V_INT_EQUIV>mode);
+  emit_move_insn (bitmask, GEN_INT (HOST_WIDE_INT_M1U
+                               << (GET_MODE_BITSIZE (<MODE>mode) - 1)));
+  emit_insn (gen_copysign<mode>3_insn (operands[0], operands[1], operands[2],
+                                      bitmask));
   DONE;
 }
 )
 
-;; As above, but we must first get to a 64-bit value if we wish to use
-;; aarch64_simd_bslv2sf.
-
-(define_expand "copysignsf3"
-  [(match_operand:SF 0 "register_operand")
-   (match_operand:SF 1 "register_operand")
-   (match_operand:SF 2 "register_operand")]
+(define_insn "copysign<GPF:mode>3_insn"
+  [(set (match_operand:GPF 0 "register_operand" "=w,w,w,r")
+       (unspec:GPF [(match_operand:GPF 1 "register_operand" "w,0,w,r")
+                    (match_operand:GPF 2 "register_operand" "w,w,0,0")
+                    (match_operand:<V_INT_EQUIV> 3 "register_operand"
+                    "0,w,w,X")]
+        UNSPEC_COPYSIGN))]
   "TARGET_FLOAT && TARGET_SIMD"
-{
-  rtx mask = gen_reg_rtx (DImode);
-
-  /* Juggle modes to get us in to a vector mode for BSL.  */
-  rtx op1 = lowpart_subreg (V2SFmode, operands[1], SFmode);
-  rtx op2 = lowpart_subreg (V2SFmode, operands[2], SFmode);
-  rtx tmp = gen_reg_rtx (V2SFmode);
-  emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 31));
-  emit_insn (gen_aarch64_simd_bslv2sf (tmp, mask, op2, op1));
-  emit_move_insn (operands[0], lowpart_subreg (SFmode, tmp, V2SFmode));
-  DONE;
-}
+  "@
+   bsl\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>
+   bit\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
+   bif\\t%0.<Vbtype>, %1.<Vbtype>, %3.<Vbtype>
+   bfxil\\t%<w1>0, %<w1>1, #0, <sizem1>"
+  [(set_attr "type" "neon_bsl<q>,neon_bsl<q>,neon_bsl<q>,bfm")]
 )
 
 ;; -------------------------------------------------------------------
index 43be7fd361116d305b0300a814ffca82a9c44a88..4a39e30da13986a6f6ef68eebca7eb29f108b2e9 100644 (file)
 (define_mode_attr sizen [(QI "8") (HI "16") (SI "32") (DI "64")])
 
 ;; Give the ordinal of the MSB in the mode
-(define_mode_attr sizem1 [(QI "#7") (HI "#15") (SI "#31") (DI "#63")])
+(define_mode_attr sizem1 [(QI "#7") (HI "#15") (SI "#31") (DI "#63")
+                         (HF "#15") (SF "#31") (DF "#63")])
 
 ;; Attribute to describe constants acceptable in logical operations
 (define_mode_attr lconst [(SI "K") (DI "L")])
                          (V8HF "16b") (V2SF  "8b")
                          (V4SF "16b") (V2DF  "16b")
                          (DI   "8b")  (DF    "8b")
-                         (SI   "8b")])
+                         (SI   "8b")  (SF    "8b")])
 
 ;; Define element mode for each vector mode.
 (define_mode_attr VEL [(V8QI "QI") (V16QI "QI")
 ;; Double vector types for ALLX.
 (define_mode_attr Vallxd [(QI "8b") (HI "4h") (SI "2s")])
 
+;; Mode with floating-point values replaced by like-sized integers.
+(define_mode_attr V_INT_EQUIV [(DF "DI") (SF "SI")])
+
 ;; Mode of result of comparison operations.
 (define_mode_attr V_cmp_result [(V8QI "V8QI") (V16QI "V16QI")
                                (V4HI "V4HI") (V8HI  "V8HI")
index ec30fd2971db95fbbd2b7676d6788933656a89f7..2b9c4f5a9877ecd107c49bf54edab80e2b35460e 100644 (file)
@@ -1,3 +1,8 @@
+2019-04-30  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>
+
+       PR target/90075
+       * gcc.target/aarch64/pr90075.c: New test.
+
 2019-04-25  Xiong Hu Luo  <luoxhu@linux.ibm.com>
 
        * gcc.target/powerpc/vsx-vector-6.p8.c: Fix failure caused by typo.
diff --git a/gcc/testsuite/gcc.target/aarch64/pr90075.c b/gcc/testsuite/gcc.target/aarch64/pr90075.c
new file mode 100644 (file)
index 0000000..cae7e61
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O1" } */
+
+typedef struct {
+  float one, two;
+} twofloats;
+
+float
+bug (twofloats tf)
+{
+  float f1, f2;
+  union {
+    twofloats tfloats;
+    float arr[2];
+  } utfloats;
+
+  utfloats.tfloats = tf;
+  f1 = utfloats.arr[1];
+  f2 = __builtin_copysignf (0, f1);
+  return f2;
+}