Skip to content

Commit

Permalink
[RISCV] Avoid matching 3/5/9 * 2^N as 2^N + 2/4/8 (e.g. 24) (#88937)
Browse files Browse the repository at this point in the history
The former is better as a zero extend can be folded into the sll,
whereas the later currently produces a seperate zext.w due to bad
interactions with other combines.
  • Loading branch information
preames authored Apr 16, 2024
1 parent 7505452 commit 184ba03
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
6 changes: 6 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13416,6 +13416,12 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
return SDValue();
uint64_t MulAmt = CNode->getZExtValue();

// 3/5/9 * 2^N -> shXadd (sll X, C), (sll X, C)
// Matched in tablegen, avoid perturbing patterns.
for (uint64_t Divisor : {3, 5, 9})
if (MulAmt % Divisor == 0 && isPowerOf2_64(MulAmt / Divisor))
return SDValue();

// If this is a power 2 + 2/4/8, we can use a shift followed by a single
// shXadd. First check if this a sum of two power of 2s because that's
// easy. Then count how many zeros are up to the first bit.
Expand Down
9 changes: 4 additions & 5 deletions llvm/test/CodeGen/RISCV/addimm-mulimm.ll
Original file line number Diff line number Diff line change
Expand Up @@ -551,9 +551,8 @@ define i64 @add_mul_combine_infinite_loop(i64 %x) {
; RV32IMB-NEXT: sh3add a1, a1, a2
; RV32IMB-NEXT: sh1add a0, a0, a0
; RV32IMB-NEXT: slli a2, a0, 3
; RV32IMB-NEXT: li a3, 1
; RV32IMB-NEXT: slli a3, a3, 11
; RV32IMB-NEXT: sh3add a0, a0, a3
; RV32IMB-NEXT: addi a0, a2, 2047
; RV32IMB-NEXT: addi a0, a0, 1
; RV32IMB-NEXT: sltu a2, a0, a2
; RV32IMB-NEXT: add a1, a1, a2
; RV32IMB-NEXT: ret
Expand All @@ -562,8 +561,8 @@ define i64 @add_mul_combine_infinite_loop(i64 %x) {
; RV64IMB: # %bb.0:
; RV64IMB-NEXT: addi a0, a0, 86
; RV64IMB-NEXT: sh1add a0, a0, a0
; RV64IMB-NEXT: slli a0, a0, 3
; RV64IMB-NEXT: addi a0, a0, -16
; RV64IMB-NEXT: li a1, -16
; RV64IMB-NEXT: sh3add a0, a0, a1
; RV64IMB-NEXT: ret
%tmp0 = mul i64 %x, 24
%tmp1 = add i64 %tmp0, 2048
Expand Down
22 changes: 22 additions & 0 deletions llvm/test/CodeGen/RISCV/rv64zba.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2490,3 +2490,25 @@ define ptr @test_gep_gep_dont_crash(ptr %p, i64 %a1, i64 %a2) {
%gep2 = getelementptr i64, ptr %gep1, i64 %a1
ret ptr %gep2
}

define i64 @regression(i32 signext %x, i32 signext %y) {
; RV64I-LABEL: regression:
; RV64I: # %bb.0:
; RV64I-NEXT: subw a0, a0, a1
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: li a1, 3
; RV64I-NEXT: slli a1, a1, 35
; RV64I-NEXT: mulhu a0, a0, a1
; RV64I-NEXT: ret
;
; RV64ZBA-LABEL: regression:
; RV64ZBA: # %bb.0:
; RV64ZBA-NEXT: subw a0, a0, a1
; RV64ZBA-NEXT: slli.uw a0, a0, 3
; RV64ZBA-NEXT: sh1add a0, a0, a0
; RV64ZBA-NEXT: ret
%sub = sub i32 %x, %y
%ext = zext i32 %sub to i64
%res = mul nuw nsw i64 %ext, 24
ret i64 %res
}

0 comments on commit 184ba03

Please sign in to comment.