From 4f8c1957de5f1ecbb7e1327a36f57e60b285e80b Mon Sep 17 00:00:00 2001 From: Ben Shi Date: Sun, 2 Apr 2023 13:06:11 +0800 Subject: [PATCH] [LoongArch] Optimize multiplication with immediates Optimize multiplication with some specific immediates to a pair of `alsl`. Reviewed By: SixWeining, xen0n Differential Revision: https://reviews.llvm.org/D147400 --- llvm/lib/Target/LoongArch/LoongArchInstrInfo.td | 25 +++++++- llvm/test/CodeGen/LoongArch/ir-instruction/mul.ll | 78 +++++++++++------------ 2 files changed, 59 insertions(+), 44 deletions(-) diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td index 011e623..db19dd4 100644 --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -951,8 +951,17 @@ foreach Idx0 = 1...4 in { foreach Idx1 = 1...4 in { defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1)); def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)), - (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), - GPR:$r, (i32 Idx1))>; + (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), + GPR:$r, (i32 Idx1))>; + } +} +foreach Idx0 = 1...4 in { + foreach Idx1 = 1...4 in { + defvar Cb = !add(1, !shl(1, Idx0)); + defvar CImm = !add(Cb, !shl(Cb, Idx1)); + def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)), + (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), + (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), (i32 Idx1))>; } } } // Predicates = [IsLA32] @@ -969,6 +978,18 @@ foreach Idx0 = 1...4 in { GPR:$r, (i64 Idx1))>; } } +foreach Idx0 = 1...4 in { + foreach Idx1 = 1...4 in { + defvar Cb = !add(1, !shl(1, Idx0)); + defvar CImm = !add(Cb, !shl(Cb, Idx1)); + def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32), + (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), + (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>; + def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)), + (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), + (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>; + } +} } // Predicates = [IsLA64] foreach Idx = 1...7 in { diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/mul.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/mul.ll index bf9f0e9..79bea7b 100644 --- a/llvm/test/CodeGen/LoongArch/ir-instruction/mul.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/mul.ll @@ -368,15 +368,14 @@ define signext i32 @mul_i32_25(i32 %a) { define signext i32 @mul_i32_27(i32 %a) { ; LA32-LABEL: mul_i32_27: ; LA32: # %bb.0: -; LA32-NEXT: ori $a1, $zero, 27 -; LA32-NEXT: mul.w $a0, $a0, $a1 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 1 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 3 ; LA32-NEXT: ret ; ; LA64-LABEL: mul_i32_27: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 27 -; LA64-NEXT: mul.d $a0, $a0, $a1 -; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 1 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 3 ; LA64-NEXT: ret %b = mul i32 %a, 27 ret i32 %b @@ -433,15 +432,14 @@ define signext i32 @mul_i32_41(i32 %a) { define signext i32 @mul_i32_45(i32 %a) { ; LA32-LABEL: mul_i32_45: ; LA32: # %bb.0: -; LA32-NEXT: ori $a1, $zero, 45 -; LA32-NEXT: mul.w $a0, $a0, $a1 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 2 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 3 ; LA32-NEXT: ret ; ; LA64-LABEL: mul_i32_45: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 45 -; LA64-NEXT: mul.d $a0, $a0, $a1 -; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 2 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 3 ; LA64-NEXT: ret %b = mul i32 %a, 45 ret i32 %b @@ -466,15 +464,14 @@ define signext i32 @mul_i32_49(i32 %a) { define signext i32 @mul_i32_51(i32 %a) { ; LA32-LABEL: mul_i32_51: ; LA32: # %bb.0: -; LA32-NEXT: ori $a1, $zero, 51 -; LA32-NEXT: mul.w $a0, $a0, $a1 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 1 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 ; LA32-NEXT: ret ; ; LA64-LABEL: mul_i32_51: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 51 -; LA64-NEXT: mul.d $a0, $a0, $a1 -; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 1 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 ; LA64-NEXT: ret %b = mul i32 %a, 51 ret i32 %b @@ -531,15 +528,14 @@ define signext i32 @mul_i32_81(i32 %a) { define signext i32 @mul_i32_85(i32 %a) { ; LA32-LABEL: mul_i32_85: ; LA32: # %bb.0: -; LA32-NEXT: ori $a1, $zero, 85 -; LA32-NEXT: mul.w $a0, $a0, $a1 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 2 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 ; LA32-NEXT: ret ; ; LA64-LABEL: mul_i32_85: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 85 -; LA64-NEXT: mul.d $a0, $a0, $a1 -; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 2 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 ; LA64-NEXT: ret %b = mul i32 %a, 85 ret i32 %b @@ -580,15 +576,14 @@ define signext i32 @mul_i32_145(i32 %a) { define signext i32 @mul_i32_153(i32 %a) { ; LA32-LABEL: mul_i32_153: ; LA32: # %bb.0: -; LA32-NEXT: ori $a1, $zero, 153 -; LA32-NEXT: mul.w $a0, $a0, $a1 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 3 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 ; LA32-NEXT: ret ; ; LA64-LABEL: mul_i32_153: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 153 -; LA64-NEXT: mul.d $a0, $a0, $a1 -; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 3 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 ; LA64-NEXT: ret %b = mul i32 %a, 153 ret i32 %b @@ -613,15 +608,14 @@ define signext i32 @mul_i32_273(i32 %a) { define signext i32 @mul_i32_289(i32 %a) { ; LA32-LABEL: mul_i32_289: ; LA32: # %bb.0: -; LA32-NEXT: ori $a1, $zero, 289 -; LA32-NEXT: mul.w $a0, $a0, $a1 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 +; LA32-NEXT: alsl.w $a0, $a0, $a0, 4 ; LA32-NEXT: ret ; ; LA64-LABEL: mul_i32_289: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 289 -; LA64-NEXT: mul.d $a0, $a0, $a1 -; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 +; LA64-NEXT: alsl.w $a0, $a0, $a0, 4 ; LA64-NEXT: ret %b = mul i32 %a, 289 ret i32 %b @@ -734,8 +728,8 @@ define i64 @mul_i64_27(i64 %a) { ; ; LA64-LABEL: mul_i64_27: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 27 -; LA64-NEXT: mul.d $a0, $a0, $a1 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 1 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 3 ; LA64-NEXT: ret %b = mul i64 %a, 27 ret i64 %b @@ -810,8 +804,8 @@ define i64 @mul_i64_45(i64 %a) { ; ; LA64-LABEL: mul_i64_45: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 45 -; LA64-NEXT: mul.d $a0, $a0, $a1 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 2 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 3 ; LA64-NEXT: ret %b = mul i64 %a, 45 ret i64 %b @@ -848,8 +842,8 @@ define i64 @mul_i64_51(i64 %a) { ; ; LA64-LABEL: mul_i64_51: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 51 -; LA64-NEXT: mul.d $a0, $a0, $a1 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 1 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 ; LA64-NEXT: ret %b = mul i64 %a, 51 ret i64 %b @@ -924,8 +918,8 @@ define i64 @mul_i64_85(i64 %a) { ; ; LA64-LABEL: mul_i64_85: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 85 -; LA64-NEXT: mul.d $a0, $a0, $a1 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 2 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 ; LA64-NEXT: ret %b = mul i64 %a, 85 ret i64 %b @@ -981,8 +975,8 @@ define i64 @mul_i64_153(i64 %a) { ; ; LA64-LABEL: mul_i64_153: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 153 -; LA64-NEXT: mul.d $a0, $a0, $a1 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 3 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 ; LA64-NEXT: ret %b = mul i64 %a, 153 ret i64 %b @@ -1019,8 +1013,8 @@ define i64 @mul_i64_289(i64 %a) { ; ; LA64-LABEL: mul_i64_289: ; LA64: # %bb.0: -; LA64-NEXT: ori $a1, $zero, 289 -; LA64-NEXT: mul.d $a0, $a0, $a1 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 +; LA64-NEXT: alsl.d $a0, $a0, $a0, 4 ; LA64-NEXT: ret %b = mul i64 %a, 289 ret i64 %b -- 2.7.4