@@ -1908,6 +1908,9 @@ or @code{EM_SPARCV9} executables.
@item vect_cmdline_needed
Target requires a command line argument to enable a SIMD instruction set.
+@item xorsign
+Target supports the xorsign optab expansion.
+
@end table
@subsubsection Environment attributes
new file mode 100644
@@ -0,0 +1,86 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-require-effective-target xorsign } */
+/* { dg-require-effective-target arm_v8_neon_ok { target { arm*-*-* } } } */
+/* { dg-add-options arm_v8_neon } */
+
+double
+check_d_pos (double x, double y)
+{
+ return x * __builtin_copysign (1.0, y);
+}
+
+float
+check_f_pos (float x, float y)
+{
+ return x * __builtin_copysignf (1.0f, y);
+}
+
+long double
+check_l_pos (long double x, long double y)
+{
+ return x * __builtin_copysignl (1.0, y);
+}
+
+/* --------------- */
+
+double
+check_d_neg (double x, double y)
+{
+ return x * __builtin_copysign (-1.0, y);
+}
+
+float
+check_f_neg (float x, float y)
+{
+ return x * __builtin_copysignf (-1.0f, y);
+}
+
+long double
+check_l_neg (long double x, long double y)
+{
+ return x * __builtin_copysignl (-1.0, y);
+}
+
+/* --------------- */
+
+double
+check_d_pos_rev (double x, double y)
+{
+ return __builtin_copysign (1.0, y) * x;
+}
+
+float
+check_f_pos_rev (float x, float y)
+{
+ return __builtin_copysignf (1.0f, y) * x;
+}
+
+long double
+check_l_pos_rev (long double x, long double y)
+{
+ return __builtin_copysignl (1.0, y) * x;
+}
+
+/* --------------- */
+
+double
+check_d_neg_rev (double x, double y)
+{
+ return __builtin_copysign (-1.0, y) * x;
+}
+
+float
+check_f_neg_rev (float x, float y)
+{
+ return __builtin_copysignf (-1.0f, y) * x;
+}
+
+long double
+check_l_neg_rev (long double x, long double y)
+{
+ return __builtin_copysignl (-1.0, y) * x;
+}
+
+/* { dg-final { scan-tree-dump "XORSIGN" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "copysign" "optimized" } } */
\ No newline at end of file
@@ -5332,6 +5332,28 @@ proc check_effective_target_vect_perm_short { } {
return $et_vect_perm_short_saved($et_index)
}
+# Return 1 if the target plus current options supports folding of
+# copysign into XORSIGN.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_xorsign { } {
+ global et_xorsign_saved
+ global et_index
+
+ if [info exists et_xorsign_saved($et_index)] {
+ verbose "check_effective_target_xorsign: using cached result" 2
+ } else {
+ set et_xorsign_saved($et_index) 0
+ if { [istarget aarch64*-*-*] || [istarget arm*-*-*] } {
+ set et_xorsign_saved($et_index) 1
+ }
+ }
+ verbose "check_effective_target_xorsign:\
+ returning $et_xorsign_saved($et_index)" 2
+ return $et_xorsign_saved($et_index)
+}
+
# Return 1 if the target plus current options supports a vector
# widening summation of *short* args into *int* result, 0 otherwise.
#