Skip to content

Commit 184ba03

Browse files
authored
[RISCV] Avoid matching 3/5/9 * 2^N as 2^N + 2/4/8 (e.g. 24) (#88937)
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.
1 parent 7505452 commit 184ba03

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13416,6 +13416,12 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
1341613416
return SDValue();
1341713417
uint64_t MulAmt = CNode->getZExtValue();
1341813418

13419+
// 3/5/9 * 2^N -> shXadd (sll X, C), (sll X, C)
13420+
// Matched in tablegen, avoid perturbing patterns.
13421+
for (uint64_t Divisor : {3, 5, 9})
13422+
if (MulAmt % Divisor == 0 && isPowerOf2_64(MulAmt / Divisor))
13423+
return SDValue();
13424+
1341913425
// If this is a power 2 + 2/4/8, we can use a shift followed by a single
1342013426
// shXadd. First check if this a sum of two power of 2s because that's
1342113427
// easy. Then count how many zeros are up to the first bit.

llvm/test/CodeGen/RISCV/addimm-mulimm.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -551,9 +551,8 @@ define i64 @add_mul_combine_infinite_loop(i64 %x) {
551551
; RV32IMB-NEXT: sh3add a1, a1, a2
552552
; RV32IMB-NEXT: sh1add a0, a0, a0
553553
; RV32IMB-NEXT: slli a2, a0, 3
554-
; RV32IMB-NEXT: li a3, 1
555-
; RV32IMB-NEXT: slli a3, a3, 11
556-
; RV32IMB-NEXT: sh3add a0, a0, a3
554+
; RV32IMB-NEXT: addi a0, a2, 2047
555+
; RV32IMB-NEXT: addi a0, a0, 1
557556
; RV32IMB-NEXT: sltu a2, a0, a2
558557
; RV32IMB-NEXT: add a1, a1, a2
559558
; RV32IMB-NEXT: ret
@@ -562,8 +561,8 @@ define i64 @add_mul_combine_infinite_loop(i64 %x) {
562561
; RV64IMB: # %bb.0:
563562
; RV64IMB-NEXT: addi a0, a0, 86
564563
; RV64IMB-NEXT: sh1add a0, a0, a0
565-
; RV64IMB-NEXT: slli a0, a0, 3
566-
; RV64IMB-NEXT: addi a0, a0, -16
564+
; RV64IMB-NEXT: li a1, -16
565+
; RV64IMB-NEXT: sh3add a0, a0, a1
567566
; RV64IMB-NEXT: ret
568567
%tmp0 = mul i64 %x, 24
569568
%tmp1 = add i64 %tmp0, 2048

llvm/test/CodeGen/RISCV/rv64zba.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,3 +2490,25 @@ define ptr @test_gep_gep_dont_crash(ptr %p, i64 %a1, i64 %a2) {
24902490
%gep2 = getelementptr i64, ptr %gep1, i64 %a1
24912491
ret ptr %gep2
24922492
}
2493+
2494+
define i64 @regression(i32 signext %x, i32 signext %y) {
2495+
; RV64I-LABEL: regression:
2496+
; RV64I: # %bb.0:
2497+
; RV64I-NEXT: subw a0, a0, a1
2498+
; RV64I-NEXT: slli a0, a0, 32
2499+
; RV64I-NEXT: li a1, 3
2500+
; RV64I-NEXT: slli a1, a1, 35
2501+
; RV64I-NEXT: mulhu a0, a0, a1
2502+
; RV64I-NEXT: ret
2503+
;
2504+
; RV64ZBA-LABEL: regression:
2505+
; RV64ZBA: # %bb.0:
2506+
; RV64ZBA-NEXT: subw a0, a0, a1
2507+
; RV64ZBA-NEXT: slli.uw a0, a0, 3
2508+
; RV64ZBA-NEXT: sh1add a0, a0, a0
2509+
; RV64ZBA-NEXT: ret
2510+
%sub = sub i32 %x, %y
2511+
%ext = zext i32 %sub to i64
2512+
%res = mul nuw nsw i64 %ext, 24
2513+
ret i64 %res
2514+
}

0 commit comments

Comments
 (0)