aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index e9cabbe..a5bf13a 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -9052,6 +9052,24 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
op0 = expand_normal (treeop0);
this_optab = optab_for_tree_code (code, type, optab_default);
enum machine_mode vec_mode = TYPE_MODE (TREE_TYPE (treeop0));
+
+ if (optab_handler (this_optab, vec_mode) != CODE_FOR_nothing)
+ {
+ struct expand_operand ops[2];
+ enum insn_code icode = optab_handler (this_optab, vec_mode);
+
+ create_output_operand (&ops[0], target, mode);
+ create_input_operand (&ops[1], op0, vec_mode);
+ if (maybe_expand_insn (icode, 2, ops))
+ {
+ target = ops[0].value;
+ if (GET_MODE (target) != mode)
+ return gen_lowpart (tmode, target);
+ return target;
+ }
+ }
+ /* Fall back to optab with vector result, and then extract scalar. */
+ this_optab = scalar_reduc_to_vector (this_optab, type);
temp = expand_unop (vec_mode, this_optab, op0, NULL_RTX, unsignedp);
gcc_assert (temp);
/* The tree code produces a scalar result, but (somewhat by convention)