Skip to content

Commit 8cd7eef

Browse files
artemiy-volkovMichielDerhaeg
authored andcommitted
arcv: create a 32-bit integer multiply-add instruction pattern
The RHX core executes integer multiply-add sequences of the form: mul r1,r2,r3 add r1,r1,r4 in 1 cycle due to macro-op fusion. This patch adds a define_insn_and_split to recognize the above sequence and preserve it as a single insn up until the post-reload split pass. Since, due to a microarchitectural restriction, the output operand of both instructions must be the same register, the insn_and_split pattern has two alternatives corresponding to the following cases: (0) r1 is different from r4, in which case the insn can be split to the sequence above; (1) r1 and r4 are the same, in which case a temporary register has to be used and there is no fusion. Alternative (1) is discouraged so that reload maximizes the number of instances where MAC fusion can be applied. Since RHX is a rv32im core, the pattern requires that the target is 32-bit and supports multiplication. In addition, the {u,}maddhisi3 expand is implemented for RHX to convert the ( 16-bit x 16-bit + 32_bit ) WIDEN_MULT_PLUS_EXPR GIMPLE operator to the aforementioned madd_split instruction directly. Lastly, a very basic testcase is introduced to make sure that the new patterns are sufficient to produce MAC-fusion-aware code. No new dejagnu failures with RUNTESTFLAGS="CFLAGS_FOR_TARGET=-mtune=rhx dg.exp". Signed-off-by: Artemiy Volkov <artemiy@synopsys.com>
1 parent 2d48e9f commit 8cd7eef

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

gcc/config/riscv/riscv.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4526,7 +4526,35 @@
45264526
(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
45274527
(sign_extend:SI (match_operand:HI 2 "register_operand")))
45284528
(match_operand:SI 3 "register_operand")))]
4529-
"TARGET_XTHEADMAC"
4529+
"TARGET_XTHEADMAC || (riscv_is_micro_arch (arcv_rhx100)
4530+
&& !TARGET_64BIT && (TARGET_ZMMUL || TARGET_MUL))"
4531+
{
4532+
if (riscv_is_micro_arch (arcv_rhx100))
4533+
{
4534+
rtx tmp0 = gen_reg_rtx (SImode), tmp1 = gen_reg_rtx (SImode);
4535+
emit_insn (gen_extendhisi2 (tmp0, operands[1]));
4536+
emit_insn (gen_extendhisi2 (tmp1, operands[2]));
4537+
emit_insn (gen_madd_split_fused (operands[0], tmp0, tmp1, operands[3]));
4538+
DONE;
4539+
}
4540+
}
4541+
)
4542+
4543+
(define_expand "umaddhisi4"
4544+
[(set (match_operand:SI 0 "register_operand")
4545+
(plus:SI
4546+
(mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand"))
4547+
(zero_extend:SI (match_operand:HI 2 "register_operand")))
4548+
(match_operand:SI 3 "register_operand")))]
4549+
"riscv_is_micro_arch (arcv_rhx100)
4550+
&& !TARGET_64BIT && (TARGET_ZMMUL || TARGET_MUL)"
4551+
{
4552+
rtx tmp0 = gen_reg_rtx (SImode), tmp1 = gen_reg_rtx (SImode);
4553+
emit_insn (gen_zero_extendhisi2 (tmp0, operands[1]));
4554+
emit_insn (gen_zero_extendhisi2 (tmp1, operands[2]));
4555+
emit_insn (gen_madd_split (operands[0], tmp0, tmp1, operands[3]));
4556+
DONE;
4557+
}
45304558
)
45314559

45324560
(define_expand "msubhisi4"
@@ -4538,6 +4566,33 @@
45384566
"TARGET_XTHEADMAC"
45394567
)
45404568

4569+
(define_insn_and_split "madd_split"
4570+
[(set (match_operand:SI 0 "register_operand" "=&r,r")
4571+
(plus:SI
4572+
(mult:SI (match_operand:SI 1 "register_operand" "r,r")
4573+
(match_operand:SI 2 "register_operand" "r,r"))
4574+
(match_operand:SI 3 "register_operand" "r,?0")))
4575+
(clobber (match_scratch:SI 4 "=&r,&r"))]
4576+
"riscv_is_micro_arch (rhx) && !TARGET_64BIT && (TARGET_ZMMUL || TARGET_MUL)"
4577+
"#"
4578+
"&& reload_completed"
4579+
[(const_int 0)]
4580+
"{
4581+
if (REGNO (operands[0]) == REGNO (operands[3]))
4582+
{
4583+
emit_insn (gen_mulsi3 (operands[4], operands[1], operands[2]));
4584+
emit_insn (gen_addsi3 (operands[0], operands[3], operands[4]));
4585+
}
4586+
else
4587+
{
4588+
emit_insn (gen_mulsi3 (operands[0], operands[1], operands[2]));
4589+
emit_insn (gen_addsi3 (operands[0], operands[0], operands[3]));
4590+
}
4591+
DONE;
4592+
}"
4593+
[(set_attr "type" "imul")]
4594+
)
4595+
45414596
;; String compare with length insn.
45424597
;; Argument 0 is the target (result)
45434598
;; Argument 1 is the source1
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* { dg-do compile } */
2+
/* { dg-require-effective-target rv32 } */
3+
/* { dg-skip-if "" { *-*-* } { "-g" "-flto" "-O0" } } */
4+
/* { dg-options "-mtune=arc-v-rhx-100-series -march=rv32im -mabi=ilp32" } */
5+
6+
int
7+
f (int x, int y, int z, int v, int w)
8+
{
9+
return x + y * z + v * w;
10+
}
11+
12+
/* { dg-final { scan-assembler {\smul\s([ast][0-9]+),a1,a2\n\sadd\s\1,\1,a0\n\smul\sa0,a3,a4\n\sadd\sa0,a0,\1\n} } } */

0 commit comments

Comments
 (0)