Skip to content

Commit 8c6726f

Browse files
s-barannikovmarkrvmurray
authored andcommitted
[SDag][ARM][RISCV] Allow lowering CTPOP into a libcall (#101786)
This is a reland of #99752 with the bug fixed (see test diff in the third commit in this PR). All `popcount` libcalls return `int`, but `ISD::CTPOP` returns the type of the argument, which can be wider than `int`. The fix is to make DAG legalizer pass the correct return type to `makeLibCall` and sign-extend the result afterwards. Original commit message: The main change is adding CTPOP to `RuntimeLibcalls.def` to allow targets to use LibCall action for CTPOP. DAG legalizers are changed accordingly. Pull Request: llvm/llvm-project#101786
1 parent 12e4da4 commit 8c6726f

14 files changed

+449
-1656
lines changed

llvm/include/llvm/IR/RuntimeLibcalls.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ HANDLE_LIBCALL(CTLZ_I16, "__clzhi2")
136136
HANDLE_LIBCALL(CTLZ_I32, "__clzsi2")
137137
HANDLE_LIBCALL(CTLZ_I64, "__clzdi2")
138138
HANDLE_LIBCALL(CTLZ_I128, "__clzti2")
139+
HANDLE_LIBCALL(CTPOP_I32, "__popcountsi2")
140+
HANDLE_LIBCALL(CTPOP_I64, "__popcountdi2")
141+
HANDLE_LIBCALL(CTPOP_I128, "__popcountti2")
139142
HANDLE_LIBCALL(BSWAP_I8, "__bswapqi2")
140143
HANDLE_LIBCALL(BSWAP_I16, "__bswaphi2")
141144
HANDLE_LIBCALL(BSWAP_I32, "__bswapsi2")

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,10 +1221,8 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
12211221
setOperationAction(ISD::ROTR, VT, Expand);
12221222
}
12231223
setOperationAction(ISD::CTTZ, MVT::i32, Custom);
1224-
// TODO: These two should be set to LibCall, but this currently breaks
1225-
// the Linux kernel build. See #101786.
1226-
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
1227-
setOperationAction(ISD::CTPOP, MVT::i64, Expand);
1224+
setOperationAction(ISD::CTPOP, MVT::i32, LibCall);
1225+
setOperationAction(ISD::CTPOP, MVT::i64, LibCall);
12281226
if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only()) {
12291227
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
12301228
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, LibCall);

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
396396
setOperationAction({ISD::CTTZ, ISD::CTTZ_ZERO_UNDEF}, MVT::i32, Custom);
397397
} else {
398398
setOperationAction(ISD::CTTZ, XLenVT, Expand);
399-
// TODO: These should be set to LibCall, but this currently breaks
400-
// the Linux kernel build. See #101786. Lacks i128 tests, too.
401399
if (Subtarget.is64Bit())
402-
setOperationAction(ISD::CTPOP, MVT::i128, Expand);
400+
setOperationAction(ISD::CTPOP, MVT::i128, LibCall);
403401
else
404-
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
405-
setOperationAction(ISD::CTPOP, MVT::i64, Expand);
402+
setOperationAction(ISD::CTPOP, MVT::i32, LibCall);
403+
setOperationAction(ISD::CTPOP, MVT::i64, LibCall);
406404
}
407405

408406
if (Subtarget.hasStdExtZbb() || Subtarget.hasVendorXTHeadBb() ||

llvm/test/CodeGen/ARM/popcnt.ll

Lines changed: 6 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -324,74 +324,20 @@ define i32 @ctpop16(i16 %x) nounwind readnone {
324324
define i32 @ctpop32(i32 %x) nounwind readnone {
325325
; CHECK-LABEL: ctpop32:
326326
; CHECK: @ %bb.0:
327-
; CHECK-NEXT: ldr r1, .LCPI22_0
328-
; CHECK-NEXT: ldr r2, .LCPI22_3
329-
; CHECK-NEXT: and r1, r1, r0, lsr #1
330-
; CHECK-NEXT: ldr r12, .LCPI22_1
331-
; CHECK-NEXT: sub r0, r0, r1
332-
; CHECK-NEXT: ldr r3, .LCPI22_2
333-
; CHECK-NEXT: and r1, r0, r2
334-
; CHECK-NEXT: and r0, r2, r0, lsr #2
335-
; CHECK-NEXT: add r0, r1, r0
336-
; CHECK-NEXT: add r0, r0, r0, lsr #4
337-
; CHECK-NEXT: and r0, r0, r12
338-
; CHECK-NEXT: mul r1, r0, r3
339-
; CHECK-NEXT: lsr r0, r1, #24
340-
; CHECK-NEXT: mov pc, lr
341-
; CHECK-NEXT: .p2align 2
342-
; CHECK-NEXT: @ %bb.1:
343-
; CHECK-NEXT: .LCPI22_0:
344-
; CHECK-NEXT: .long 1431655765 @ 0x55555555
345-
; CHECK-NEXT: .LCPI22_1:
346-
; CHECK-NEXT: .long 252645135 @ 0xf0f0f0f
347-
; CHECK-NEXT: .LCPI22_2:
348-
; CHECK-NEXT: .long 16843009 @ 0x1010101
349-
; CHECK-NEXT: .LCPI22_3:
350-
; CHECK-NEXT: .long 858993459 @ 0x33333333
327+
; CHECK-NEXT: b __popcountsi2
351328
%count = tail call i32 @llvm.ctpop.i32(i32 %x)
352329
ret i32 %count
353330
}
354331

355332
define i64 @ctpop64(i64 %x) nounwind readnone {
356333
; CHECK-LABEL: ctpop64:
357334
; CHECK: @ %bb.0:
358-
; CHECK-NEXT: .save {r4, lr}
359-
; CHECK-NEXT: push {r4, lr}
360-
; CHECK-NEXT: ldr r2, .LCPI23_0
361-
; CHECK-NEXT: ldr r3, .LCPI23_3
362-
; CHECK-NEXT: and r4, r2, r0, lsr #1
363-
; CHECK-NEXT: and r2, r2, r1, lsr #1
364-
; CHECK-NEXT: sub r0, r0, r4
365-
; CHECK-NEXT: sub r1, r1, r2
366-
; CHECK-NEXT: and r4, r0, r3
367-
; CHECK-NEXT: and r2, r1, r3
368-
; CHECK-NEXT: and r0, r3, r0, lsr #2
369-
; CHECK-NEXT: and r1, r3, r1, lsr #2
370-
; CHECK-NEXT: add r0, r4, r0
371-
; CHECK-NEXT: ldr lr, .LCPI23_1
372-
; CHECK-NEXT: add r1, r2, r1
373-
; CHECK-NEXT: ldr r12, .LCPI23_2
374-
; CHECK-NEXT: add r0, r0, r0, lsr #4
375-
; CHECK-NEXT: and r0, r0, lr
376-
; CHECK-NEXT: add r1, r1, r1, lsr #4
377-
; CHECK-NEXT: mul r2, r0, r12
378-
; CHECK-NEXT: and r0, r1, lr
379-
; CHECK-NEXT: mul r1, r0, r12
380-
; CHECK-NEXT: lsr r0, r2, #24
381-
; CHECK-NEXT: add r0, r0, r1, lsr #24
382-
; CHECK-NEXT: mov r1, #0
383-
; CHECK-NEXT: pop {r4, lr}
335+
; CHECK-NEXT: .save {r11, lr}
336+
; CHECK-NEXT: push {r11, lr}
337+
; CHECK-NEXT: bl __popcountdi2
338+
; CHECK-NEXT: asr r1, r0, #31
339+
; CHECK-NEXT: pop {r11, lr}
384340
; CHECK-NEXT: mov pc, lr
385-
; CHECK-NEXT: .p2align 2
386-
; CHECK-NEXT: @ %bb.1:
387-
; CHECK-NEXT: .LCPI23_0:
388-
; CHECK-NEXT: .long 1431655765 @ 0x55555555
389-
; CHECK-NEXT: .LCPI23_1:
390-
; CHECK-NEXT: .long 252645135 @ 0xf0f0f0f
391-
; CHECK-NEXT: .LCPI23_2:
392-
; CHECK-NEXT: .long 16843009 @ 0x1010101
393-
; CHECK-NEXT: .LCPI23_3:
394-
; CHECK-NEXT: .long 858993459 @ 0x33333333
395341
%count = tail call i64 @llvm.ctpop.i64(i64 %x)
396342
ret i64 %count
397343
}

0 commit comments

Comments
 (0)