diff mbox series

[COMMITTED,19/22] ada: Implement fast modulo reduction for nonbinary modular multiplication

Message ID 20240621085819.2485987-19-poulhies@adacore.com
State New
Headers show
Series [COMMITTED,01/22] ada: Spurious style error with mutiple square brackets | expand

Commit Message

Marc Poulhiès June 21, 2024, 8:58 a.m. UTC
From: Eric Botcazou <ebotcazou@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 mbox series

Patch

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)
 	    {