[RISCV][P-ext] Add isel patterns for mhacc/mhaccu/mhaccsu. (#190670)

This commit is contained in:
Craig Topper 2026-04-06 15:37:51 -07:00 committed by GitHub
parent ce61fe5c48
commit 8e1ea8af38
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 137 additions and 0 deletions

View File

@ -1959,6 +1959,13 @@ let Predicates = [HasStdExtP, IsRV32] in {
def : Pat<(i32 (add GPR:$rd, (mul_oneuse sexti16:$rs1, zexti16:$rs2))),
(MACCSU_H00 GPR:$rd, sexti16:$rs1, zexti16:$rs2)>;
def : Pat<(i32 (add GPR:$rd, (binop_oneuse<mulhs> GPR:$rs1, GPR:$rs2))),
(MHACC GPR:$rd, GPR:$rs1, GPR:$rs2)>;
def : Pat<(i32 (add GPR:$rd, (binop_oneuse<mulhu> GPR:$rs1, GPR:$rs2))),
(MHACCU GPR:$rd, GPR:$rs1, GPR:$rs2)>;
def : Pat<(i32 (add GPR:$rd, (binop_oneuse<riscv_mulhsu> GPR:$rs1, GPR:$rs2))),
(MHACCSU GPR:$rd, GPR:$rs1, GPR:$rs2)>;
// Narrowing shift patterns (NSRL/NSRA)
// Immediate shift amount patterns
def : Pat<(riscv_nsrl GPR:$lo, GPR:$hi, uimm6:$shamt),

View File

@ -1189,6 +1189,136 @@ define i32 @macc_h00_multiple_uses(i16 %a, i16 %b, i32 %c, ptr %out) nounwind {
ret i32 %result
}
define i32 @mhacc(i32 %rd, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: mhacc:
; CHECK: # %bb.0:
; CHECK-NEXT: mhacc a0, a1, a2
; CHECK-NEXT: ret
%aext = sext i32 %a to i64
%bext = sext i32 %b to i64
%mul = mul i64 %aext, %bext
%shift = lshr i64 %mul, 32
%trunc = trunc i64 %shift to i32
%result = add i32 %rd, %trunc
ret i32 %result
}
define i32 @mhacc_commute(i32 %rd, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: mhacc_commute:
; CHECK: # %bb.0:
; CHECK-NEXT: mhacc a0, a1, a2
; CHECK-NEXT: ret
%aext = sext i32 %a to i64
%bext = sext i32 %b to i64
%mul = mul i64 %aext, %bext
%shift = lshr i64 %mul, 32
%trunc = trunc i64 %shift to i32
%result = add i32 %trunc, %rd
ret i32 %result
}
define i32 @mhaccu(i32 %rd, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: mhaccu:
; CHECK: # %bb.0:
; CHECK-NEXT: mhaccu a0, a1, a2
; CHECK-NEXT: ret
%aext = zext i32 %a to i64
%bext = zext i32 %b to i64
%mul = mul i64 %aext, %bext
%shift = lshr i64 %mul, 32
%trunc = trunc i64 %shift to i32
%result = add i32 %rd, %trunc
ret i32 %result
}
define i32 @mhaccu_commute(i32 %rd, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: mhaccu_commute:
; CHECK: # %bb.0:
; CHECK-NEXT: mhaccu a0, a1, a2
; CHECK-NEXT: ret
%aext = zext i32 %a to i64
%bext = zext i32 %b to i64
%mul = mul i64 %aext, %bext
%shift = lshr i64 %mul, 32
%trunc = trunc i64 %shift to i32
%result = add i32 %trunc, %rd
ret i32 %result
}
define i32 @mhaccsu(i32 %rd, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: mhaccsu:
; CHECK: # %bb.0:
; CHECK-NEXT: mhaccsu a0, a1, a2
; CHECK-NEXT: ret
%aext = sext i32 %a to i64
%bext = zext i32 %b to i64
%mul = mul i64 %aext, %bext
%shift = lshr i64 %mul, 32
%trunc = trunc i64 %shift to i32
%result = add i32 %rd, %trunc
ret i32 %result
}
define i32 @mhaccsu_commute(i32 %rd, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: mhaccsu_commute:
; CHECK: # %bb.0:
; CHECK-NEXT: mhaccsu a0, a1, a2
; CHECK-NEXT: ret
%aext = sext i32 %a to i64
%bext = zext i32 %b to i64
%mul = mul i64 %aext, %bext
%shift = lshr i64 %mul, 32
%trunc = trunc i64 %shift to i32
%result = add i32 %trunc, %rd
ret i32 %result
}
define i32 @mhaccsu_swap_operands(i32 %rd, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: mhaccsu_swap_operands:
; CHECK: # %bb.0:
; CHECK-NEXT: mhaccsu a0, a2, a1
; CHECK-NEXT: ret
%aext = zext i32 %a to i64
%bext = sext i32 %b to i64
%mul = mul i64 %aext, %bext
%shift = lshr i64 %mul, 32
%trunc = trunc i64 %shift to i32
%result = add i32 %rd, %trunc
ret i32 %result
}
define i32 @mhaccsu_swap_operands_commute(i32 %rd, i32 %a, i32 %b) nounwind {
; CHECK-LABEL: mhaccsu_swap_operands_commute:
; CHECK: # %bb.0:
; CHECK-NEXT: mhaccsu a0, a2, a1
; CHECK-NEXT: ret
%aext = zext i32 %a to i64
%bext = sext i32 %b to i64
%mul = mul i64 %aext, %bext
%shift = lshr i64 %mul, 32
%trunc = trunc i64 %shift to i32
%result = add i32 %trunc, %rd
ret i32 %result
}
; Negative test: multiply result has multiple uses, should not combine to mhacc
define i32 @mhacc_multiple_uses(i32 %a, i32 %b, i32 %c, ptr %out) nounwind {
; CHECK-LABEL: mhacc_multiple_uses:
; CHECK: # %bb.0:
; CHECK-NEXT: mulh a1, a0, a1
; CHECK-NEXT: add a0, a2, a1
; CHECK-NEXT: sw a1, 0(a3)
; CHECK-NEXT: ret
%aext = sext i32 %a to i64
%bext = sext i32 %b to i64
%mul = mul i64 %aext, %bext
%shift = lshr i64 %mul, 32
%trunc = trunc i64 %shift to i32
%result = add i32 %c, %trunc
store i32 %trunc, ptr %out
ret i32 %result
}
; Negative test: multiply result has multiple uses, should not combine
define void @wmaccu_multiple_uses(i32 %a, i32 %b, i64 %c, ptr %out1, ptr %out2) nounwind {
; CHECK-LABEL: wmaccu_multiple_uses: