summaryrefslogtreecommitdiff
path: root/gcc/fold-const-call.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fold-const-call.c')
-rw-r--r--gcc/fold-const-call.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c
index 60acf96bbf3..fcf4a14ebaa 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -1195,6 +1195,28 @@ fold_const_call (combined_fn fn, tree type, tree arg)
}
}
+/* Fold a call to IFN_FOLD_LEFT_<CODE> (ARG0, ARG1), returning a value
+ of type TYPE. */
+
+static tree
+fold_const_fold_left (tree type, tree arg0, tree arg1, tree_code code)
+{
+ if (TREE_CODE (arg1) != VECTOR_CST)
+ return NULL_TREE;
+
+ unsigned HOST_WIDE_INT nelts;
+ if (!VECTOR_CST_NELTS (arg1).is_constant (&nelts))
+ return NULL_TREE;
+
+ for (unsigned HOST_WIDE_INT i = 0; i < nelts; i++)
+ {
+ arg0 = const_binop (code, type, arg0, VECTOR_CST_ELT (arg1, i));
+ if (arg0 == NULL_TREE || !CONSTANT_CLASS_P (arg0))
+ return NULL_TREE;
+ }
+ return arg0;
+}
+
/* Try to evaluate:
*RESULT = FN (*ARG0, *ARG1)
@@ -1500,6 +1522,9 @@ fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
}
return NULL_TREE;
+ case CFN_FOLD_LEFT_PLUS:
+ return fold_const_fold_left (type, arg0, arg1, PLUS_EXPR);
+
default:
return fold_const_call_1 (fn, type, arg0, arg1);
}