1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I 4; RUN: llc -mtriple=riscv32 -mattr=+zbs -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBS,RV32ZBSNOZBB 6; RUN: llc -mtriple=riscv32 -mattr=+zbs,+zbb -verify-machineinstrs < %s \ 7; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBS,RV32ZBSZBB 8 9define i32 @bclr_i32(i32 %a, i32 %b) nounwind { 10; RV32I-LABEL: bclr_i32: 11; RV32I: # %bb.0: 12; RV32I-NEXT: li a2, 1 13; RV32I-NEXT: sll a1, a2, a1 14; RV32I-NEXT: not a1, a1 15; RV32I-NEXT: and a0, a1, a0 16; RV32I-NEXT: ret 17; 18; RV32ZBS-LABEL: bclr_i32: 19; RV32ZBS: # %bb.0: 20; RV32ZBS-NEXT: bclr a0, a0, a1 21; RV32ZBS-NEXT: ret 22 %and = and i32 %b, 31 23 %shl = shl nuw i32 1, %and 24 %neg = xor i32 %shl, -1 25 %and1 = and i32 %neg, %a 26 ret i32 %and1 27} 28 29define i32 @bclr_i32_no_mask(i32 %a, i32 %b) nounwind { 30; RV32I-LABEL: bclr_i32_no_mask: 31; RV32I: # %bb.0: 32; RV32I-NEXT: li a2, 1 33; RV32I-NEXT: sll a1, a2, a1 34; RV32I-NEXT: not a1, a1 35; RV32I-NEXT: and a0, a1, a0 36; RV32I-NEXT: ret 37; 38; RV32ZBS-LABEL: bclr_i32_no_mask: 39; RV32ZBS: # %bb.0: 40; RV32ZBS-NEXT: bclr a0, a0, a1 41; RV32ZBS-NEXT: ret 42 %shl = shl nuw i32 1, %b 43 %neg = xor i32 %shl, -1 44 %and1 = and i32 %neg, %a 45 ret i32 %and1 46} 47 48define i64 @bclr_i64(i64 %a, i64 %b) nounwind { 49; RV32I-LABEL: bclr_i64: 50; RV32I: # %bb.0: 51; RV32I-NEXT: andi a3, a2, 63 52; RV32I-NEXT: li a4, 1 53; RV32I-NEXT: addi a5, a3, -32 54; RV32I-NEXT: sll a2, a4, a2 55; RV32I-NEXT: sll a3, a4, a3 56; RV32I-NEXT: slti a4, a5, 0 57; RV32I-NEXT: neg a5, a4 58; RV32I-NEXT: addi a4, a4, -1 59; RV32I-NEXT: and a2, a5, a2 60; RV32I-NEXT: and a3, a4, a3 61; RV32I-NEXT: not a2, a2 62; RV32I-NEXT: not a3, a3 63; RV32I-NEXT: and a0, a2, a0 64; RV32I-NEXT: and a1, a3, a1 65; RV32I-NEXT: ret 66; 67; RV32ZBSNOZBB-LABEL: bclr_i64: 68; RV32ZBSNOZBB: # %bb.0: 69; RV32ZBSNOZBB-NEXT: andi a3, a2, 63 70; RV32ZBSNOZBB-NEXT: bset a2, zero, a2 71; RV32ZBSNOZBB-NEXT: addi a4, a3, -32 72; RV32ZBSNOZBB-NEXT: bset a3, zero, a3 73; RV32ZBSNOZBB-NEXT: slti a4, a4, 0 74; RV32ZBSNOZBB-NEXT: neg a5, a4 75; RV32ZBSNOZBB-NEXT: addi a4, a4, -1 76; RV32ZBSNOZBB-NEXT: and a2, a5, a2 77; RV32ZBSNOZBB-NEXT: and a3, a4, a3 78; RV32ZBSNOZBB-NEXT: not a3, a3 79; RV32ZBSNOZBB-NEXT: not a2, a2 80; RV32ZBSNOZBB-NEXT: and a0, a2, a0 81; RV32ZBSNOZBB-NEXT: and a1, a3, a1 82; RV32ZBSNOZBB-NEXT: ret 83; 84; RV32ZBSZBB-LABEL: bclr_i64: 85; RV32ZBSZBB: # %bb.0: 86; RV32ZBSZBB-NEXT: andi a3, a2, 63 87; RV32ZBSZBB-NEXT: bset a2, zero, a2 88; RV32ZBSZBB-NEXT: bset a4, zero, a3 89; RV32ZBSZBB-NEXT: addi a3, a3, -32 90; RV32ZBSZBB-NEXT: slti a3, a3, 0 91; RV32ZBSZBB-NEXT: addi a5, a3, -1 92; RV32ZBSZBB-NEXT: neg a3, a3 93; RV32ZBSZBB-NEXT: and a4, a5, a4 94; RV32ZBSZBB-NEXT: and a2, a3, a2 95; RV32ZBSZBB-NEXT: andn a0, a0, a2 96; RV32ZBSZBB-NEXT: andn a1, a1, a4 97; RV32ZBSZBB-NEXT: ret 98 %and = and i64 %b, 63 99 %shl = shl nuw i64 1, %and 100 %neg = xor i64 %shl, -1 101 %and1 = and i64 %neg, %a 102 ret i64 %and1 103} 104 105define i32 @bset_i32(i32 %a, i32 %b) nounwind { 106; RV32I-LABEL: bset_i32: 107; RV32I: # %bb.0: 108; RV32I-NEXT: li a2, 1 109; RV32I-NEXT: sll a1, a2, a1 110; RV32I-NEXT: or a0, a1, a0 111; RV32I-NEXT: ret 112; 113; RV32ZBS-LABEL: bset_i32: 114; RV32ZBS: # %bb.0: 115; RV32ZBS-NEXT: bset a0, a0, a1 116; RV32ZBS-NEXT: ret 117 %and = and i32 %b, 31 118 %shl = shl nuw i32 1, %and 119 %or = or i32 %shl, %a 120 ret i32 %or 121} 122 123define i32 @bset_i32_no_mask(i32 %a, i32 %b) nounwind { 124; RV32I-LABEL: bset_i32_no_mask: 125; RV32I: # %bb.0: 126; RV32I-NEXT: li a2, 1 127; RV32I-NEXT: sll a1, a2, a1 128; RV32I-NEXT: or a0, a1, a0 129; RV32I-NEXT: ret 130; 131; RV32ZBS-LABEL: bset_i32_no_mask: 132; RV32ZBS: # %bb.0: 133; RV32ZBS-NEXT: bset a0, a0, a1 134; RV32ZBS-NEXT: ret 135 %shl = shl nuw i32 1, %b 136 %or = or i32 %shl, %a 137 ret i32 %or 138} 139 140; We can use bsetw for 1 << x by setting the first source to zero. 141define signext i32 @bset_i32_zero(i32 signext %a) nounwind { 142; RV32I-LABEL: bset_i32_zero: 143; RV32I: # %bb.0: 144; RV32I-NEXT: li a1, 1 145; RV32I-NEXT: sll a0, a1, a0 146; RV32I-NEXT: ret 147; 148; RV32ZBS-LABEL: bset_i32_zero: 149; RV32ZBS: # %bb.0: 150; RV32ZBS-NEXT: bset a0, zero, a0 151; RV32ZBS-NEXT: ret 152 %shl = shl i32 1, %a 153 ret i32 %shl 154} 155 156; As we are not matching directly i64 code patterns on RV32 some i64 patterns 157; don't have yet any matching bit manipulation instructions on RV32. 158; This test is presented here in case future expansions of the Bitmanip 159; extensions introduce instructions suitable for this pattern. 160 161define i64 @bset_i64(i64 %a, i64 %b) nounwind { 162; RV32I-LABEL: bset_i64: 163; RV32I: # %bb.0: 164; RV32I-NEXT: li a3, 1 165; RV32I-NEXT: sll a2, a3, a2 166; RV32I-NEXT: srai a3, a2, 31 167; RV32I-NEXT: or a0, a2, a0 168; RV32I-NEXT: or a1, a3, a1 169; RV32I-NEXT: ret 170; 171; RV32ZBS-LABEL: bset_i64: 172; RV32ZBS: # %bb.0: 173; RV32ZBS-NEXT: bset a3, zero, a2 174; RV32ZBS-NEXT: srai a3, a3, 31 175; RV32ZBS-NEXT: bset a0, a0, a2 176; RV32ZBS-NEXT: or a1, a3, a1 177; RV32ZBS-NEXT: ret 178 %1 = trunc i64 %b to i32 179 %conv = and i32 %1, 63 180 %shl = shl nuw i32 1, %conv 181 %conv1 = sext i32 %shl to i64 182 %or = or i64 %conv1, %a 183 ret i64 %or 184} 185 186define signext i64 @bset_i64_zero(i64 signext %a) nounwind { 187; RV32I-LABEL: bset_i64_zero: 188; RV32I: # %bb.0: 189; RV32I-NEXT: addi a1, a0, -32 190; RV32I-NEXT: li a2, 1 191; RV32I-NEXT: slti a1, a1, 0 192; RV32I-NEXT: sll a2, a2, a0 193; RV32I-NEXT: neg a0, a1 194; RV32I-NEXT: addi a1, a1, -1 195; RV32I-NEXT: and a0, a0, a2 196; RV32I-NEXT: and a1, a1, a2 197; RV32I-NEXT: ret 198; 199; RV32ZBS-LABEL: bset_i64_zero: 200; RV32ZBS: # %bb.0: 201; RV32ZBS-NEXT: addi a1, a0, -32 202; RV32ZBS-NEXT: bset a2, zero, a0 203; RV32ZBS-NEXT: slti a0, a1, 0 204; RV32ZBS-NEXT: neg a1, a0 205; RV32ZBS-NEXT: addi a3, a0, -1 206; RV32ZBS-NEXT: and a0, a1, a2 207; RV32ZBS-NEXT: and a1, a3, a2 208; RV32ZBS-NEXT: ret 209 %shl = shl i64 1, %a 210 ret i64 %shl 211} 212 213define i32 @binv_i32(i32 %a, i32 %b) nounwind { 214; RV32I-LABEL: binv_i32: 215; RV32I: # %bb.0: 216; RV32I-NEXT: li a2, 1 217; RV32I-NEXT: sll a1, a2, a1 218; RV32I-NEXT: xor a0, a1, a0 219; RV32I-NEXT: ret 220; 221; RV32ZBS-LABEL: binv_i32: 222; RV32ZBS: # %bb.0: 223; RV32ZBS-NEXT: binv a0, a0, a1 224; RV32ZBS-NEXT: ret 225 %and = and i32 %b, 31 226 %shl = shl nuw i32 1, %and 227 %xor = xor i32 %shl, %a 228 ret i32 %xor 229} 230 231; As we are not matching directly i64 code patterns on RV32 some i64 patterns 232; don't have yet any matching bit manipulation instructions on RV32. 233; This test is presented here in case future expansions of the Bitmanip 234; extensions introduce instructions suitable for this pattern. 235 236define i64 @binv_i64(i64 %a, i64 %b) nounwind { 237; RV32I-LABEL: binv_i64: 238; RV32I: # %bb.0: 239; RV32I-NEXT: li a3, 1 240; RV32I-NEXT: sll a2, a3, a2 241; RV32I-NEXT: srai a3, a2, 31 242; RV32I-NEXT: xor a0, a2, a0 243; RV32I-NEXT: xor a1, a3, a1 244; RV32I-NEXT: ret 245; 246; RV32ZBS-LABEL: binv_i64: 247; RV32ZBS: # %bb.0: 248; RV32ZBS-NEXT: bset a3, zero, a2 249; RV32ZBS-NEXT: srai a3, a3, 31 250; RV32ZBS-NEXT: binv a0, a0, a2 251; RV32ZBS-NEXT: xor a1, a3, a1 252; RV32ZBS-NEXT: ret 253 %1 = trunc i64 %b to i32 254 %conv = and i32 %1, 63 255 %shl = shl nuw i32 1, %conv 256 %conv1 = sext i32 %shl to i64 257 %xor = xor i64 %conv1, %a 258 ret i64 %xor 259} 260 261define i32 @bext_i32(i32 %a, i32 %b) nounwind { 262; RV32I-LABEL: bext_i32: 263; RV32I: # %bb.0: 264; RV32I-NEXT: srl a0, a0, a1 265; RV32I-NEXT: andi a0, a0, 1 266; RV32I-NEXT: ret 267; 268; RV32ZBS-LABEL: bext_i32: 269; RV32ZBS: # %bb.0: 270; RV32ZBS-NEXT: bext a0, a0, a1 271; RV32ZBS-NEXT: ret 272 %and = and i32 %b, 31 273 %shr = lshr i32 %a, %and 274 %and1 = and i32 %shr, 1 275 ret i32 %and1 276} 277 278define i32 @bext_i32_no_mask(i32 %a, i32 %b) nounwind { 279; RV32I-LABEL: bext_i32_no_mask: 280; RV32I: # %bb.0: 281; RV32I-NEXT: srl a0, a0, a1 282; RV32I-NEXT: andi a0, a0, 1 283; RV32I-NEXT: ret 284; 285; RV32ZBS-LABEL: bext_i32_no_mask: 286; RV32ZBS: # %bb.0: 287; RV32ZBS-NEXT: bext a0, a0, a1 288; RV32ZBS-NEXT: ret 289 %shr = lshr i32 %a, %b 290 %and1 = and i32 %shr, 1 291 ret i32 %and1 292} 293 294; As we are not matching directly i64 code patterns on RV32 some i64 patterns 295; don't have yet any matching bit manipulation instructions on RV32. 296; This test is presented here in case future expansions of the Bitmanip 297; extensions introduce instructions suitable for this pattern. 298 299define i64 @bext_i64(i64 %a, i64 %b) nounwind { 300; CHECK-LABEL: bext_i64: 301; CHECK: # %bb.0: 302; CHECK-NEXT: andi a3, a2, 63 303; CHECK-NEXT: addi a4, a3, -32 304; CHECK-NEXT: bltz a4, .LBB12_2 305; CHECK-NEXT: # %bb.1: 306; CHECK-NEXT: srl a0, a1, a3 307; CHECK-NEXT: j .LBB12_3 308; CHECK-NEXT: .LBB12_2: 309; CHECK-NEXT: srl a0, a0, a2 310; CHECK-NEXT: slli a1, a1, 1 311; CHECK-NEXT: not a2, a3 312; CHECK-NEXT: sll a1, a1, a2 313; CHECK-NEXT: or a0, a0, a1 314; CHECK-NEXT: .LBB12_3: 315; CHECK-NEXT: andi a0, a0, 1 316; CHECK-NEXT: li a1, 0 317; CHECK-NEXT: ret 318 %conv = and i64 %b, 63 319 %shr = lshr i64 %a, %conv 320 %and1 = and i64 %shr, 1 321 ret i64 %and1 322} 323 324define i32 @bexti_i32(i32 %a) nounwind { 325; RV32I-LABEL: bexti_i32: 326; RV32I: # %bb.0: 327; RV32I-NEXT: slli a0, a0, 26 328; RV32I-NEXT: srli a0, a0, 31 329; RV32I-NEXT: ret 330; 331; RV32ZBS-LABEL: bexti_i32: 332; RV32ZBS: # %bb.0: 333; RV32ZBS-NEXT: bexti a0, a0, 5 334; RV32ZBS-NEXT: ret 335 %shr = lshr i32 %a, 5 336 %and = and i32 %shr, 1 337 ret i32 %and 338} 339 340define i64 @bexti_i64(i64 %a) nounwind { 341; RV32I-LABEL: bexti_i64: 342; RV32I: # %bb.0: 343; RV32I-NEXT: slli a0, a0, 26 344; RV32I-NEXT: srli a0, a0, 31 345; RV32I-NEXT: li a1, 0 346; RV32I-NEXT: ret 347; 348; RV32ZBS-LABEL: bexti_i64: 349; RV32ZBS: # %bb.0: 350; RV32ZBS-NEXT: bexti a0, a0, 5 351; RV32ZBS-NEXT: li a1, 0 352; RV32ZBS-NEXT: ret 353 %shr = lshr i64 %a, 5 354 %and = and i64 %shr, 1 355 ret i64 %and 356} 357 358define signext i32 @bexti_i32_cmp(i32 signext %a) nounwind { 359; RV32I-LABEL: bexti_i32_cmp: 360; RV32I: # %bb.0: 361; RV32I-NEXT: slli a0, a0, 26 362; RV32I-NEXT: srli a0, a0, 31 363; RV32I-NEXT: ret 364; 365; RV32ZBS-LABEL: bexti_i32_cmp: 366; RV32ZBS: # %bb.0: 367; RV32ZBS-NEXT: bexti a0, a0, 5 368; RV32ZBS-NEXT: ret 369 %and = and i32 %a, 32 370 %cmp = icmp ne i32 %and, 0 371 %zext = zext i1 %cmp to i32 372 ret i32 %zext 373} 374 375define i64 @bexti_i64_cmp(i64 %a) nounwind { 376; RV32I-LABEL: bexti_i64_cmp: 377; RV32I: # %bb.0: 378; RV32I-NEXT: slli a0, a0, 26 379; RV32I-NEXT: srli a0, a0, 31 380; RV32I-NEXT: li a1, 0 381; RV32I-NEXT: ret 382; 383; RV32ZBS-LABEL: bexti_i64_cmp: 384; RV32ZBS: # %bb.0: 385; RV32ZBS-NEXT: bexti a0, a0, 5 386; RV32ZBS-NEXT: li a1, 0 387; RV32ZBS-NEXT: ret 388 %and = and i64 %a, 32 389 %cmp = icmp ne i64 %and, 0 390 %zext = zext i1 %cmp to i64 391 ret i64 %zext 392} 393 394define i32 @bclri_i32_10(i32 %a) nounwind { 395; CHECK-LABEL: bclri_i32_10: 396; CHECK: # %bb.0: 397; CHECK-NEXT: andi a0, a0, -1025 398; CHECK-NEXT: ret 399 %and = and i32 %a, -1025 400 ret i32 %and 401} 402 403define i32 @bclri_i32_11(i32 %a) nounwind { 404; RV32I-LABEL: bclri_i32_11: 405; RV32I: # %bb.0: 406; RV32I-NEXT: lui a1, 1048575 407; RV32I-NEXT: addi a1, a1, 2047 408; RV32I-NEXT: and a0, a0, a1 409; RV32I-NEXT: ret 410; 411; RV32ZBS-LABEL: bclri_i32_11: 412; RV32ZBS: # %bb.0: 413; RV32ZBS-NEXT: bclri a0, a0, 11 414; RV32ZBS-NEXT: ret 415 %and = and i32 %a, -2049 416 ret i32 %and 417} 418 419define i32 @bclri_i32_30(i32 %a) nounwind { 420; RV32I-LABEL: bclri_i32_30: 421; RV32I: # %bb.0: 422; RV32I-NEXT: lui a1, 786432 423; RV32I-NEXT: addi a1, a1, -1 424; RV32I-NEXT: and a0, a0, a1 425; RV32I-NEXT: ret 426; 427; RV32ZBS-LABEL: bclri_i32_30: 428; RV32ZBS: # %bb.0: 429; RV32ZBS-NEXT: bclri a0, a0, 30 430; RV32ZBS-NEXT: ret 431 %and = and i32 %a, -1073741825 432 ret i32 %and 433} 434 435define i32 @bclri_i32_31(i32 %a) nounwind { 436; RV32I-LABEL: bclri_i32_31: 437; RV32I: # %bb.0: 438; RV32I-NEXT: slli a0, a0, 1 439; RV32I-NEXT: srli a0, a0, 1 440; RV32I-NEXT: ret 441; 442; RV32ZBS-LABEL: bclri_i32_31: 443; RV32ZBS: # %bb.0: 444; RV32ZBS-NEXT: bclri a0, a0, 31 445; RV32ZBS-NEXT: ret 446 %and = and i32 %a, -2147483649 447 ret i32 %and 448} 449 450define i32 @bclri_i32_large0(i32 %a) nounwind { 451; RV32I-LABEL: bclri_i32_large0: 452; RV32I: # %bb.0: 453; RV32I-NEXT: lui a1, 1044480 454; RV32I-NEXT: addi a1, a1, -256 455; RV32I-NEXT: and a0, a0, a1 456; RV32I-NEXT: ret 457; 458; RV32ZBS-LABEL: bclri_i32_large0: 459; RV32ZBS: # %bb.0: 460; RV32ZBS-NEXT: andi a0, a0, -256 461; RV32ZBS-NEXT: bclri a0, a0, 24 462; RV32ZBS-NEXT: ret 463 %and = and i32 %a, -16777472 464 ret i32 %and 465} 466 467define i32 @bclri_i32_large1(i32 %a) nounwind { 468; RV32I-LABEL: bclri_i32_large1: 469; RV32I: # %bb.0: 470; RV32I-NEXT: lui a1, 1044464 471; RV32I-NEXT: addi a1, a1, -1 472; RV32I-NEXT: and a0, a0, a1 473; RV32I-NEXT: ret 474; 475; RV32ZBS-LABEL: bclri_i32_large1: 476; RV32ZBS: # %bb.0: 477; RV32ZBS-NEXT: bclri a0, a0, 16 478; RV32ZBS-NEXT: bclri a0, a0, 24 479; RV32ZBS-NEXT: ret 480 %and = and i32 %a, -16842753 481 ret i32 %and 482} 483 484define i32 @bclri_i32_large2(i32 %0) { 485; RV32I-LABEL: bclri_i32_large2: 486; RV32I: # %bb.0: 487; RV32I-NEXT: lui a1, 524288 488; RV32I-NEXT: addi a1, a1, -5 489; RV32I-NEXT: and a0, a0, a1 490; RV32I-NEXT: ret 491; 492; RV32ZBS-LABEL: bclri_i32_large2: 493; RV32ZBS: # %bb.0: 494; RV32ZBS-NEXT: bclri a0, a0, 2 495; RV32ZBS-NEXT: bclri a0, a0, 31 496; RV32ZBS-NEXT: ret 497 %2 = and i32 %0, 2147483643 498 ret i32 %2 499} 500 501define i32 @bclri_i32_large3(i32 %0) { 502; RV32I-LABEL: bclri_i32_large3: 503; RV32I: # %bb.0: 504; RV32I-NEXT: lui a1, 524288 505; RV32I-NEXT: addi a1, a1, -6 506; RV32I-NEXT: and a0, a0, a1 507; RV32I-NEXT: ret 508; 509; RV32ZBS-LABEL: bclri_i32_large3: 510; RV32ZBS: # %bb.0: 511; RV32ZBS-NEXT: andi a0, a0, -6 512; RV32ZBS-NEXT: bclri a0, a0, 31 513; RV32ZBS-NEXT: ret 514 %2 = and i32 %0, 2147483642 515 ret i32 %2 516} 517 518define i32 @bseti_i32_10(i32 %a) nounwind { 519; CHECK-LABEL: bseti_i32_10: 520; CHECK: # %bb.0: 521; CHECK-NEXT: ori a0, a0, 1024 522; CHECK-NEXT: ret 523 %or = or i32 %a, 1024 524 ret i32 %or 525} 526 527define i32 @bseti_i32_11(i32 %a) nounwind { 528; RV32I-LABEL: bseti_i32_11: 529; RV32I: # %bb.0: 530; RV32I-NEXT: li a1, 1 531; RV32I-NEXT: slli a1, a1, 11 532; RV32I-NEXT: or a0, a0, a1 533; RV32I-NEXT: ret 534; 535; RV32ZBS-LABEL: bseti_i32_11: 536; RV32ZBS: # %bb.0: 537; RV32ZBS-NEXT: bseti a0, a0, 11 538; RV32ZBS-NEXT: ret 539 %or = or i32 %a, 2048 540 ret i32 %or 541} 542 543define i32 @bseti_i32_30(i32 %a) nounwind { 544; RV32I-LABEL: bseti_i32_30: 545; RV32I: # %bb.0: 546; RV32I-NEXT: lui a1, 262144 547; RV32I-NEXT: or a0, a0, a1 548; RV32I-NEXT: ret 549; 550; RV32ZBS-LABEL: bseti_i32_30: 551; RV32ZBS: # %bb.0: 552; RV32ZBS-NEXT: bseti a0, a0, 30 553; RV32ZBS-NEXT: ret 554 %or = or i32 %a, 1073741824 555 ret i32 %or 556} 557 558define i32 @bseti_i32_31(i32 %a) nounwind { 559; RV32I-LABEL: bseti_i32_31: 560; RV32I: # %bb.0: 561; RV32I-NEXT: lui a1, 524288 562; RV32I-NEXT: or a0, a0, a1 563; RV32I-NEXT: ret 564; 565; RV32ZBS-LABEL: bseti_i32_31: 566; RV32ZBS: # %bb.0: 567; RV32ZBS-NEXT: bseti a0, a0, 31 568; RV32ZBS-NEXT: ret 569 %or = or i32 %a, 2147483648 570 ret i32 %or 571} 572 573define i32 @binvi_i32_10(i32 %a) nounwind { 574; CHECK-LABEL: binvi_i32_10: 575; CHECK: # %bb.0: 576; CHECK-NEXT: xori a0, a0, 1024 577; CHECK-NEXT: ret 578 %xor = xor i32 %a, 1024 579 ret i32 %xor 580} 581 582define i32 @binvi_i32_11(i32 %a) nounwind { 583; RV32I-LABEL: binvi_i32_11: 584; RV32I: # %bb.0: 585; RV32I-NEXT: li a1, 1 586; RV32I-NEXT: slli a1, a1, 11 587; RV32I-NEXT: xor a0, a0, a1 588; RV32I-NEXT: ret 589; 590; RV32ZBS-LABEL: binvi_i32_11: 591; RV32ZBS: # %bb.0: 592; RV32ZBS-NEXT: binvi a0, a0, 11 593; RV32ZBS-NEXT: ret 594 %xor = xor i32 %a, 2048 595 ret i32 %xor 596} 597 598define i32 @binvi_i32_30(i32 %a) nounwind { 599; RV32I-LABEL: binvi_i32_30: 600; RV32I: # %bb.0: 601; RV32I-NEXT: lui a1, 262144 602; RV32I-NEXT: xor a0, a0, a1 603; RV32I-NEXT: ret 604; 605; RV32ZBS-LABEL: binvi_i32_30: 606; RV32ZBS: # %bb.0: 607; RV32ZBS-NEXT: binvi a0, a0, 30 608; RV32ZBS-NEXT: ret 609 %xor = xor i32 %a, 1073741824 610 ret i32 %xor 611} 612 613define i32 @binvi_i32_31(i32 %a) nounwind { 614; RV32I-LABEL: binvi_i32_31: 615; RV32I: # %bb.0: 616; RV32I-NEXT: lui a1, 524288 617; RV32I-NEXT: xor a0, a0, a1 618; RV32I-NEXT: ret 619; 620; RV32ZBS-LABEL: binvi_i32_31: 621; RV32ZBS: # %bb.0: 622; RV32ZBS-NEXT: binvi a0, a0, 31 623; RV32ZBS-NEXT: ret 624 %xor = xor i32 %a, 2147483648 625 ret i32 %xor 626} 627 628define i32 @xor_i32_4098(i32 %a) nounwind { 629; RV32I-LABEL: xor_i32_4098: 630; RV32I: # %bb.0: 631; RV32I-NEXT: lui a1, 1 632; RV32I-NEXT: addi a1, a1, 2 633; RV32I-NEXT: xor a0, a0, a1 634; RV32I-NEXT: ret 635; 636; RV32ZBS-LABEL: xor_i32_4098: 637; RV32ZBS: # %bb.0: 638; RV32ZBS-NEXT: binvi a0, a0, 1 639; RV32ZBS-NEXT: binvi a0, a0, 12 640; RV32ZBS-NEXT: ret 641 %xor = xor i32 %a, 4098 642 ret i32 %xor 643} 644 645define i32 @xor_i32_4099(i32 %a) nounwind { 646; RV32I-LABEL: xor_i32_4099: 647; RV32I: # %bb.0: 648; RV32I-NEXT: lui a1, 1 649; RV32I-NEXT: addi a1, a1, 3 650; RV32I-NEXT: xor a0, a0, a1 651; RV32I-NEXT: ret 652; 653; RV32ZBS-LABEL: xor_i32_4099: 654; RV32ZBS: # %bb.0: 655; RV32ZBS-NEXT: xori a0, a0, 3 656; RV32ZBS-NEXT: binvi a0, a0, 12 657; RV32ZBS-NEXT: ret 658 %xor = xor i32 %a, 4099 659 ret i32 %xor 660} 661 662define i32 @xor_i32_96(i32 %a) nounwind { 663; CHECK-LABEL: xor_i32_96: 664; CHECK: # %bb.0: 665; CHECK-NEXT: xori a0, a0, 96 666; CHECK-NEXT: ret 667 %xor = xor i32 %a, 96 668 ret i32 %xor 669} 670 671define i32 @xor_i32_66901(i32 %a) nounwind { 672; RV32I-LABEL: xor_i32_66901: 673; RV32I: # %bb.0: 674; RV32I-NEXT: lui a1, 16 675; RV32I-NEXT: addi a1, a1, 1365 676; RV32I-NEXT: xor a0, a0, a1 677; RV32I-NEXT: ret 678; 679; RV32ZBS-LABEL: xor_i32_66901: 680; RV32ZBS: # %bb.0: 681; RV32ZBS-NEXT: xori a0, a0, 1365 682; RV32ZBS-NEXT: binvi a0, a0, 16 683; RV32ZBS-NEXT: ret 684 %xor = xor i32 %a, 66901 685 ret i32 %xor 686} 687 688define i32 @or_i32_4098(i32 %a) nounwind { 689; RV32I-LABEL: or_i32_4098: 690; RV32I: # %bb.0: 691; RV32I-NEXT: lui a1, 1 692; RV32I-NEXT: addi a1, a1, 2 693; RV32I-NEXT: or a0, a0, a1 694; RV32I-NEXT: ret 695; 696; RV32ZBS-LABEL: or_i32_4098: 697; RV32ZBS: # %bb.0: 698; RV32ZBS-NEXT: bseti a0, a0, 1 699; RV32ZBS-NEXT: bseti a0, a0, 12 700; RV32ZBS-NEXT: ret 701 %or = or i32 %a, 4098 702 ret i32 %or 703} 704 705define i32 @or_i32_4099(i32 %a) nounwind { 706; RV32I-LABEL: or_i32_4099: 707; RV32I: # %bb.0: 708; RV32I-NEXT: lui a1, 1 709; RV32I-NEXT: addi a1, a1, 3 710; RV32I-NEXT: or a0, a0, a1 711; RV32I-NEXT: ret 712; 713; RV32ZBS-LABEL: or_i32_4099: 714; RV32ZBS: # %bb.0: 715; RV32ZBS-NEXT: ori a0, a0, 3 716; RV32ZBS-NEXT: bseti a0, a0, 12 717; RV32ZBS-NEXT: ret 718 %or = or i32 %a, 4099 719 ret i32 %or 720} 721 722define i32 @or_i32_96(i32 %a) nounwind { 723; CHECK-LABEL: or_i32_96: 724; CHECK: # %bb.0: 725; CHECK-NEXT: ori a0, a0, 96 726; CHECK-NEXT: ret 727 %or = or i32 %a, 96 728 ret i32 %or 729} 730 731define i32 @or_i32_66901(i32 %a) nounwind { 732; RV32I-LABEL: or_i32_66901: 733; RV32I: # %bb.0: 734; RV32I-NEXT: lui a1, 16 735; RV32I-NEXT: addi a1, a1, 1365 736; RV32I-NEXT: or a0, a0, a1 737; RV32I-NEXT: ret 738; 739; RV32ZBS-LABEL: or_i32_66901: 740; RV32ZBS: # %bb.0: 741; RV32ZBS-NEXT: ori a0, a0, 1365 742; RV32ZBS-NEXT: bseti a0, a0, 16 743; RV32ZBS-NEXT: ret 744 %or = or i32 %a, 66901 745 ret i32 %or 746} 747 748define i32 @bset_trailing_ones_i32_mask(i32 %a) nounwind { 749; RV32I-LABEL: bset_trailing_ones_i32_mask: 750; RV32I: # %bb.0: 751; RV32I-NEXT: li a1, -1 752; RV32I-NEXT: sll a0, a1, a0 753; RV32I-NEXT: not a0, a0 754; RV32I-NEXT: ret 755; 756; RV32ZBS-LABEL: bset_trailing_ones_i32_mask: 757; RV32ZBS: # %bb.0: 758; RV32ZBS-NEXT: bset a0, zero, a0 759; RV32ZBS-NEXT: addi a0, a0, -1 760; RV32ZBS-NEXT: ret 761 %and = and i32 %a, 31 762 %shift = shl nsw i32 -1, %and 763 %not = xor i32 %shift, -1 764 ret i32 %not 765} 766 767define i32 @bset_trailing_ones_i32_no_mask(i32 %a) nounwind { 768; RV32I-LABEL: bset_trailing_ones_i32_no_mask: 769; RV32I: # %bb.0: 770; RV32I-NEXT: li a1, -1 771; RV32I-NEXT: sll a0, a1, a0 772; RV32I-NEXT: not a0, a0 773; RV32I-NEXT: ret 774; 775; RV32ZBS-LABEL: bset_trailing_ones_i32_no_mask: 776; RV32ZBS: # %bb.0: 777; RV32ZBS-NEXT: bset a0, zero, a0 778; RV32ZBS-NEXT: addi a0, a0, -1 779; RV32ZBS-NEXT: ret 780 %shift = shl nsw i32 -1, %a 781 %not = xor i32 %shift, -1 782 ret i32 %not 783} 784 785define i64 @bset_trailing_ones_i64_mask(i64 %a) nounwind { 786; CHECK-LABEL: bset_trailing_ones_i64_mask: 787; CHECK: # %bb.0: 788; CHECK-NEXT: li a2, -1 789; CHECK-NEXT: andi a3, a0, 63 790; CHECK-NEXT: addi a1, a3, -32 791; CHECK-NEXT: sll a0, a2, a0 792; CHECK-NEXT: bltz a1, .LBB43_2 793; CHECK-NEXT: # %bb.1: 794; CHECK-NEXT: sll a2, a2, a3 795; CHECK-NEXT: j .LBB43_3 796; CHECK-NEXT: .LBB43_2: 797; CHECK-NEXT: not a2, a3 798; CHECK-NEXT: lui a3, 524288 799; CHECK-NEXT: addi a3, a3, -1 800; CHECK-NEXT: srl a2, a3, a2 801; CHECK-NEXT: or a2, a0, a2 802; CHECK-NEXT: .LBB43_3: 803; CHECK-NEXT: srai a1, a1, 31 804; CHECK-NEXT: and a0, a1, a0 805; CHECK-NEXT: not a1, a2 806; CHECK-NEXT: not a0, a0 807; CHECK-NEXT: ret 808 %and = and i64 %a, 63 809 %shift = shl nsw i64 -1, %and 810 %not = xor i64 %shift, -1 811 ret i64 %not 812} 813 814define i64 @bset_trailing_ones_i64_no_mask(i64 %a) nounwind { 815; CHECK-LABEL: bset_trailing_ones_i64_no_mask: 816; CHECK: # %bb.0: 817; CHECK-NEXT: li a1, -1 818; CHECK-NEXT: addi a2, a0, -32 819; CHECK-NEXT: sll a1, a1, a0 820; CHECK-NEXT: bltz a2, .LBB44_2 821; CHECK-NEXT: # %bb.1: 822; CHECK-NEXT: mv a0, a1 823; CHECK-NEXT: j .LBB44_3 824; CHECK-NEXT: .LBB44_2: 825; CHECK-NEXT: not a0, a0 826; CHECK-NEXT: lui a3, 524288 827; CHECK-NEXT: addi a3, a3, -1 828; CHECK-NEXT: srl a0, a3, a0 829; CHECK-NEXT: or a0, a1, a0 830; CHECK-NEXT: .LBB44_3: 831; CHECK-NEXT: srai a2, a2, 31 832; CHECK-NEXT: and a2, a2, a1 833; CHECK-NEXT: not a1, a0 834; CHECK-NEXT: not a0, a2 835; CHECK-NEXT: ret 836 %shift = shl nsw i64 -1, %a 837 %not = xor i64 %shift, -1 838 ret i64 %not 839} 840 841define i1 @icmp_eq_pow2(i32 %x) nounwind { 842; RV32I-LABEL: icmp_eq_pow2: 843; RV32I: # %bb.0: 844; RV32I-NEXT: lui a1, 8 845; RV32I-NEXT: xor a0, a0, a1 846; RV32I-NEXT: seqz a0, a0 847; RV32I-NEXT: ret 848; 849; RV32ZBS-LABEL: icmp_eq_pow2: 850; RV32ZBS: # %bb.0: 851; RV32ZBS-NEXT: binvi a0, a0, 15 852; RV32ZBS-NEXT: seqz a0, a0 853; RV32ZBS-NEXT: ret 854 %cmp = icmp eq i32 %x, 32768 855 ret i1 %cmp 856} 857 858define i1 @icmp_ne_pow2(i32 %x) nounwind { 859; RV32I-LABEL: icmp_ne_pow2: 860; RV32I: # %bb.0: 861; RV32I-NEXT: lui a1, 8 862; RV32I-NEXT: xor a0, a0, a1 863; RV32I-NEXT: seqz a0, a0 864; RV32I-NEXT: ret 865; 866; RV32ZBS-LABEL: icmp_ne_pow2: 867; RV32ZBS: # %bb.0: 868; RV32ZBS-NEXT: binvi a0, a0, 15 869; RV32ZBS-NEXT: seqz a0, a0 870; RV32ZBS-NEXT: ret 871 %cmp = icmp eq i32 %x, 32768 872 ret i1 %cmp 873} 874 875define i1 @icmp_eq_nonpow2(i32 %x) nounwind { 876; CHECK-LABEL: icmp_eq_nonpow2: 877; CHECK: # %bb.0: 878; CHECK-NEXT: lui a1, 8 879; CHECK-NEXT: addi a1, a1, -1 880; CHECK-NEXT: xor a0, a0, a1 881; CHECK-NEXT: seqz a0, a0 882; CHECK-NEXT: ret 883 %cmp = icmp eq i32 %x, 32767 884 ret i1 %cmp 885} 886