On Tue, Jun 14, 2016 at 12:50 AM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Mon, Jun 13, 2016 at 11:54 PM, Joseph Myers <jos...@codesourcery.com> 
> wrote:
>
>>> Attached patch intriduces __builtin_signbitq built-in function, so the
>>> compiler will be able to use SSE4.1 PTEST instruction to determine
>>> sign bit of __float128 value.
>>
>> The __builtin_signbit function is type-generic from GCC 6 onwards, so I
>> don't see any need for this type-specific function.  (The .md pattern may
>> still be useful, of course, for better expansion of type-generic
>> __builtin_signbit on float128 arguments.)
>>
>>> The patch introduces complete infrastructure, including fallback to
>>> __signbittf2 libgcc function for non-SSE4.1 targets.
>>
>> I don't see any need for a libgcc fallback either.  Generic code in GCC
>> should always be able to implement signbit using bit-manipulation, without
>> needing any library fallback.

After some more head scratching, I have reverted my v1 patch and
committed the following revision. It works like magic, without any
libgcc fallbacks.

Thanks for guiding me to the right direction, and sorry for the troubles!

2016-06-13  Uros Bizjak  <ubiz...@gmail.com>

    * config/i386/i386.md (signbittf2): New expander.
    * config/i386/sse.md (ptesttf2): New insn pattern.

testsuite/ChangeLog:

2016-06-13  Uros Bizjak  <ubiz...@gmail.com>

    * gcc.target/i386/float128-3.c: New test.
    * gcc.target/i386/quad-sse4.c: Ditto.
    * gcc.target/i386/quad-sse.c: Use -msse instead of -msse2.
    Update scan strings.

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

Committed to mainline SVN.

Uros.
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 237382)
+++ config/i386/i386.md (working copy)
@@ -16198,6 +16198,22 @@
   DONE;
 })
 
+(define_expand "signbittf2"
+  [(use (match_operand:SI 0 "register_operand"))
+   (use (match_operand:TF 1 "register_operand"))]
+  "TARGET_SSE4_1"
+{
+  rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
+  rtx scratch = gen_reg_rtx (QImode);
+
+  emit_insn (gen_ptesttf2 (operands[1], mask));
+  ix86_expand_setcc (scratch, NE,
+                    gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
+
+  emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
+  DONE;
+})
+
 (define_expand "signbitxf2"
   [(use (match_operand:SI 0 "register_operand"))
    (use (match_operand:XF 1 "register_operand"))]
Index: config/i386/sse.md
===================================================================
--- config/i386/sse.md  (revision 237380)
+++ config/i386/sse.md  (working copy)
@@ -15212,6 +15212,19 @@
      (const_string "*")))
    (set_attr "mode" "<sseinsnmode>")])
 
+(define_insn "ptesttf2"
+  [(set (reg:CC FLAGS_REG)
+       (unspec:CC [(match_operand:TF 0 "register_operand" "Yr, *x, x")
+                   (match_operand:TF 1 "vector_operand" "YrBm, *xBm, xm")]
+                  UNSPEC_PTEST))]
+  "TARGET_SSE4_1"
+  "%vptest\t{%1, %0|%0, %1}"
+  [(set_attr "isa" "noavx,noavx,avx")
+   (set_attr "type" "ssecomi")
+   (set_attr "prefix_extra" "1")
+   (set_attr "prefix" "orig,orig,vex")
+   (set_attr "mode" "TI")])
+
 (define_insn "<sse4_1>_round<ssemodesuffix><avxsizesuffix>"
   [(set (match_operand:VF_128_256 0 "register_operand" "=Yr,*x,x")
        (unspec:VF_128_256
Index: testsuite/gcc.target/i386/float128-3.c
===================================================================
--- testsuite/gcc.target/i386/float128-3.c      (nonexistent)
+++ testsuite/gcc.target/i386/float128-3.c      (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse4.1" } */
+/* { dg-require-effective-target sse4 } */
+
+#include "sse4_1-check.h"
+
+int signbit (__float128);
+
+extern void abort (void);
+
+static void
+sse4_1_test (void)
+{
+  static volatile __float128 a;
+
+  a = -1.2q;
+  if (!signbit (a))
+    abort ();
+
+  a = 1.2q;
+  if (signbit (a))
+    abort ();
+}
Index: gcc/testsuite/gcc.target/i386/quad-sse.c
===================================================================
--- gcc/testsuite/gcc.target/i386/quad-sse.c    (revision 237380)
+++ gcc/testsuite/gcc.target/i386/quad-sse.c    (working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -msse2" } */
+/* { dg-options "-O2 -msse" } */
 
 __float128 x, y;
 
@@ -18,4 +18,4 @@ __float128 test_3(void)
   return __builtin_copysignq (x, y);
 }
 
-/* { dg-final { scan-assembler-not "call.*(neg|fabs|copysign)" } } */
+/* { dg-final { scan-assembler-not "neg|fabs|copysign" } } */
Index: testsuite/gcc.target/i386/quad-sse4.c
===================================================================
--- testsuite/gcc.target/i386/quad-sse4.c       (nonexistent)
+++ testsuite/gcc.target/i386/quad-sse4.c       (working copy)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.1" } */
+
+int signbit (__float128);
+
+__float128 x;
+
+int __test_1(void)
+{
+  return signbit (x);
+}
+
+/* { dg-final { scan-assembler-not "signbit" } } */

Reply via email to