From: Eric Botcazou <ebotca...@adacore.com> This adds the missing guard to prevent the reduction from being used when the target does not provide or cannot synthesize a high-part multiply.
gcc/ada/ * gcc-interface/trans.cc (gnat_to_gnu) <N_Op_Mod>: Fix formatting. * gcc-interface/utils2.cc: Include optabs-query.h. (fast_modulo_reduction): Call can_mult_highpart_p on the TYPE_MODE before generating a high-part multiply. Fix formatting. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/gcc-interface/trans.cc | 2 +- gcc/ada/gcc-interface/utils2.cc | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index 7c5282602b2..83ed17bff84 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -7323,7 +7323,7 @@ gnat_to_gnu (Node_Id gnat_node) pair in the needed precision up to the word size. But not when optimizing for size, because it will be longer than a div+mul+sub sequence. */ - else if (!optimize_size + else if (!optimize_size && (code == FLOOR_MOD_EXPR || code == TRUNC_MOD_EXPR) && TYPE_UNSIGNED (gnu_type) && TYPE_PRECISION (gnu_type) <= BITS_PER_WORD diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc index a37eccc4cfb..d101d7729bf 100644 --- a/gcc/ada/gcc-interface/utils2.cc +++ b/gcc/ada/gcc-interface/utils2.cc @@ -35,6 +35,7 @@ #include "builtins.h" #include "expmed.h" #include "fold-const.h" +#include "optabs-query.h" #include "stor-layout.h" #include "stringpool.h" #include "varasm.h" @@ -558,11 +559,11 @@ fast_modulo_reduction (tree op, tree modulus, unsigned int precision) op / d = (op * multiplier) >> shifter - But choose_multiplier provides a slightly different interface: + But choose_multiplier provides a slightly different interface: - op / d = (op h* multiplier) >> reduced_shifter + op / d = (op h* multiplier) >> reduced_shifter - that makes things easier by using a high-part multiplication. */ + that makes things easier by using a high-part multiplication. */ mh = choose_multiplier (d, type_precision, precision, &ml, &post_shift); /* If the suggested multiplier is more than TYPE_PRECISION bits, we can @@ -577,8 +578,9 @@ fast_modulo_reduction (tree op, tree modulus, unsigned int precision) pre_shift = 0; /* If the suggested multiplier is still more than TYPE_PRECISION bits, - try again with a larger type up to the word size. */ - if (mh != 0) + or the TYPE_MODE does not have a high-part multiply, try again with + a larger type up to the word size. */ + if (mh != 0 || !can_mult_highpart_p (TYPE_MODE (type), true)) { if (type_precision < BITS_PER_WORD) { -- 2.45.1