Skip to content

Commit a8477b0

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 12c7874 commit a8477b0

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
@@ -4510,7 +4510,21 @@
45104510
rtx tmp0 = gen_reg_rtx (SImode), tmp1 = gen_reg_rtx (SImode);
45114511
emit_insn (gen_extendhisi2 (tmp0, operands[1]));
45124512
emit_insn (gen_extendhisi2 (tmp1, operands[2]));
4513-
emit_insn (gen_madd_split_fused (operands[0], tmp0, tmp1, operands[3]));
4513+
4514+
if (TARGET_64BIT)
4515+
{
4516+
rtx op0 = gen_reg_rtx (DImode);
4517+
emit_insn (gen_madd_split_fused_extended (op0, tmp0, tmp1, operands[3]));
4518+
op0 = gen_lowpart (SImode, op0);
4519+
SUBREG_PROMOTED_VAR_P (op0) = 1;
4520+
SUBREG_PROMOTED_SET (op0, SRP_SIGNED);
4521+
emit_move_insn (operands[0], op0);
4522+
}
4523+
else
4524+
{
4525+
emit_insn (gen_madd_split_fused (operands[0], tmp0, tmp1, operands[3]));
4526+
}
4527+
45144528
DONE;
45154529
}
45164530
}
@@ -4528,7 +4542,21 @@
45284542
rtx tmp0 = gen_reg_rtx (SImode), tmp1 = gen_reg_rtx (SImode);
45294543
emit_insn (gen_zero_extendhisi2 (tmp0, operands[1]));
45304544
emit_insn (gen_zero_extendhisi2 (tmp1, operands[2]));
4531-
emit_insn (gen_madd_split_fused (operands[0], tmp0, tmp1, operands[3]));
4545+
4546+
if (TARGET_64BIT)
4547+
{
4548+
rtx op0 = gen_reg_rtx (DImode);
4549+
emit_insn (gen_madd_split_fused_extended (op0, tmp0, tmp1, operands[3]));
4550+
op0 = gen_lowpart (SImode, op0);
4551+
SUBREG_PROMOTED_VAR_P (op0) = 1;
4552+
SUBREG_PROMOTED_SET (op0, SRP_SIGNED);
4553+
emit_move_insn (operands[0], op0);
4554+
}
4555+
else
4556+
{
4557+
emit_insn (gen_madd_split_fused (operands[0], tmp0, tmp1, operands[3]));
4558+
}
4559+
45324560
DONE;
45334561
}
45344562
)
@@ -4564,6 +4592,29 @@
45644592
[(set_attr "type" "imul_fused")]
45654593
)
45664594

4595+
(define_insn "madd_split_fused_extended"
4596+
[(set (match_operand:DI 0 "register_operand" "=&r,r")
4597+
(sign_extend:DI
4598+
(plus:SI
4599+
(mult:SI (match_operand:SI 1 "register_operand" "r,r")
4600+
(match_operand:SI 2 "register_operand" "r,r"))
4601+
(match_operand:SI 3 "register_operand" "r,?0"))))
4602+
(clobber (match_scratch:SI 4 "=&r,&r"))]
4603+
"arcv_micro_arch_supports_fusion_p ()
4604+
&& (TARGET_ZMMUL || TARGET_MUL)"
4605+
{
4606+
if (REGNO (operands[0]) == REGNO (operands[3]))
4607+
{
4608+
return "mulw\t%4,%1,%2\n\taddw\t%4,%3,%4\n\tmv\t%0,%4";
4609+
}
4610+
else
4611+
{
4612+
return "mulw\t%0,%1,%2\n\taddw\t%0,%0,%3";
4613+
}
4614+
}
4615+
[(set_attr "type" "imul_fused")]
4616+
)
4617+
45674618
(define_insn "*zero_extract_fused"
45684619
[(set (match_operand:SI 0 "register_operand" "=r")
45694620
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")

0 commit comments

Comments
 (0)