1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc --mtriple=loongarch32 -mattr=+d < %s | FileCheck %s --check-prefix=LA32 3; RUN: llc --mtriple=loongarch64 -mattr=+d < %s | FileCheck %s --check-prefix=LA64 4 5declare i8 @llvm.ctlz.i8(i8, i1) 6declare i16 @llvm.ctlz.i16(i16, i1) 7declare i32 @llvm.ctlz.i32(i32, i1) 8declare i64 @llvm.ctlz.i64(i64, i1) 9declare i8 @llvm.ctpop.i8(i8) 10declare i16 @llvm.ctpop.i16(i16) 11declare i32 @llvm.ctpop.i32(i32) 12declare i64 @llvm.ctpop.i64(i64) 13declare i8 @llvm.cttz.i8(i8, i1) 14declare i16 @llvm.cttz.i16(i16, i1) 15declare i32 @llvm.cttz.i32(i32, i1) 16declare i64 @llvm.cttz.i64(i64, i1) 17 18define i8 @test_ctlz_i8(i8 %a) nounwind { 19; LA32-LABEL: test_ctlz_i8: 20; LA32: # %bb.0: 21; LA32-NEXT: andi $a0, $a0, 255 22; LA32-NEXT: clz.w $a0, $a0 23; LA32-NEXT: addi.w $a0, $a0, -24 24; LA32-NEXT: ret 25; 26; LA64-LABEL: test_ctlz_i8: 27; LA64: # %bb.0: 28; LA64-NEXT: andi $a0, $a0, 255 29; LA64-NEXT: clz.d $a0, $a0 30; LA64-NEXT: addi.d $a0, $a0, -56 31; LA64-NEXT: ret 32 %tmp = call i8 @llvm.ctlz.i8(i8 %a, i1 false) 33 ret i8 %tmp 34} 35 36define i16 @test_ctlz_i16(i16 %a) nounwind { 37; LA32-LABEL: test_ctlz_i16: 38; LA32: # %bb.0: 39; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0 40; LA32-NEXT: clz.w $a0, $a0 41; LA32-NEXT: addi.w $a0, $a0, -16 42; LA32-NEXT: ret 43; 44; LA64-LABEL: test_ctlz_i16: 45; LA64: # %bb.0: 46; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 47; LA64-NEXT: clz.d $a0, $a0 48; LA64-NEXT: addi.d $a0, $a0, -48 49; LA64-NEXT: ret 50 %tmp = call i16 @llvm.ctlz.i16(i16 %a, i1 false) 51 ret i16 %tmp 52} 53 54define i32 @test_ctlz_i32(i32 %a) nounwind { 55; LA32-LABEL: test_ctlz_i32: 56; LA32: # %bb.0: 57; LA32-NEXT: clz.w $a0, $a0 58; LA32-NEXT: ret 59; 60; LA64-LABEL: test_ctlz_i32: 61; LA64: # %bb.0: 62; LA64-NEXT: clz.w $a0, $a0 63; LA64-NEXT: ret 64 %tmp = call i32 @llvm.ctlz.i32(i32 %a, i1 false) 65 ret i32 %tmp 66} 67 68define i64 @test_ctlz_i64(i64 %a) nounwind { 69; LA32-LABEL: test_ctlz_i64: 70; LA32: # %bb.0: 71; LA32-NEXT: sltu $a2, $zero, $a1 72; LA32-NEXT: clz.w $a1, $a1 73; LA32-NEXT: maskeqz $a1, $a1, $a2 74; LA32-NEXT: clz.w $a0, $a0 75; LA32-NEXT: addi.w $a0, $a0, 32 76; LA32-NEXT: masknez $a0, $a0, $a2 77; LA32-NEXT: or $a0, $a1, $a0 78; LA32-NEXT: move $a1, $zero 79; LA32-NEXT: ret 80; 81; LA64-LABEL: test_ctlz_i64: 82; LA64: # %bb.0: 83; LA64-NEXT: clz.d $a0, $a0 84; LA64-NEXT: ret 85 %tmp = call i64 @llvm.ctlz.i64(i64 %a, i1 false) 86 ret i64 %tmp 87} 88 89define i8 @test_not_ctlz_i8(i8 %a) nounwind { 90; LA32-LABEL: test_not_ctlz_i8: 91; LA32: # %bb.0: 92; LA32-NEXT: slli.w $a0, $a0, 24 93; LA32-NEXT: clo.w $a0, $a0 94; LA32-NEXT: ret 95; 96; LA64-LABEL: test_not_ctlz_i8: 97; LA64: # %bb.0: 98; LA64-NEXT: slli.d $a0, $a0, 56 99; LA64-NEXT: clo.d $a0, $a0 100; LA64-NEXT: ret 101 %neg = xor i8 %a, -1 102 %tmp = call i8 @llvm.ctlz.i8(i8 %neg, i1 false) 103 ret i8 %tmp 104} 105 106define i16 @test_not_ctlz_i16(i16 %a) nounwind { 107; LA32-LABEL: test_not_ctlz_i16: 108; LA32: # %bb.0: 109; LA32-NEXT: slli.w $a0, $a0, 16 110; LA32-NEXT: clo.w $a0, $a0 111; LA32-NEXT: ret 112; 113; LA64-LABEL: test_not_ctlz_i16: 114; LA64: # %bb.0: 115; LA64-NEXT: slli.d $a0, $a0, 48 116; LA64-NEXT: clo.d $a0, $a0 117; LA64-NEXT: ret 118 %neg = xor i16 %a, -1 119 %tmp = call i16 @llvm.ctlz.i16(i16 %neg, i1 false) 120 ret i16 %tmp 121} 122 123define i32 @test_not_ctlz_i32(i32 %a) nounwind { 124; LA32-LABEL: test_not_ctlz_i32: 125; LA32: # %bb.0: 126; LA32-NEXT: clo.w $a0, $a0 127; LA32-NEXT: ret 128; 129; LA64-LABEL: test_not_ctlz_i32: 130; LA64: # %bb.0: 131; LA64-NEXT: clo.w $a0, $a0 132; LA64-NEXT: ret 133 %neg = xor i32 %a, -1 134 %tmp = call i32 @llvm.ctlz.i32(i32 %neg, i1 false) 135 ret i32 %tmp 136} 137 138define i64 @test_not_ctlz_i64(i64 %a) nounwind { 139; LA32-LABEL: test_not_ctlz_i64: 140; LA32: # %bb.0: 141; LA32-NEXT: nor $a2, $a1, $zero 142; LA32-NEXT: sltu $a2, $zero, $a2 143; LA32-NEXT: clo.w $a0, $a0 144; LA32-NEXT: addi.w $a0, $a0, 32 145; LA32-NEXT: masknez $a0, $a0, $a2 146; LA32-NEXT: clo.w $a1, $a1 147; LA32-NEXT: maskeqz $a1, $a1, $a2 148; LA32-NEXT: or $a0, $a1, $a0 149; LA32-NEXT: move $a1, $zero 150; LA32-NEXT: ret 151; 152; LA64-LABEL: test_not_ctlz_i64: 153; LA64: # %bb.0: 154; LA64-NEXT: clo.d $a0, $a0 155; LA64-NEXT: ret 156 %neg = xor i64 %a, -1 157 %tmp = call i64 @llvm.ctlz.i64(i64 %neg, i1 false) 158 ret i64 %tmp 159} 160 161define i8 @test_ctpop_i8(i8 %a) nounwind { 162; LA32-LABEL: test_ctpop_i8: 163; LA32: # %bb.0: 164; LA32-NEXT: srli.w $a1, $a0, 1 165; LA32-NEXT: andi $a1, $a1, 85 166; LA32-NEXT: sub.w $a0, $a0, $a1 167; LA32-NEXT: andi $a1, $a0, 51 168; LA32-NEXT: srli.w $a0, $a0, 2 169; LA32-NEXT: andi $a0, $a0, 51 170; LA32-NEXT: add.w $a0, $a1, $a0 171; LA32-NEXT: srli.w $a1, $a0, 4 172; LA32-NEXT: add.w $a0, $a0, $a1 173; LA32-NEXT: andi $a0, $a0, 15 174; LA32-NEXT: ret 175; 176; LA64-LABEL: test_ctpop_i8: 177; LA64: # %bb.0: 178; LA64-NEXT: andi $a0, $a0, 255 179; LA64-NEXT: vldi $vr0, 0 180; LA64-NEXT: vinsgr2vr.d $vr0, $a0, 0 181; LA64-NEXT: vpcnt.d $vr0, $vr0 182; LA64-NEXT: vpickve2gr.d $a0, $vr0, 0 183; LA64-NEXT: ret 184 %1 = call i8 @llvm.ctpop.i8(i8 %a) 185 ret i8 %1 186} 187 188define i16 @test_ctpop_i16(i16 %a) nounwind { 189; LA32-LABEL: test_ctpop_i16: 190; LA32: # %bb.0: 191; LA32-NEXT: srli.w $a1, $a0, 1 192; LA32-NEXT: lu12i.w $a2, 5 193; LA32-NEXT: ori $a2, $a2, 1365 194; LA32-NEXT: and $a1, $a1, $a2 195; LA32-NEXT: sub.w $a0, $a0, $a1 196; LA32-NEXT: lu12i.w $a1, 3 197; LA32-NEXT: ori $a1, $a1, 819 198; LA32-NEXT: and $a2, $a0, $a1 199; LA32-NEXT: srli.w $a0, $a0, 2 200; LA32-NEXT: and $a0, $a0, $a1 201; LA32-NEXT: add.w $a0, $a2, $a0 202; LA32-NEXT: srli.w $a1, $a0, 4 203; LA32-NEXT: add.w $a0, $a0, $a1 204; LA32-NEXT: bstrpick.w $a1, $a0, 11, 8 205; LA32-NEXT: andi $a0, $a0, 15 206; LA32-NEXT: add.w $a0, $a0, $a1 207; LA32-NEXT: ret 208; 209; LA64-LABEL: test_ctpop_i16: 210; LA64: # %bb.0: 211; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0 212; LA64-NEXT: vldi $vr0, 0 213; LA64-NEXT: vinsgr2vr.d $vr0, $a0, 0 214; LA64-NEXT: vpcnt.d $vr0, $vr0 215; LA64-NEXT: vpickve2gr.d $a0, $vr0, 0 216; LA64-NEXT: ret 217 %1 = call i16 @llvm.ctpop.i16(i16 %a) 218 ret i16 %1 219} 220 221define i32 @test_ctpop_i32(i32 %a) nounwind { 222; LA32-LABEL: test_ctpop_i32: 223; LA32: # %bb.0: 224; LA32-NEXT: srli.w $a1, $a0, 1 225; LA32-NEXT: lu12i.w $a2, 349525 226; LA32-NEXT: ori $a2, $a2, 1365 227; LA32-NEXT: and $a1, $a1, $a2 228; LA32-NEXT: sub.w $a0, $a0, $a1 229; LA32-NEXT: lu12i.w $a1, 209715 230; LA32-NEXT: ori $a1, $a1, 819 231; LA32-NEXT: and $a2, $a0, $a1 232; LA32-NEXT: srli.w $a0, $a0, 2 233; LA32-NEXT: and $a0, $a0, $a1 234; LA32-NEXT: add.w $a0, $a2, $a0 235; LA32-NEXT: srli.w $a1, $a0, 4 236; LA32-NEXT: add.w $a0, $a0, $a1 237; LA32-NEXT: lu12i.w $a1, 61680 238; LA32-NEXT: ori $a1, $a1, 3855 239; LA32-NEXT: and $a0, $a0, $a1 240; LA32-NEXT: lu12i.w $a1, 4112 241; LA32-NEXT: ori $a1, $a1, 257 242; LA32-NEXT: mul.w $a0, $a0, $a1 243; LA32-NEXT: srli.w $a0, $a0, 24 244; LA32-NEXT: ret 245; 246; LA64-LABEL: test_ctpop_i32: 247; LA64: # %bb.0: 248; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 249; LA64-NEXT: vldi $vr0, 0 250; LA64-NEXT: vinsgr2vr.d $vr0, $a0, 0 251; LA64-NEXT: vpcnt.d $vr0, $vr0 252; LA64-NEXT: vpickve2gr.d $a0, $vr0, 0 253; LA64-NEXT: ret 254 %1 = call i32 @llvm.ctpop.i32(i32 %a) 255 ret i32 %1 256} 257 258define i64 @test_ctpop_i64(i64 %a) nounwind { 259; LA32-LABEL: test_ctpop_i64: 260; LA32: # %bb.0: 261; LA32-NEXT: srli.w $a2, $a1, 1 262; LA32-NEXT: lu12i.w $a3, 349525 263; LA32-NEXT: ori $a3, $a3, 1365 264; LA32-NEXT: and $a2, $a2, $a3 265; LA32-NEXT: sub.w $a1, $a1, $a2 266; LA32-NEXT: lu12i.w $a2, 209715 267; LA32-NEXT: ori $a2, $a2, 819 268; LA32-NEXT: and $a4, $a1, $a2 269; LA32-NEXT: srli.w $a1, $a1, 2 270; LA32-NEXT: and $a1, $a1, $a2 271; LA32-NEXT: add.w $a1, $a4, $a1 272; LA32-NEXT: srli.w $a4, $a1, 4 273; LA32-NEXT: add.w $a1, $a1, $a4 274; LA32-NEXT: lu12i.w $a4, 61680 275; LA32-NEXT: ori $a4, $a4, 3855 276; LA32-NEXT: and $a1, $a1, $a4 277; LA32-NEXT: lu12i.w $a5, 4112 278; LA32-NEXT: ori $a5, $a5, 257 279; LA32-NEXT: mul.w $a1, $a1, $a5 280; LA32-NEXT: srli.w $a1, $a1, 24 281; LA32-NEXT: srli.w $a6, $a0, 1 282; LA32-NEXT: and $a3, $a6, $a3 283; LA32-NEXT: sub.w $a0, $a0, $a3 284; LA32-NEXT: and $a3, $a0, $a2 285; LA32-NEXT: srli.w $a0, $a0, 2 286; LA32-NEXT: and $a0, $a0, $a2 287; LA32-NEXT: add.w $a0, $a3, $a0 288; LA32-NEXT: srli.w $a2, $a0, 4 289; LA32-NEXT: add.w $a0, $a0, $a2 290; LA32-NEXT: and $a0, $a0, $a4 291; LA32-NEXT: mul.w $a0, $a0, $a5 292; LA32-NEXT: srli.w $a0, $a0, 24 293; LA32-NEXT: add.w $a0, $a0, $a1 294; LA32-NEXT: move $a1, $zero 295; LA32-NEXT: ret 296; 297; LA64-LABEL: test_ctpop_i64: 298; LA64: # %bb.0: 299; LA64-NEXT: vldi $vr0, 0 300; LA64-NEXT: vinsgr2vr.d $vr0, $a0, 0 301; LA64-NEXT: vpcnt.d $vr0, $vr0 302; LA64-NEXT: vpickve2gr.d $a0, $vr0, 0 303; LA64-NEXT: ret 304 %1 = call i64 @llvm.ctpop.i64(i64 %a) 305 ret i64 %1 306} 307 308define i8 @test_cttz_i8(i8 %a) nounwind { 309; LA32-LABEL: test_cttz_i8: 310; LA32: # %bb.0: 311; LA32-NEXT: ori $a0, $a0, 256 312; LA32-NEXT: ctz.w $a0, $a0 313; LA32-NEXT: ret 314; 315; LA64-LABEL: test_cttz_i8: 316; LA64: # %bb.0: 317; LA64-NEXT: ori $a0, $a0, 256 318; LA64-NEXT: ctz.d $a0, $a0 319; LA64-NEXT: ret 320 %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 false) 321 ret i8 %tmp 322} 323 324define i16 @test_cttz_i16(i16 %a) nounwind { 325; LA32-LABEL: test_cttz_i16: 326; LA32: # %bb.0: 327; LA32-NEXT: lu12i.w $a1, 16 328; LA32-NEXT: or $a0, $a0, $a1 329; LA32-NEXT: ctz.w $a0, $a0 330; LA32-NEXT: ret 331; 332; LA64-LABEL: test_cttz_i16: 333; LA64: # %bb.0: 334; LA64-NEXT: lu12i.w $a1, 16 335; LA64-NEXT: or $a0, $a0, $a1 336; LA64-NEXT: ctz.d $a0, $a0 337; LA64-NEXT: ret 338 %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 false) 339 ret i16 %tmp 340} 341 342define i32 @test_cttz_i32(i32 %a) nounwind { 343; LA32-LABEL: test_cttz_i32: 344; LA32: # %bb.0: 345; LA32-NEXT: ctz.w $a0, $a0 346; LA32-NEXT: ret 347; 348; LA64-LABEL: test_cttz_i32: 349; LA64: # %bb.0: 350; LA64-NEXT: ctz.w $a0, $a0 351; LA64-NEXT: ret 352 %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 false) 353 ret i32 %tmp 354} 355 356define i64 @test_cttz_i64(i64 %a) nounwind { 357; LA32-LABEL: test_cttz_i64: 358; LA32: # %bb.0: 359; LA32-NEXT: sltu $a2, $zero, $a0 360; LA32-NEXT: ctz.w $a0, $a0 361; LA32-NEXT: maskeqz $a0, $a0, $a2 362; LA32-NEXT: ctz.w $a1, $a1 363; LA32-NEXT: addi.w $a1, $a1, 32 364; LA32-NEXT: masknez $a1, $a1, $a2 365; LA32-NEXT: or $a0, $a0, $a1 366; LA32-NEXT: move $a1, $zero 367; LA32-NEXT: ret 368; 369; LA64-LABEL: test_cttz_i64: 370; LA64: # %bb.0: 371; LA64-NEXT: ctz.d $a0, $a0 372; LA64-NEXT: ret 373 %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 false) 374 ret i64 %tmp 375} 376 377define i8 @test_not_cttz_i8(i8 %a) nounwind { 378; LA32-LABEL: test_not_cttz_i8: 379; LA32: # %bb.0: 380; LA32-NEXT: ori $a1, $zero, 256 381; LA32-NEXT: orn $a0, $a1, $a0 382; LA32-NEXT: ctz.w $a0, $a0 383; LA32-NEXT: ret 384; 385; LA64-LABEL: test_not_cttz_i8: 386; LA64: # %bb.0: 387; LA64-NEXT: ori $a1, $zero, 256 388; LA64-NEXT: orn $a0, $a1, $a0 389; LA64-NEXT: ctz.d $a0, $a0 390; LA64-NEXT: ret 391 %neg = xor i8 %a, -1 392 %tmp = call i8 @llvm.cttz.i8(i8 %neg, i1 false) 393 ret i8 %tmp 394} 395 396define i16 @test_not_cttz_i16(i16 %a) nounwind { 397; LA32-LABEL: test_not_cttz_i16: 398; LA32: # %bb.0: 399; LA32-NEXT: lu12i.w $a1, 16 400; LA32-NEXT: orn $a0, $a1, $a0 401; LA32-NEXT: ctz.w $a0, $a0 402; LA32-NEXT: ret 403; 404; LA64-LABEL: test_not_cttz_i16: 405; LA64: # %bb.0: 406; LA64-NEXT: lu12i.w $a1, 16 407; LA64-NEXT: orn $a0, $a1, $a0 408; LA64-NEXT: ctz.d $a0, $a0 409; LA64-NEXT: ret 410 %neg = xor i16 %a, -1 411 %tmp = call i16 @llvm.cttz.i16(i16 %neg, i1 false) 412 ret i16 %tmp 413} 414 415define i32 @test_not_cttz_i32(i32 %a) nounwind { 416; LA32-LABEL: test_not_cttz_i32: 417; LA32: # %bb.0: 418; LA32-NEXT: cto.w $a0, $a0 419; LA32-NEXT: ret 420; 421; LA64-LABEL: test_not_cttz_i32: 422; LA64: # %bb.0: 423; LA64-NEXT: cto.w $a0, $a0 424; LA64-NEXT: ret 425 %neg = xor i32 %a, -1 426 %tmp = call i32 @llvm.cttz.i32(i32 %neg, i1 false) 427 ret i32 %tmp 428} 429 430define i64 @test_not_cttz_i64(i64 %a) nounwind { 431; LA32-LABEL: test_not_cttz_i64: 432; LA32: # %bb.0: 433; LA32-NEXT: nor $a2, $a0, $zero 434; LA32-NEXT: sltu $a2, $zero, $a2 435; LA32-NEXT: cto.w $a1, $a1 436; LA32-NEXT: addi.w $a1, $a1, 32 437; LA32-NEXT: masknez $a1, $a1, $a2 438; LA32-NEXT: cto.w $a0, $a0 439; LA32-NEXT: maskeqz $a0, $a0, $a2 440; LA32-NEXT: or $a0, $a0, $a1 441; LA32-NEXT: move $a1, $zero 442; LA32-NEXT: ret 443; 444; LA64-LABEL: test_not_cttz_i64: 445; LA64: # %bb.0: 446; LA64-NEXT: cto.d $a0, $a0 447; LA64-NEXT: ret 448 %neg = xor i64 %a, -1 449 %tmp = call i64 @llvm.cttz.i64(i64 %neg, i1 false) 450 ret i64 %tmp 451} 452