|  | ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | 
|  | ; RUN: llc --mtriple=loongarch32 -mattr=-32s,+lsx < %s | FileCheck %s --check-prefix=LA32R | 
|  | ; RUN: llc --mtriple=loongarch32 -mattr=+32s,+lsx < %s | FileCheck %s --check-prefix=LA32S | 
|  | ; RUN: llc --mtriple=loongarch64 -mattr=+lsx < %s | FileCheck %s --check-prefix=LA64 | 
|  |  | 
|  | declare i8 @llvm.ctpop.i8(i8) | 
|  | declare i16 @llvm.ctpop.i16(i16) | 
|  | declare i32 @llvm.ctpop.i32(i32) | 
|  | declare i64 @llvm.ctpop.i64(i64) | 
|  |  | 
|  | define i8 @test_ctpop_i8(i8 %a) nounwind { | 
|  | ; LA32R-LABEL: test_ctpop_i8: | 
|  | ; LA32R:       # %bb.0: | 
|  | ; LA32R-NEXT:    andi $a0, $a0, 255 | 
|  | ; LA32R-NEXT:    vldi $vr0, 0 | 
|  | ; LA32R-NEXT:    vinsgr2vr.w $vr0, $a0, 0 | 
|  | ; LA32R-NEXT:    vpcnt.w $vr0, $vr0 | 
|  | ; LA32R-NEXT:    vpickve2gr.w $a0, $vr0, 0 | 
|  | ; LA32R-NEXT:    ret | 
|  | ; | 
|  | ; LA32S-LABEL: test_ctpop_i8: | 
|  | ; LA32S:       # %bb.0: | 
|  | ; LA32S-NEXT:    andi $a0, $a0, 255 | 
|  | ; LA32S-NEXT:    vldi $vr0, 0 | 
|  | ; LA32S-NEXT:    vinsgr2vr.w $vr0, $a0, 0 | 
|  | ; LA32S-NEXT:    vpcnt.w $vr0, $vr0 | 
|  | ; LA32S-NEXT:    vpickve2gr.w $a0, $vr0, 0 | 
|  | ; LA32S-NEXT:    ret | 
|  | ; | 
|  | ; LA64-LABEL: test_ctpop_i8: | 
|  | ; LA64:       # %bb.0: | 
|  | ; LA64-NEXT:    andi $a0, $a0, 255 | 
|  | ; LA64-NEXT:    vldi $vr0, 0 | 
|  | ; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0 | 
|  | ; LA64-NEXT:    vpcnt.d $vr0, $vr0 | 
|  | ; LA64-NEXT:    vpickve2gr.d $a0, $vr0, 0 | 
|  | ; LA64-NEXT:    ret | 
|  | %1 = call i8 @llvm.ctpop.i8(i8 %a) | 
|  | ret i8 %1 | 
|  | } | 
|  |  | 
|  | define i16 @test_ctpop_i16(i16 %a) nounwind { | 
|  | ; LA32R-LABEL: test_ctpop_i16: | 
|  | ; LA32R:       # %bb.0: | 
|  | ; LA32R-NEXT:    lu12i.w $a1, 15 | 
|  | ; LA32R-NEXT:    ori $a1, $a1, 4095 | 
|  | ; LA32R-NEXT:    and $a0, $a0, $a1 | 
|  | ; LA32R-NEXT:    vldi $vr0, 0 | 
|  | ; LA32R-NEXT:    vinsgr2vr.w $vr0, $a0, 0 | 
|  | ; LA32R-NEXT:    vpcnt.w $vr0, $vr0 | 
|  | ; LA32R-NEXT:    vpickve2gr.w $a0, $vr0, 0 | 
|  | ; LA32R-NEXT:    ret | 
|  | ; | 
|  | ; LA32S-LABEL: test_ctpop_i16: | 
|  | ; LA32S:       # %bb.0: | 
|  | ; LA32S-NEXT:    bstrpick.w $a0, $a0, 15, 0 | 
|  | ; LA32S-NEXT:    vldi $vr0, 0 | 
|  | ; LA32S-NEXT:    vinsgr2vr.w $vr0, $a0, 0 | 
|  | ; LA32S-NEXT:    vpcnt.w $vr0, $vr0 | 
|  | ; LA32S-NEXT:    vpickve2gr.w $a0, $vr0, 0 | 
|  | ; LA32S-NEXT:    ret | 
|  | ; | 
|  | ; LA64-LABEL: test_ctpop_i16: | 
|  | ; LA64:       # %bb.0: | 
|  | ; LA64-NEXT:    bstrpick.d $a0, $a0, 15, 0 | 
|  | ; LA64-NEXT:    vldi $vr0, 0 | 
|  | ; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0 | 
|  | ; LA64-NEXT:    vpcnt.d $vr0, $vr0 | 
|  | ; LA64-NEXT:    vpickve2gr.d $a0, $vr0, 0 | 
|  | ; LA64-NEXT:    ret | 
|  | %1 = call i16 @llvm.ctpop.i16(i16 %a) | 
|  | ret i16 %1 | 
|  | } | 
|  |  | 
|  | define i32 @test_ctpop_i32(i32 %a) nounwind { | 
|  | ; LA32R-LABEL: test_ctpop_i32: | 
|  | ; LA32R:       # %bb.0: | 
|  | ; LA32R-NEXT:    vldi $vr0, 0 | 
|  | ; LA32R-NEXT:    vinsgr2vr.w $vr0, $a0, 0 | 
|  | ; LA32R-NEXT:    vpcnt.w $vr0, $vr0 | 
|  | ; LA32R-NEXT:    vpickve2gr.w $a0, $vr0, 0 | 
|  | ; LA32R-NEXT:    ret | 
|  | ; | 
|  | ; LA32S-LABEL: test_ctpop_i32: | 
|  | ; LA32S:       # %bb.0: | 
|  | ; LA32S-NEXT:    vldi $vr0, 0 | 
|  | ; LA32S-NEXT:    vinsgr2vr.w $vr0, $a0, 0 | 
|  | ; LA32S-NEXT:    vpcnt.w $vr0, $vr0 | 
|  | ; LA32S-NEXT:    vpickve2gr.w $a0, $vr0, 0 | 
|  | ; LA32S-NEXT:    ret | 
|  | ; | 
|  | ; LA64-LABEL: test_ctpop_i32: | 
|  | ; LA64:       # %bb.0: | 
|  | ; LA64-NEXT:    bstrpick.d $a0, $a0, 31, 0 | 
|  | ; LA64-NEXT:    vldi $vr0, 0 | 
|  | ; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0 | 
|  | ; LA64-NEXT:    vpcnt.d $vr0, $vr0 | 
|  | ; LA64-NEXT:    vpickve2gr.d $a0, $vr0, 0 | 
|  | ; LA64-NEXT:    ret | 
|  | %1 = call i32 @llvm.ctpop.i32(i32 %a) | 
|  | ret i32 %1 | 
|  | } | 
|  |  | 
|  | define i64 @test_ctpop_i64(i64 %a) nounwind { | 
|  | ; LA32R-LABEL: test_ctpop_i64: | 
|  | ; LA32R:       # %bb.0: | 
|  | ; LA32R-NEXT:    vldi $vr0, 0 | 
|  | ; LA32R-NEXT:    vldi $vr1, 0 | 
|  | ; LA32R-NEXT:    vinsgr2vr.w $vr1, $a1, 0 | 
|  | ; LA32R-NEXT:    vpcnt.w $vr1, $vr1 | 
|  | ; LA32R-NEXT:    vpickve2gr.w $a1, $vr1, 0 | 
|  | ; LA32R-NEXT:    vinsgr2vr.w $vr0, $a0, 0 | 
|  | ; LA32R-NEXT:    vpcnt.w $vr0, $vr0 | 
|  | ; LA32R-NEXT:    vpickve2gr.w $a0, $vr0, 0 | 
|  | ; LA32R-NEXT:    add.w $a0, $a0, $a1 | 
|  | ; LA32R-NEXT:    move $a1, $zero | 
|  | ; LA32R-NEXT:    ret | 
|  | ; | 
|  | ; LA32S-LABEL: test_ctpop_i64: | 
|  | ; LA32S:       # %bb.0: | 
|  | ; LA32S-NEXT:    vldi $vr0, 0 | 
|  | ; LA32S-NEXT:    vldi $vr1, 0 | 
|  | ; LA32S-NEXT:    vinsgr2vr.w $vr1, $a1, 0 | 
|  | ; LA32S-NEXT:    vpcnt.w $vr1, $vr1 | 
|  | ; LA32S-NEXT:    vpickve2gr.w $a1, $vr1, 0 | 
|  | ; LA32S-NEXT:    vinsgr2vr.w $vr0, $a0, 0 | 
|  | ; LA32S-NEXT:    vpcnt.w $vr0, $vr0 | 
|  | ; LA32S-NEXT:    vpickve2gr.w $a0, $vr0, 0 | 
|  | ; LA32S-NEXT:    add.w $a0, $a0, $a1 | 
|  | ; LA32S-NEXT:    move $a1, $zero | 
|  | ; LA32S-NEXT:    ret | 
|  | ; | 
|  | ; LA64-LABEL: test_ctpop_i64: | 
|  | ; LA64:       # %bb.0: | 
|  | ; LA64-NEXT:    vldi $vr0, 0 | 
|  | ; LA64-NEXT:    vinsgr2vr.d $vr0, $a0, 0 | 
|  | ; LA64-NEXT:    vpcnt.d $vr0, $vr0 | 
|  | ; LA64-NEXT:    vpickve2gr.d $a0, $vr0, 0 | 
|  | ; LA64-NEXT:    ret | 
|  | %1 = call i64 @llvm.ctpop.i64(i64 %a) | 
|  | ret i64 %1 | 
|  | } |