From: Eric Botcazou Date: Sat, 20 Apr 2024 10:26:52 +0000 (+0200) Subject: ada: Implement fast modulo reduction for nonbinary modular multiplication X-Git-Tag: basepoints/gcc-16~8026 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9aa8324e8a2c992593591d965b3e2d527ed891d3;p=thirdparty%2Fgcc.git ada: Implement fast modulo reduction for nonbinary modular multiplication 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) : 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. --- 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) {