[Bug rtl-optimization/115186] Suboptimal codes generated by rtl-expand for divmod
dizhao at os dot amperecomputing.com
gcc-bugzilla@gcc.gnu.org
Wed May 22 10:28:55 GMT 2024
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115186
--- Comment #1 from Di Zhao <dizhao at os dot amperecomputing.com> ---
A raw fix below can fix this case (not sure if this is the right way):
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 50d22762cae..bf42a0ff5ca 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -3976,7 +3976,10 @@ expmed_mult_highpart (scalar_int_mode mode, rtx op0, rtx
op1,
bool sign_adjust = false;
enum mult_variant variant;
struct algorithm alg;
- rtx narrow_op1, tem;
+ rtx narrow_op1, tem, tem2;
+ rtx_insn *shift_add_insns;
+ rtx_insn *mult_insns;
+ unsigned shift_add_cost, mult_cost;
/* We can't support modes wider than HOST_BITS_PER_INT. */
gcc_assert (HWI_COMPUTABLE_MODE_P (mode));
@@ -4014,6 +4017,7 @@ expmed_mult_highpart (scalar_int_mode mode, rtx op0, rtx
op1,
if (tem)
return tem;
+ start_sequence ();
tem = convert_to_mode (wider_mode, op0, unsignedp);
tem = expand_mult_const (wider_mode, tem, cnst1, 0, &alg, variant);
tem = extract_high_half (mode, tem);
@@ -4021,8 +4025,29 @@ expmed_mult_highpart (scalar_int_mode mode, rtx op0, rtx
op1,
/* Adjust result for signedness. */
if (sign_adjust)
tem = force_operand (gen_rtx_MINUS (mode, tem, op0), tem);
+ shift_add_insns = get_insns ();
+ end_sequence ();
+ shift_add_cost = seq_cost (shift_add_insns, speed);
+
+ start_sequence ();
+ tem2 = expmed_mult_highpart_optab (mode, op0, op1, target, unsignedp,
+ max_cost);
+ mult_insns = get_insns ();
+ end_sequence ();
+ mult_cost = seq_cost (mult_insns, speed);
- return tem;
+ if (tem2 && mult_cost < shift_add_cost)
+ {
+ emit_insn (mult_insns);
+ return tem2;
+ }
+ else if (shift_add_cost < max_cost)
+ {
+ emit_insn (shift_add_insns);
+ return tem;
+ }
+ else
+ return 0;
}
return expmed_mult_highpart_optab (mode, op0, narrow_op1, target,
unsignedp, max_cost);
More information about the Gcc-bugs
mailing list