Skip to content

Commit cbbcb10

Browse files
committed
[RISCV] Refine the (mul (zext.w X), C) -> mulhu isel heuristic.
We try to shift both X and C left by 32 to replace the zext.w with a SLLI and use mulhu. If C is already a simm32, this likely makes a constant that is more expensive to materialize.
1 parent 6cfebf3 commit cbbcb10

File tree

2 files changed

+37
-20
lines changed

2 files changed

+37
-20
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,17 +1065,21 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
10651065
if (!isMask_64(C2))
10661066
break;
10671067

1068-
// If this can be an ANDI, ZEXT.H or ZEXT.W, don't do this if the ANDI/ZEXT
1069-
// has multiple users or the constant is a simm12. This prevents inserting
1070-
// a shift and still have uses of the AND/ZEXT. Shifting a simm12 will
1071-
// likely make it more costly to materialize. Otherwise, using a SLLI
1072-
// might allow it to be compressed.
1068+
// If this can be an ANDI or ZEXT.H, don't do this if the ANDI/ZEXT has
1069+
// multiple users or the constant is a simm12. This prevents inserting a
1070+
// shift and still have uses of the AND/ZEXT. Shifting a simm12 will likely
1071+
// make it more costly to materialize. Otherwise, using a SLLI might allow
1072+
// it to be compressed.
10731073
bool IsANDIOrZExt =
10741074
isInt<12>(C2) ||
1075-
(C2 == UINT64_C(0xFFFF) && Subtarget->hasStdExtZbb()) ||
1076-
(C2 == UINT64_C(0xFFFFFFFF) && Subtarget->hasStdExtZba());
1075+
(C2 == UINT64_C(0xFFFF) && Subtarget->hasStdExtZbb());
10771076
if (IsANDIOrZExt && (isInt<12>(N1C->getSExtValue()) || !N0.hasOneUse()))
10781077
break;
1078+
// If this can be a ZEXT.w, don't do this if the ZEXT has multiple users or
1079+
// the constant is a simm32.
1080+
bool IsZExtW = C2 == UINT64_C(0xFFFFFFFF) && Subtarget->hasStdExtZba();
1081+
if (IsZExtW && (isInt<32>(N1C->getSExtValue()) || !N0.hasOneUse()))
1082+
break;
10791083

10801084
// We need to shift left the AND input and C1 by a total of XLen bits.
10811085

llvm/test/CodeGen/RISCV/div-by-constant.ll

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,32 @@ define i32 @udiv_constant_add(i32 %a) nounwind {
4646
; RV32-NEXT: srli a0, a0, 2
4747
; RV32-NEXT: ret
4848
;
49-
; RV64-LABEL: udiv_constant_add:
50-
; RV64: # %bb.0:
51-
; RV64-NEXT: slli a1, a0, 32
52-
; RV64-NEXT: lui a2, 149797
53-
; RV64-NEXT: addiw a2, a2, -1755
54-
; RV64-NEXT: slli a2, a2, 32
55-
; RV64-NEXT: mulhu a1, a1, a2
56-
; RV64-NEXT: srli a1, a1, 32
57-
; RV64-NEXT: subw a0, a0, a1
58-
; RV64-NEXT: srliw a0, a0, 1
59-
; RV64-NEXT: add a0, a0, a1
60-
; RV64-NEXT: srli a0, a0, 2
61-
; RV64-NEXT: ret
49+
; RV64IM-LABEL: udiv_constant_add:
50+
; RV64IM: # %bb.0:
51+
; RV64IM-NEXT: slli a1, a0, 32
52+
; RV64IM-NEXT: lui a2, 149797
53+
; RV64IM-NEXT: addiw a2, a2, -1755
54+
; RV64IM-NEXT: slli a2, a2, 32
55+
; RV64IM-NEXT: mulhu a1, a1, a2
56+
; RV64IM-NEXT: srli a1, a1, 32
57+
; RV64IM-NEXT: subw a0, a0, a1
58+
; RV64IM-NEXT: srliw a0, a0, 1
59+
; RV64IM-NEXT: add a0, a0, a1
60+
; RV64IM-NEXT: srli a0, a0, 2
61+
; RV64IM-NEXT: ret
62+
;
63+
; RV64IMZB-LABEL: udiv_constant_add:
64+
; RV64IMZB: # %bb.0:
65+
; RV64IMZB-NEXT: zext.w a1, a0
66+
; RV64IMZB-NEXT: lui a2, 149797
67+
; RV64IMZB-NEXT: addiw a2, a2, -1755
68+
; RV64IMZB-NEXT: mul a1, a1, a2
69+
; RV64IMZB-NEXT: srli a1, a1, 32
70+
; RV64IMZB-NEXT: subw a0, a0, a1
71+
; RV64IMZB-NEXT: srliw a0, a0, 1
72+
; RV64IMZB-NEXT: add a0, a0, a1
73+
; RV64IMZB-NEXT: srli a0, a0, 2
74+
; RV64IMZB-NEXT: ret
6275
%1 = udiv i32 %a, 7
6376
ret i32 %1
6477
}

0 commit comments

Comments
 (0)