Skip to content

Commit 13188bc

Browse files
authored
[GlobalISel]: Simplify udiv lowering by determining known zeros (#89678)
1 parent c5dcb52 commit 13188bc

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5069,6 +5069,9 @@ MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) {
50695069
const unsigned EltBits = ScalarTy.getScalarSizeInBits();
50705070
LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
50715071
LLT ScalarShiftAmtTy = ShiftAmtTy.getScalarType();
5072+
5073+
unsigned KnownLeadingZeros =
5074+
KB ? KB->getKnownBits(LHS).countMinLeadingZeros() : 0;
50725075
auto &MIB = Builder;
50735076

50745077
bool UseNPQ = false;
@@ -5086,8 +5089,12 @@ MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) {
50865089
// at the end.
50875090
// TODO: Use undef values for divisor of 1.
50885091
if (!Divisor.isOne()) {
5092+
5093+
// UnsignedDivisionByConstantInfo doesn't work correctly if leading zeros
5094+
// in the dividend exceeds the leading zeros for the divisor.
50895095
UnsignedDivisionByConstantInfo magics =
5090-
UnsignedDivisionByConstantInfo::get(Divisor);
5096+
UnsignedDivisionByConstantInfo::get(
5097+
Divisor, std::min(KnownLeadingZeros, Divisor.countl_zero()));
50915098

50925099
Magic = std::move(magics.Magic);
50935100

llvm/test/CodeGen/AArch64/GlobalISel/combine-udiv.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,29 @@ define <8 x i16> @pr38477(<8 x i16> %a0) {
243243
%1 = udiv <8 x i16> %a0, <i16 1, i16 119, i16 73, i16 -111, i16 -3, i16 118, i16 32, i16 31>
244244
ret <8 x i16> %1
245245
}
246+
247+
define i32 @udiv_div_by_180(i32 %x)
248+
; SDAG-LABEL: udiv_div_by_180:
249+
; SDAG: // %bb.0:
250+
; SDAG-NEXT: mov w8, #5826 // =0x16c2
251+
; SDAG-NEXT: and w9, w0, #0xff
252+
; SDAG-NEXT: movk w8, #364, lsl #16
253+
; SDAG-NEXT: umull x8, w9, w8
254+
; SDAG-NEXT: lsr x0, x8, #32
255+
; SDAG-NEXT: // kill: def $w0 killed $w0 killed $x0
256+
; SDAG-NEXT: ret
257+
;
258+
; GISEL-LABEL: udiv_div_by_180:
259+
; GISEL: // %bb.0:
260+
; GISEL-NEXT: uxtb w8, w0
261+
; GISEL-NEXT: mov w9, #5826 // =0x16c2
262+
; GISEL-NEXT: movk w9, #364, lsl #16
263+
; GISEL-NEXT: umull x8, w8, w9
264+
; GISEL-NEXT: lsr x0, x8, #32
265+
; GISEL-NEXT: // kill: def $w0 killed $w0 killed $x0
266+
; GISEL-NEXT: ret
267+
{
268+
%truncate = and i32 %x, 255
269+
%udiv = udiv i32 %truncate, 180
270+
ret i32 %udiv
271+
}

0 commit comments

Comments
 (0)