Skip to content

Commit 9ce9c29

Browse files
artemiy-volkovMichielDerhaeg
authored andcommitted
arcv: do not emit 64-bit MAC pairs for 32-bit data
Currently on ARC-V, the maddhisi3 pattern always expands to the madd_split_fused instruction regardless of the target word size, which leads to the full-width mul and add instructions being emitted for 32-bit data even on riscv64: mul a6,a4,s6 add a6,a6,s7 sext.w s7,a6 To fix this, add another define_insn (madd_split_fused_extended) pattern wrapping the result of a MAC operation into a sign-extension from 32 to 64 bits, and use it in the (u)maddhisi3 expander in case of a 64-bit target. The assembly code after this change is more efficient, viz.: mulw a6,a4,s6 addw a6,a6,s7 Signed-off-by: Artemiy Volkov <artemiy@synopsys.com>
1 parent 285dc3d commit 9ce9c29

File tree

1 file changed

+53
-2
lines changed

1 file changed

+53
-2
lines changed

gcc/config/riscv/riscv.md

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4534,7 +4534,21 @@
45344534
rtx tmp0 = gen_reg_rtx (SImode), tmp1 = gen_reg_rtx (SImode);
45354535
emit_insn (gen_extendhisi2 (tmp0, operands[1]));
45364536
emit_insn (gen_extendhisi2 (tmp1, operands[2]));
4537-
emit_insn (gen_madd_split_fused (operands[0], tmp0, tmp1, operands[3]));
4537+
4538+
if (TARGET_64BIT)
4539+
{
4540+
rtx op0 = gen_reg_rtx (DImode);
4541+
emit_insn (gen_madd_split_fused_extended (op0, tmp0, tmp1, operands[3]));
4542+
op0 = gen_lowpart (SImode, op0);
4543+
SUBREG_PROMOTED_VAR_P (op0) = 1;
4544+
SUBREG_PROMOTED_SET (op0, SRP_SIGNED);
4545+
emit_move_insn (operands[0], op0);
4546+
}
4547+
else
4548+
{
4549+
emit_insn (gen_madd_split_fused (operands[0], tmp0, tmp1, operands[3]));
4550+
}
4551+
45384552
DONE;
45394553
}
45404554
}
@@ -4552,7 +4566,21 @@
45524566
rtx tmp0 = gen_reg_rtx (SImode), tmp1 = gen_reg_rtx (SImode);
45534567
emit_insn (gen_zero_extendhisi2 (tmp0, operands[1]));
45544568
emit_insn (gen_zero_extendhisi2 (tmp1, operands[2]));
4555-
emit_insn (gen_madd_split_fused (operands[0], tmp0, tmp1, operands[3]));
4569+
4570+
if (TARGET_64BIT)
4571+
{
4572+
rtx op0 = gen_reg_rtx (DImode);
4573+
emit_insn (gen_madd_split_fused_extended (op0, tmp0, tmp1, operands[3]));
4574+
op0 = gen_lowpart (SImode, op0);
4575+
SUBREG_PROMOTED_VAR_P (op0) = 1;
4576+
SUBREG_PROMOTED_SET (op0, SRP_SIGNED);
4577+
emit_move_insn (operands[0], op0);
4578+
}
4579+
else
4580+
{
4581+
emit_insn (gen_madd_split_fused (operands[0], tmp0, tmp1, operands[3]));
4582+
}
4583+
45564584
DONE;
45574585
}
45584586
)
@@ -4588,6 +4616,29 @@
45884616
[(set_attr "type" "imul_fused")]
45894617
)
45904618

4619+
(define_insn "madd_split_fused_extended"
4620+
[(set (match_operand:DI 0 "register_operand" "=&r,r")
4621+
(sign_extend:DI
4622+
(plus:SI
4623+
(mult:SI (match_operand:SI 1 "register_operand" "r,r")
4624+
(match_operand:SI 2 "register_operand" "r,r"))
4625+
(match_operand:SI 3 "register_operand" "r,?0"))))
4626+
(clobber (match_scratch:SI 4 "=&r,&r"))]
4627+
"arcv_micro_arch_supports_fusion_p ()
4628+
&& (TARGET_ZMMUL || TARGET_MUL)"
4629+
{
4630+
if (REGNO (operands[0]) == REGNO (operands[3]))
4631+
{
4632+
return "mulw\t%4,%1,%2\n\taddw\t%4,%3,%4\n\tmv\t%0,%4";
4633+
}
4634+
else
4635+
{
4636+
return "mulw\t%0,%1,%2\n\taddw\t%0,%0,%3";
4637+
}
4638+
}
4639+
[(set_attr "type" "imul_fused")]
4640+
)
4641+
45914642
(define_insn "*zero_extract_fused"
45924643
[(set (match_operand:SI 0 "register_operand" "=r")
45934644
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")

0 commit comments

Comments
 (0)