aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2021-11-30 09:52:25 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2021-11-30 09:52:25 +0000
commite9fff24cd2b365a236fcb31bdf186f6ec9e00f76 (patch)
tree8bf1c8fe2dcdb1f22fe4a1eafb002f6ceb1b2872 /gcc/gimple-fold.c
parente32b9eb32d7cd2d39bf9c70497890ac61b9ee14c (diff)
downloadgcc-e9fff24cd2b365a236fcb31bdf186f6ec9e00f76.zip
gcc-e9fff24cd2b365a236fcb31bdf186f6ec9e00f76.tar.gz
gcc-e9fff24cd2b365a236fcb31bdf186f6ec9e00f76.tar.bz2
Canonicalize argument order for commutative functions
This patch uses information about internal functions to canonicalize the argument order of calls. gcc/ * gimple-fold.c: Include internal-fn.h. (fold_stmt_1): If a function maps to an internal one, use first_commutative_argument to canonicalize the order of commutative arguments. * gimple-match-head.c (gimple_resimplify2, gimple_resimplify3) (gimple_resimplify4, gimple_resimplify5): Extend commutativity checks to functions. gcc/testsuite/ * gcc.dg/fmax-fmin-1.c: New test.
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r--gcc/gimple-fold.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 44fba12..1d8fd74 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -69,6 +69,7 @@ along with GCC; see the file COPYING3. If not see
#include "varasm.h"
#include "memmodel.h"
#include "optabs.h"
+#include "internal-fn.h"
enum strlen_range_kind {
/* Compute the exact constant string length. */
@@ -6109,18 +6110,36 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
break;
case GIMPLE_CALL:
{
- for (i = 0; i < gimple_call_num_args (stmt); ++i)
+ gcall *call = as_a<gcall *> (stmt);
+ for (i = 0; i < gimple_call_num_args (call); ++i)
{
- tree *arg = gimple_call_arg_ptr (stmt, i);
+ tree *arg = gimple_call_arg_ptr (call, i);
if (REFERENCE_CLASS_P (*arg)
&& maybe_canonicalize_mem_ref_addr (arg))
changed = true;
}
- tree *lhs = gimple_call_lhs_ptr (stmt);
+ tree *lhs = gimple_call_lhs_ptr (call);
if (*lhs
&& REFERENCE_CLASS_P (*lhs)
&& maybe_canonicalize_mem_ref_addr (lhs))
changed = true;
+ if (*lhs)
+ {
+ combined_fn cfn = gimple_call_combined_fn (call);
+ internal_fn ifn = associated_internal_fn (cfn, TREE_TYPE (*lhs));
+ int opno = first_commutative_argument (ifn);
+ if (opno >= 0)
+ {
+ tree arg1 = gimple_call_arg (call, opno);
+ tree arg2 = gimple_call_arg (call, opno + 1);
+ if (tree_swap_operands_p (arg1, arg2))
+ {
+ gimple_call_set_arg (call, opno, arg2);
+ gimple_call_set_arg (call, opno + 1, arg1);
+ changed = true;
+ }
+ }
+ }
break;
}
case GIMPLE_ASM: