diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2021-11-30 09:52:25 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2021-11-30 09:52:25 +0000 |
commit | e9fff24cd2b365a236fcb31bdf186f6ec9e00f76 (patch) | |
tree | 8bf1c8fe2dcdb1f22fe4a1eafb002f6ceb1b2872 /gcc/gimple-fold.c | |
parent | e32b9eb32d7cd2d39bf9c70497890ac61b9ee14c (diff) | |
download | gcc-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.c | 25 |
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: |