Skip to content

Commit 1bafe77

Browse files
authored
[AArch64] Improve the codegen for sdiv 2 (#98324)
Same as X86, , if X's size is BitWidth, then X sdiv 2 can be expressived as ``` X += X >> (BitWidth - 1) X = X >> 1 ``` Fix #97884
1 parent 941f794 commit 1bafe77

File tree

3 files changed

+10
-8
lines changed

3 files changed

+10
-8
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17740,6 +17740,12 @@ AArch64TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
1774017740
!(Divisor.isPowerOf2() || Divisor.isNegatedPowerOf2()))
1774117741
return SDValue();
1774217742

17743+
// If the divisor is 2 or -2, the default expansion is better. It will add
17744+
// (N->getValueType(0) >> (BitWidth - 1)) to it before shifting right.
17745+
if (Divisor == 2 ||
17746+
Divisor == APInt(Divisor.getBitWidth(), -2, /*isSigned*/ true))
17747+
return SDValue();
17748+
1774317749
return TargetLowering::buildSDIVPow2WithCMov(N, Divisor, DAG, Created);
1774417750
}
1774517751

llvm/test/CodeGen/AArch64/aarch64-bit-gen.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,8 @@ define <4 x i32> @test_bit_sink_operand(<4 x i32> %src, <4 x i32> %dst, <4 x i32
202202
; CHECK-SD: // %bb.0: // %entry
203203
; CHECK-SD-NEXT: sub sp, sp, #32
204204
; CHECK-SD-NEXT: .cfi_def_cfa_offset 32
205-
; CHECK-SD-NEXT: cmp w0, #0
205+
; CHECK-SD-NEXT: add w8, w0, w0, lsr #31
206206
; CHECK-SD-NEXT: mov w9, wzr
207-
; CHECK-SD-NEXT: cinc w8, w0, lt
208207
; CHECK-SD-NEXT: asr w8, w8, #1
209208
; CHECK-SD-NEXT: .LBB11_1: // %do.body
210209
; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1

llvm/test/CodeGen/AArch64/sdivpow2.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ define i64 @test7(i64 %x) {
9090
define i64 @test8(i64 %x) {
9191
; ISEL-LABEL: test8:
9292
; ISEL: // %bb.0:
93-
; ISEL-NEXT: cmp x0, #0
94-
; ISEL-NEXT: cinc x8, x0, lt
93+
; ISEL-NEXT: add x8, x0, x0, lsr #63
9594
; ISEL-NEXT: asr x0, x8, #1
9695
; ISEL-NEXT: ret
9796
;
@@ -110,10 +109,8 @@ define i32 @sdiv_int(i32 %begin, i32 %first) #0 {
110109
; ISEL-LABEL: sdiv_int:
111110
; ISEL: // %bb.0:
112111
; ISEL-NEXT: sub w8, w0, w1
113-
; ISEL-NEXT: add w9, w8, #1
114-
; ISEL-NEXT: add w10, w8, #2
115-
; ISEL-NEXT: cmp w9, #0
116-
; ISEL-NEXT: csinc w8, w10, w8, lt
112+
; ISEL-NEXT: add w8, w8, #1
113+
; ISEL-NEXT: add w8, w8, w8, lsr #31
117114
; ISEL-NEXT: sub w0, w0, w8, asr #1
118115
; ISEL-NEXT: ret
119116
;

0 commit comments

Comments
 (0)