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,RV32,RV32I 4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefixes=CHECK,RV64,RV64I 6; RUN: llc -mtriple=riscv32 -mattr=+zbs -verify-machineinstrs < %s \ 7; RUN: | FileCheck %s -check-prefixes=CHECK,ZBS,RV32,RV32ZBS 8; RUN: llc -mtriple=riscv64 -mattr=+zbs -verify-machineinstrs < %s \ 9; RUN: | FileCheck %s -check-prefixes=CHECK,ZBS,RV64,RV64ZBS 10 11define signext i32 @bittest_7_i32(i32 signext %a) nounwind { 12; CHECK-LABEL: bittest_7_i32: 13; CHECK: # %bb.0: 14; CHECK-NEXT: andi a0, a0, 128 15; CHECK-NEXT: seqz a0, a0 16; CHECK-NEXT: ret 17 %shr = lshr i32 %a, 7 18 %not = xor i32 %shr, -1 19 %and = and i32 %not, 1 20 ret i32 %and 21} 22 23define signext i32 @bittest_10_i32(i32 signext %a) nounwind { 24; CHECK-LABEL: bittest_10_i32: 25; CHECK: # %bb.0: 26; CHECK-NEXT: andi a0, a0, 1024 27; CHECK-NEXT: seqz a0, a0 28; CHECK-NEXT: ret 29 %shr = lshr i32 %a, 10 30 %not = xor i32 %shr, -1 31 %and = and i32 %not, 1 32 ret i32 %and 33} 34 35define signext i32 @bittest_11_i32(i32 signext %a) nounwind { 36; RV32I-LABEL: bittest_11_i32: 37; RV32I: # %bb.0: 38; RV32I-NEXT: not a0, a0 39; RV32I-NEXT: slli a0, a0, 20 40; RV32I-NEXT: srli a0, a0, 31 41; RV32I-NEXT: ret 42; 43; RV64I-LABEL: bittest_11_i32: 44; RV64I: # %bb.0: 45; RV64I-NEXT: not a0, a0 46; RV64I-NEXT: slli a0, a0, 52 47; RV64I-NEXT: srli a0, a0, 63 48; RV64I-NEXT: ret 49; 50; ZBS-LABEL: bittest_11_i32: 51; ZBS: # %bb.0: 52; ZBS-NEXT: not a0, a0 53; ZBS-NEXT: bexti a0, a0, 11 54; ZBS-NEXT: ret 55 %shr = lshr i32 %a, 11 56 %not = xor i32 %shr, -1 57 %and = and i32 %not, 1 58 ret i32 %and 59} 60 61define signext i32 @bittest_31_i32(i32 signext %a) nounwind { 62; RV32-LABEL: bittest_31_i32: 63; RV32: # %bb.0: 64; RV32-NEXT: not a0, a0 65; RV32-NEXT: srli a0, a0, 31 66; RV32-NEXT: ret 67; 68; RV64-LABEL: bittest_31_i32: 69; RV64: # %bb.0: 70; RV64-NEXT: not a0, a0 71; RV64-NEXT: srliw a0, a0, 31 72; RV64-NEXT: ret 73 %shr = lshr i32 %a, 31 74 %not = xor i32 %shr, -1 75 %and = and i32 %not, 1 76 ret i32 %and 77} 78 79define i64 @bittest_7_i64(i64 %a) nounwind { 80; RV32-LABEL: bittest_7_i64: 81; RV32: # %bb.0: 82; RV32-NEXT: andi a0, a0, 128 83; RV32-NEXT: seqz a0, a0 84; RV32-NEXT: li a1, 0 85; RV32-NEXT: ret 86; 87; RV64-LABEL: bittest_7_i64: 88; RV64: # %bb.0: 89; RV64-NEXT: andi a0, a0, 128 90; RV64-NEXT: seqz a0, a0 91; RV64-NEXT: ret 92 %shr = lshr i64 %a, 7 93 %not = xor i64 %shr, -1 94 %and = and i64 %not, 1 95 ret i64 %and 96} 97 98define i64 @bittest_10_i64(i64 %a) nounwind { 99; RV32-LABEL: bittest_10_i64: 100; RV32: # %bb.0: 101; RV32-NEXT: andi a0, a0, 1024 102; RV32-NEXT: seqz a0, a0 103; RV32-NEXT: li a1, 0 104; RV32-NEXT: ret 105; 106; RV64-LABEL: bittest_10_i64: 107; RV64: # %bb.0: 108; RV64-NEXT: andi a0, a0, 1024 109; RV64-NEXT: seqz a0, a0 110; RV64-NEXT: ret 111 %shr = lshr i64 %a, 10 112 %not = xor i64 %shr, -1 113 %and = and i64 %not, 1 114 ret i64 %and 115} 116 117define i64 @bittest_11_i64(i64 %a) nounwind { 118; RV32I-LABEL: bittest_11_i64: 119; RV32I: # %bb.0: 120; RV32I-NEXT: not a0, a0 121; RV32I-NEXT: slli a0, a0, 20 122; RV32I-NEXT: srli a0, a0, 31 123; RV32I-NEXT: li a1, 0 124; RV32I-NEXT: ret 125; 126; RV64I-LABEL: bittest_11_i64: 127; RV64I: # %bb.0: 128; RV64I-NEXT: not a0, a0 129; RV64I-NEXT: slli a0, a0, 52 130; RV64I-NEXT: srli a0, a0, 63 131; RV64I-NEXT: ret 132; 133; RV32ZBS-LABEL: bittest_11_i64: 134; RV32ZBS: # %bb.0: 135; RV32ZBS-NEXT: not a0, a0 136; RV32ZBS-NEXT: bexti a0, a0, 11 137; RV32ZBS-NEXT: li a1, 0 138; RV32ZBS-NEXT: ret 139; 140; RV64ZBS-LABEL: bittest_11_i64: 141; RV64ZBS: # %bb.0: 142; RV64ZBS-NEXT: not a0, a0 143; RV64ZBS-NEXT: bexti a0, a0, 11 144; RV64ZBS-NEXT: ret 145 %shr = lshr i64 %a, 11 146 %not = xor i64 %shr, -1 147 %and = and i64 %not, 1 148 ret i64 %and 149} 150 151define i64 @bittest_31_i64(i64 %a) nounwind { 152; RV32-LABEL: bittest_31_i64: 153; RV32: # %bb.0: 154; RV32-NEXT: not a0, a0 155; RV32-NEXT: srli a0, a0, 31 156; RV32-NEXT: li a1, 0 157; RV32-NEXT: ret 158; 159; RV64-LABEL: bittest_31_i64: 160; RV64: # %bb.0: 161; RV64-NEXT: not a0, a0 162; RV64-NEXT: srliw a0, a0, 31 163; RV64-NEXT: ret 164 %shr = lshr i64 %a, 31 165 %not = xor i64 %shr, -1 166 %and = and i64 %not, 1 167 ret i64 %and 168} 169 170define i64 @bittest_32_i64(i64 %a) nounwind { 171; RV32-LABEL: bittest_32_i64: 172; RV32: # %bb.0: 173; RV32-NEXT: not a0, a1 174; RV32-NEXT: andi a0, a0, 1 175; RV32-NEXT: li a1, 0 176; RV32-NEXT: ret 177; 178; RV64I-LABEL: bittest_32_i64: 179; RV64I: # %bb.0: 180; RV64I-NEXT: not a0, a0 181; RV64I-NEXT: slli a0, a0, 31 182; RV64I-NEXT: srli a0, a0, 63 183; RV64I-NEXT: ret 184; 185; RV64ZBS-LABEL: bittest_32_i64: 186; RV64ZBS: # %bb.0: 187; RV64ZBS-NEXT: not a0, a0 188; RV64ZBS-NEXT: bexti a0, a0, 32 189; RV64ZBS-NEXT: ret 190 %shr = lshr i64 %a, 32 191 %not = xor i64 %shr, -1 192 %and = and i64 %not, 1 193 ret i64 %and 194} 195 196define i64 @bittest_63_i64(i64 %a) nounwind { 197; RV32-LABEL: bittest_63_i64: 198; RV32: # %bb.0: 199; RV32-NEXT: not a0, a1 200; RV32-NEXT: srli a0, a0, 31 201; RV32-NEXT: li a1, 0 202; RV32-NEXT: ret 203; 204; RV64-LABEL: bittest_63_i64: 205; RV64: # %bb.0: 206; RV64-NEXT: not a0, a0 207; RV64-NEXT: srli a0, a0, 63 208; RV64-NEXT: ret 209 %shr = lshr i64 %a, 63 210 %not = xor i64 %shr, -1 211 %and = and i64 %not, 1 212 ret i64 %and 213} 214 215; Make sure we use (andi (srl X, Y), 1) or bext. 216define i1 @bittest_constant_by_var_shr_i32(i32 signext %b) nounwind { 217; RV32I-LABEL: bittest_constant_by_var_shr_i32: 218; RV32I: # %bb.0: 219; RV32I-NEXT: lui a1, 301408 220; RV32I-NEXT: addi a1, a1, 722 221; RV32I-NEXT: srl a0, a1, a0 222; RV32I-NEXT: andi a0, a0, 1 223; RV32I-NEXT: ret 224; 225; RV64I-LABEL: bittest_constant_by_var_shr_i32: 226; RV64I: # %bb.0: 227; RV64I-NEXT: lui a1, 301408 228; RV64I-NEXT: addiw a1, a1, 722 229; RV64I-NEXT: srlw a0, a1, a0 230; RV64I-NEXT: andi a0, a0, 1 231; RV64I-NEXT: ret 232; 233; RV32ZBS-LABEL: bittest_constant_by_var_shr_i32: 234; RV32ZBS: # %bb.0: 235; RV32ZBS-NEXT: lui a1, 301408 236; RV32ZBS-NEXT: addi a1, a1, 722 237; RV32ZBS-NEXT: bext a0, a1, a0 238; RV32ZBS-NEXT: ret 239; 240; RV64ZBS-LABEL: bittest_constant_by_var_shr_i32: 241; RV64ZBS: # %bb.0: 242; RV64ZBS-NEXT: lui a1, 301408 243; RV64ZBS-NEXT: addiw a1, a1, 722 244; RV64ZBS-NEXT: bext a0, a1, a0 245; RV64ZBS-NEXT: ret 246 %shl = lshr i32 1234567890, %b 247 %and = and i32 %shl, 1 248 %cmp = icmp ne i32 %and, 0 249 ret i1 %cmp 250} 251 252; Make sure we use (andi (srl X, Y), 1) or bext. 253define i1 @bittest_constant_by_var_shl_i32(i32 signext %b) nounwind { 254; RV32I-LABEL: bittest_constant_by_var_shl_i32: 255; RV32I: # %bb.0: 256; RV32I-NEXT: lui a1, 301408 257; RV32I-NEXT: addi a1, a1, 722 258; RV32I-NEXT: srl a0, a1, a0 259; RV32I-NEXT: andi a0, a0, 1 260; RV32I-NEXT: ret 261; 262; RV64I-LABEL: bittest_constant_by_var_shl_i32: 263; RV64I: # %bb.0: 264; RV64I-NEXT: lui a1, 301408 265; RV64I-NEXT: addiw a1, a1, 722 266; RV64I-NEXT: srlw a0, a1, a0 267; RV64I-NEXT: andi a0, a0, 1 268; RV64I-NEXT: ret 269; 270; RV32ZBS-LABEL: bittest_constant_by_var_shl_i32: 271; RV32ZBS: # %bb.0: 272; RV32ZBS-NEXT: lui a1, 301408 273; RV32ZBS-NEXT: addi a1, a1, 722 274; RV32ZBS-NEXT: bext a0, a1, a0 275; RV32ZBS-NEXT: ret 276; 277; RV64ZBS-LABEL: bittest_constant_by_var_shl_i32: 278; RV64ZBS: # %bb.0: 279; RV64ZBS-NEXT: lui a1, 301408 280; RV64ZBS-NEXT: addiw a1, a1, 722 281; RV64ZBS-NEXT: bext a0, a1, a0 282; RV64ZBS-NEXT: ret 283 %shl = shl i32 1, %b 284 %and = and i32 %shl, 1234567890 285 %cmp = icmp ne i32 %and, 0 286 ret i1 %cmp 287} 288 289; Make sure we use (andi (srl X, Y), 1) or bext. 290define i1 @bittest_constant_by_var_shr_i64(i64 %b) nounwind { 291; RV32-LABEL: bittest_constant_by_var_shr_i64: 292; RV32: # %bb.0: 293; RV32-NEXT: addi a1, a0, -32 294; RV32-NEXT: bltz a1, .LBB12_2 295; RV32-NEXT: # %bb.1: 296; RV32-NEXT: andi a0, zero, 1 297; RV32-NEXT: ret 298; RV32-NEXT: .LBB12_2: 299; RV32-NEXT: lui a1, 301408 300; RV32-NEXT: addi a1, a1, 722 301; RV32-NEXT: srl a0, a1, a0 302; RV32-NEXT: andi a0, a0, 1 303; RV32-NEXT: ret 304; 305; RV64I-LABEL: bittest_constant_by_var_shr_i64: 306; RV64I: # %bb.0: 307; RV64I-NEXT: lui a1, 301408 308; RV64I-NEXT: addiw a1, a1, 722 309; RV64I-NEXT: srl a0, a1, a0 310; RV64I-NEXT: andi a0, a0, 1 311; RV64I-NEXT: ret 312; 313; RV64ZBS-LABEL: bittest_constant_by_var_shr_i64: 314; RV64ZBS: # %bb.0: 315; RV64ZBS-NEXT: lui a1, 301408 316; RV64ZBS-NEXT: addiw a1, a1, 722 317; RV64ZBS-NEXT: bext a0, a1, a0 318; RV64ZBS-NEXT: ret 319 %shl = lshr i64 1234567890, %b 320 %and = and i64 %shl, 1 321 %cmp = icmp ne i64 %and, 0 322 ret i1 %cmp 323} 324 325; Make sure we use (andi (srl X, Y), 1) or bext. 326define i1 @bittest_constant_by_var_shl_i64(i64 %b) nounwind { 327; RV32-LABEL: bittest_constant_by_var_shl_i64: 328; RV32: # %bb.0: 329; RV32-NEXT: addi a1, a0, -32 330; RV32-NEXT: bltz a1, .LBB13_2 331; RV32-NEXT: # %bb.1: 332; RV32-NEXT: andi a0, zero, 1 333; RV32-NEXT: ret 334; RV32-NEXT: .LBB13_2: 335; RV32-NEXT: lui a1, 301408 336; RV32-NEXT: addi a1, a1, 722 337; RV32-NEXT: srl a0, a1, a0 338; RV32-NEXT: andi a0, a0, 1 339; RV32-NEXT: ret 340; 341; RV64I-LABEL: bittest_constant_by_var_shl_i64: 342; RV64I: # %bb.0: 343; RV64I-NEXT: lui a1, 301408 344; RV64I-NEXT: addiw a1, a1, 722 345; RV64I-NEXT: srl a0, a1, a0 346; RV64I-NEXT: andi a0, a0, 1 347; RV64I-NEXT: ret 348; 349; RV64ZBS-LABEL: bittest_constant_by_var_shl_i64: 350; RV64ZBS: # %bb.0: 351; RV64ZBS-NEXT: lui a1, 301408 352; RV64ZBS-NEXT: addiw a1, a1, 722 353; RV64ZBS-NEXT: bext a0, a1, a0 354; RV64ZBS-NEXT: ret 355 %shl = shl i64 1, %b 356 %and = and i64 %shl, 1234567890 357 %cmp = icmp ne i64 %and, 0 358 ret i1 %cmp 359} 360 361; We want to use (andi (srl X, Y), 1) or bext before the beqz. 362define void @bittest_switch(i32 signext %0) { 363; RV32I-LABEL: bittest_switch: 364; RV32I: # %bb.0: 365; RV32I-NEXT: li a1, 31 366; RV32I-NEXT: bltu a1, a0, .LBB14_3 367; RV32I-NEXT: # %bb.1: 368; RV32I-NEXT: lui a1, 524291 369; RV32I-NEXT: addi a1, a1, 768 370; RV32I-NEXT: srl a0, a1, a0 371; RV32I-NEXT: andi a0, a0, 1 372; RV32I-NEXT: beqz a0, .LBB14_3 373; RV32I-NEXT: # %bb.2: 374; RV32I-NEXT: tail bar@plt 375; RV32I-NEXT: .LBB14_3: 376; RV32I-NEXT: ret 377; 378; RV64I-LABEL: bittest_switch: 379; RV64I: # %bb.0: 380; RV64I-NEXT: li a1, 31 381; RV64I-NEXT: bltu a1, a0, .LBB14_3 382; RV64I-NEXT: # %bb.1: 383; RV64I-NEXT: lui a1, 2048 384; RV64I-NEXT: addiw a1, a1, 51 385; RV64I-NEXT: slli a1, a1, 8 386; RV64I-NEXT: srl a0, a1, a0 387; RV64I-NEXT: andi a0, a0, 1 388; RV64I-NEXT: beqz a0, .LBB14_3 389; RV64I-NEXT: # %bb.2: 390; RV64I-NEXT: tail bar@plt 391; RV64I-NEXT: .LBB14_3: 392; RV64I-NEXT: ret 393; 394; RV32ZBS-LABEL: bittest_switch: 395; RV32ZBS: # %bb.0: 396; RV32ZBS-NEXT: li a1, 31 397; RV32ZBS-NEXT: bltu a1, a0, .LBB14_3 398; RV32ZBS-NEXT: # %bb.1: 399; RV32ZBS-NEXT: lui a1, 524291 400; RV32ZBS-NEXT: addi a1, a1, 768 401; RV32ZBS-NEXT: bext a0, a1, a0 402; RV32ZBS-NEXT: beqz a0, .LBB14_3 403; RV32ZBS-NEXT: # %bb.2: 404; RV32ZBS-NEXT: tail bar@plt 405; RV32ZBS-NEXT: .LBB14_3: 406; RV32ZBS-NEXT: ret 407; 408; RV64ZBS-LABEL: bittest_switch: 409; RV64ZBS: # %bb.0: 410; RV64ZBS-NEXT: li a1, 31 411; RV64ZBS-NEXT: bltu a1, a0, .LBB14_3 412; RV64ZBS-NEXT: # %bb.1: 413; RV64ZBS-NEXT: lui a1, 2048 414; RV64ZBS-NEXT: addiw a1, a1, 51 415; RV64ZBS-NEXT: slli a1, a1, 8 416; RV64ZBS-NEXT: bext a0, a1, a0 417; RV64ZBS-NEXT: beqz a0, .LBB14_3 418; RV64ZBS-NEXT: # %bb.2: 419; RV64ZBS-NEXT: tail bar@plt 420; RV64ZBS-NEXT: .LBB14_3: 421; RV64ZBS-NEXT: ret 422 switch i32 %0, label %3 [ 423 i32 8, label %2 424 i32 9, label %2 425 i32 12, label %2 426 i32 13, label %2 427 i32 31, label %2 428 ] 429 4302: 431 tail call void @bar() 432 br label %3 433 4343: 435 ret void 436} 437 438declare void @bar() 439