Optimize mul in the zba extension with SH*ADD

This patch does the following optimization of mul with a constant.

(mul x, 11) -> (SH1ADD (SH2ADD x, x), x)
(mul x, 19) -> (SH1ADD (SH3ADD x, x), x)
(mul x, 13) -> (SH2ADD (SH1ADD x, x), x)
(mul x, 21) -> (SH2ADD (SH2ADD x, x), x)
(mul x, 37) -> (SH2ADD (SH3ADD x, x), x)
(mul x, 25) -> (SH3ADD (SH1ADD x, x), x)
(mul x, 41) -> (SH3ADD (SH2ADD x, x), x)
(mul x, 73) -> (SH3ADD (SH3ADD x, x), x)
(mul x, 27) -> (SH1ADD (SH3ADD x, x), (SH3ADD x, x))
(mul x, 45) -> (SH2ADD (SH3ADD x, x), (SH3ADD x, x))
(mul x, 81) -> (SH3ADD (SH3ADD x, x), (SH3ADD x, x))

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D107065
This commit is contained in:
Ben Shi 2021-07-29 20:39:54 +08:00 committed by Ben Shi
parent 811be79433
commit bb6fddb63c
5 changed files with 121 additions and 90 deletions

View File

@ -893,6 +893,14 @@ def mul_oneuse : PatFrag<(ops node:$A, node:$B), (mul node:$A, node:$B), [{
return N->hasOneUse();
}]>;
def mul_const_oneuse : PatFrag<(ops node:$A, node:$B),
(mul node:$A, node:$B), [{
if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
if (N1C->hasOneUse())
return true;
return false;
}]>;
/// Simple arithmetic operations
def : PatGprGpr<add, ADD>;

View File

@ -1020,6 +1020,29 @@ def : Pat<(mul GPR:$r, C5LeftShift:$i),
def : Pat<(mul GPR:$r, C9LeftShift:$i),
(SLLI (SH3ADD GPR:$r, GPR:$r),
(TrailingZerosXForm C9LeftShift:$i))>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 11)),
(SH1ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 19)),
(SH1ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 13)),
(SH2ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 21)),
(SH2ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 37)),
(SH2ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 25)),
(SH3ADD (SH1ADD GPR:$r, GPR:$r), GPR:$r)>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 41)),
(SH3ADD (SH2ADD GPR:$r, GPR:$r), GPR:$r)>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 73)),
(SH3ADD (SH3ADD GPR:$r, GPR:$r), GPR:$r)>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 27)),
(SH1ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 45)),
(SH2ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)),
(SH3ADD (SH3ADD GPR:$r, GPR:$r), (SH3ADD GPR:$r, GPR:$r))>;
} // Predicates = [HasStdExtZba]
let Predicates = [HasStdExtZba, IsRV64] in {

View File

@ -438,14 +438,14 @@ define i32 @mul11(i32 %a) {
;
; RV32IB-LABEL: mul11:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 11
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh2add a1, a0, a0
; RV32IB-NEXT: sh1add a0, a1, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul11:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 11
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh2add a1, a0, a0
; RV32IBA-NEXT: sh1add a0, a1, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 11
ret i32 %c
@ -460,14 +460,14 @@ define i32 @mul19(i32 %a) {
;
; RV32IB-LABEL: mul19:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 19
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh3add a1, a0, a0
; RV32IB-NEXT: sh1add a0, a1, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul19:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 19
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh3add a1, a0, a0
; RV32IBA-NEXT: sh1add a0, a1, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 19
ret i32 %c
@ -482,14 +482,14 @@ define i32 @mul13(i32 %a) {
;
; RV32IB-LABEL: mul13:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 13
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh1add a1, a0, a0
; RV32IB-NEXT: sh2add a0, a1, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul13:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 13
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh1add a1, a0, a0
; RV32IBA-NEXT: sh2add a0, a1, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 13
ret i32 %c
@ -504,14 +504,14 @@ define i32 @mul21(i32 %a) {
;
; RV32IB-LABEL: mul21:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 21
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh2add a1, a0, a0
; RV32IB-NEXT: sh2add a0, a1, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul21:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 21
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh2add a1, a0, a0
; RV32IBA-NEXT: sh2add a0, a1, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 21
ret i32 %c
@ -526,14 +526,14 @@ define i32 @mul37(i32 %a) {
;
; RV32IB-LABEL: mul37:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 37
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh3add a1, a0, a0
; RV32IB-NEXT: sh2add a0, a1, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul37:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 37
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh3add a1, a0, a0
; RV32IBA-NEXT: sh2add a0, a1, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 37
ret i32 %c
@ -548,14 +548,14 @@ define i32 @mul25(i32 %a) {
;
; RV32IB-LABEL: mul25:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 25
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh1add a1, a0, a0
; RV32IB-NEXT: sh3add a0, a1, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul25:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 25
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh1add a1, a0, a0
; RV32IBA-NEXT: sh3add a0, a1, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 25
ret i32 %c
@ -570,14 +570,14 @@ define i32 @mul41(i32 %a) {
;
; RV32IB-LABEL: mul41:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 41
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh2add a1, a0, a0
; RV32IB-NEXT: sh3add a0, a1, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul41:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 41
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh2add a1, a0, a0
; RV32IBA-NEXT: sh3add a0, a1, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 41
ret i32 %c
@ -592,14 +592,14 @@ define i32 @mul73(i32 %a) {
;
; RV32IB-LABEL: mul73:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 73
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh3add a1, a0, a0
; RV32IB-NEXT: sh3add a0, a1, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul73:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 73
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh3add a1, a0, a0
; RV32IBA-NEXT: sh3add a0, a1, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 73
ret i32 %c
@ -614,14 +614,14 @@ define i32 @mul27(i32 %a) {
;
; RV32IB-LABEL: mul27:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 27
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh3add a0, a0, a0
; RV32IB-NEXT: sh1add a0, a0, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul27:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 27
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh3add a0, a0, a0
; RV32IBA-NEXT: sh1add a0, a0, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 27
ret i32 %c
@ -636,14 +636,14 @@ define i32 @mul45(i32 %a) {
;
; RV32IB-LABEL: mul45:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 45
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh3add a0, a0, a0
; RV32IB-NEXT: sh2add a0, a0, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul45:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 45
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh3add a0, a0, a0
; RV32IBA-NEXT: sh2add a0, a0, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 45
ret i32 %c
@ -658,14 +658,14 @@ define i32 @mul81(i32 %a) {
;
; RV32IB-LABEL: mul81:
; RV32IB: # %bb.0:
; RV32IB-NEXT: addi a1, zero, 81
; RV32IB-NEXT: mul a0, a0, a1
; RV32IB-NEXT: sh3add a0, a0, a0
; RV32IB-NEXT: sh3add a0, a0, a0
; RV32IB-NEXT: ret
;
; RV32IBA-LABEL: mul81:
; RV32IBA: # %bb.0:
; RV32IBA-NEXT: addi a1, zero, 81
; RV32IBA-NEXT: mul a0, a0, a1
; RV32IBA-NEXT: sh3add a0, a0, a0
; RV32IBA-NEXT: sh3add a0, a0, a0
; RV32IBA-NEXT: ret
%c = mul i32 %a, 81
ret i32 %c

View File

@ -943,14 +943,14 @@ define i64 @mul11(i64 %a) {
;
; RV64IB-LABEL: mul11:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 11
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh2add a1, a0, a0
; RV64IB-NEXT: sh1add a0, a1, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul11:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 11
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh2add a1, a0, a0
; RV64IBA-NEXT: sh1add a0, a1, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 11
ret i64 %c
@ -965,14 +965,14 @@ define i64 @mul19(i64 %a) {
;
; RV64IB-LABEL: mul19:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 19
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh3add a1, a0, a0
; RV64IB-NEXT: sh1add a0, a1, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul19:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 19
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh3add a1, a0, a0
; RV64IBA-NEXT: sh1add a0, a1, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 19
ret i64 %c
@ -987,14 +987,14 @@ define i64 @mul13(i64 %a) {
;
; RV64IB-LABEL: mul13:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 13
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh1add a1, a0, a0
; RV64IB-NEXT: sh2add a0, a1, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul13:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 13
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh1add a1, a0, a0
; RV64IBA-NEXT: sh2add a0, a1, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 13
ret i64 %c
@ -1009,14 +1009,14 @@ define i64 @mul21(i64 %a) {
;
; RV64IB-LABEL: mul21:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 21
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh2add a1, a0, a0
; RV64IB-NEXT: sh2add a0, a1, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul21:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 21
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh2add a1, a0, a0
; RV64IBA-NEXT: sh2add a0, a1, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 21
ret i64 %c
@ -1031,14 +1031,14 @@ define i64 @mul37(i64 %a) {
;
; RV64IB-LABEL: mul37:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 37
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh3add a1, a0, a0
; RV64IB-NEXT: sh2add a0, a1, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul37:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 37
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh3add a1, a0, a0
; RV64IBA-NEXT: sh2add a0, a1, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 37
ret i64 %c
@ -1053,14 +1053,14 @@ define i64 @mul25(i64 %a) {
;
; RV64IB-LABEL: mul25:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 25
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh1add a1, a0, a0
; RV64IB-NEXT: sh3add a0, a1, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul25:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 25
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh1add a1, a0, a0
; RV64IBA-NEXT: sh3add a0, a1, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 25
ret i64 %c
@ -1075,14 +1075,14 @@ define i64 @mul41(i64 %a) {
;
; RV64IB-LABEL: mul41:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 41
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh2add a1, a0, a0
; RV64IB-NEXT: sh3add a0, a1, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul41:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 41
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh2add a1, a0, a0
; RV64IBA-NEXT: sh3add a0, a1, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 41
ret i64 %c
@ -1097,14 +1097,14 @@ define i64 @mul73(i64 %a) {
;
; RV64IB-LABEL: mul73:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 73
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh3add a1, a0, a0
; RV64IB-NEXT: sh3add a0, a1, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul73:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 73
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh3add a1, a0, a0
; RV64IBA-NEXT: sh3add a0, a1, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 73
ret i64 %c
@ -1119,14 +1119,14 @@ define i64 @mul27(i64 %a) {
;
; RV64IB-LABEL: mul27:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 27
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh3add a0, a0, a0
; RV64IB-NEXT: sh1add a0, a0, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul27:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 27
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh3add a0, a0, a0
; RV64IBA-NEXT: sh1add a0, a0, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 27
ret i64 %c
@ -1141,14 +1141,14 @@ define i64 @mul45(i64 %a) {
;
; RV64IB-LABEL: mul45:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 45
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh3add a0, a0, a0
; RV64IB-NEXT: sh2add a0, a0, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul45:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 45
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh3add a0, a0, a0
; RV64IBA-NEXT: sh2add a0, a0, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 45
ret i64 %c
@ -1163,14 +1163,14 @@ define i64 @mul81(i64 %a) {
;
; RV64IB-LABEL: mul81:
; RV64IB: # %bb.0:
; RV64IB-NEXT: addi a1, zero, 81
; RV64IB-NEXT: mul a0, a0, a1
; RV64IB-NEXT: sh3add a0, a0, a0
; RV64IB-NEXT: sh3add a0, a0, a0
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: mul81:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: addi a1, zero, 81
; RV64IBA-NEXT: mul a0, a0, a1
; RV64IBA-NEXT: sh3add a0, a0, a0
; RV64IBA-NEXT: sh3add a0, a0, a0
; RV64IBA-NEXT: ret
%c = mul i64 %a, 81
ret i64 %c

View File

@ -1149,8 +1149,8 @@ define zeroext i1 @umulo2.i32(i32 %v1, i32* %res) {
; RV64ZBA-LABEL: umulo2.i32:
; RV64ZBA: # %bb.0: # %entry
; RV64ZBA-NEXT: zext.w a0, a0
; RV64ZBA-NEXT: addi a2, zero, 13
; RV64ZBA-NEXT: mul a2, a0, a2
; RV64ZBA-NEXT: sh1add a2, a0, a0
; RV64ZBA-NEXT: sh2add a2, a2, a0
; RV64ZBA-NEXT: srli a0, a2, 32
; RV64ZBA-NEXT: snez a0, a0
; RV64ZBA-NEXT: sw a2, 0(a1)