===================================================================
@@ -8182,6 +8182,59 @@
return NULL_RTX;
}
+static bool
+is_copysign_call_with_1 (gimple *call)
+{
+ if (!is_gimple_call (call))
+ return false;
+
+ if (gimple_call_builtin_p (call, BUILT_IN_NORMAL))
+ {
+ gcall *c = as_a<gcall*> (call);
+ tree decl = gimple_call_fndecl (call);
+ switch (DECL_FUNCTION_CODE (decl))
+ {
+ CASE_FLT_FN (BUILT_IN_COPYSIGN):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
+ return real_one_p (gimple_call_arg (c, 0));
+ default:
+ return false;
+ }
+ }
+}
+
+static rtx
+maybe_expand_mult_copysign (tree treeop0, tree treeop1, rtx target)
+{
+ tree type = TREE_TYPE (treeop0);
+ rtx op0, op1;
+
+ if (!SCALAR_FLOAT_TYPE_P (type)
+ && VECTOR_FLOAT_TYPE_P (type))
+ return NULL;
+
+ if (HONOR_SNANS (type))
+ return NULL;
+
+ if (!targetm.expand_mult_copysign_xor ())
+ return NULL;
+
+ if (TREE_CODE (treeop0) == SSA_NAME)
+ {
+ gimple *call0 = SSA_NAME_DEF_STMT (treeop0);
+ if (is_copysign_call_with_1 (call0))
+ {
+ gcall *c = as_a<gcall*> (call0);
+ treeop0 = gimple_call_arg (c, 1);
+ expand_operands (treeop1, treeop0, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
+ return expand_copysign (op0, op1, target, true);
+ }
+ }
+
+ return NULL;
+}
+
+
rtx
expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
enum expand_modifier modifier)
@@ -8791,6 +8844,10 @@
if (modifier == EXPAND_STACK_PARM)
target = 0;
+ temp = maybe_expand_mult_copysign (treeop0, treeop1);
+ if (temp)
+ return temp;
+
expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
===================================================================
@@ -2640,6 +2640,13 @@
default_have_conditional_execution)
DEFHOOK
+(expand_mult_copysign_xor,
+ "This target hook returns true if the target wants to use xor's\n
+to expand x * copysign (1., y) as x ^ (y & (1 << sign_bit_position)).\n"
+ bool, (void),
+ hook_bool_void_false)
+
+DEFHOOK
(gen_ccmp_first,
"This function prepares to emit a comparison insn for the first compare in a\n\
sequence of conditional comparisions. It returns an appropriate comparison\n\