aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2024-04-20 12:26:52 +0200
committerMarc Poulhiès <poulhies@adacore.com>2024-06-21 10:34:22 +0200
commit9aa8324e8a2c992593591d965b3e2d527ed891d3 (patch)
tree9a372d6c8200ea62ae235defdfec84e3f327ea2e /gcc/ada
parent4e128544abc14871388ca194e61d6c482d3a11a6 (diff)
downloadgcc-9aa8324e8a2c992593591d965b3e2d527ed891d3.zip
gcc-9aa8324e8a2c992593591d965b3e2d527ed891d3.tar.gz
gcc-9aa8324e8a2c992593591d965b3e2d527ed891d3.tar.bz2
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) <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.
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/gcc-interface/trans.cc2
-rw-r--r--gcc/ada/gcc-interface/utils2.cc12
2 files changed, 8 insertions, 6 deletions
diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index 7c52826..83ed17b 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 a37eccc..d101d77 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)
{