1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV64I 4; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64ZBB 6 7declare i32 @llvm.ctlz.i32(i32, i1) 8 9define signext i32 @ctlz_i32(i32 signext %a) nounwind { 10; RV64I-LABEL: ctlz_i32: 11; RV64I: # %bb.0: 12; RV64I-NEXT: beqz a0, .LBB0_2 13; RV64I-NEXT: # %bb.1: # %cond.false 14; RV64I-NEXT: srliw a1, a0, 1 15; RV64I-NEXT: lui a2, 349525 16; RV64I-NEXT: or a0, a0, a1 17; RV64I-NEXT: addiw a1, a2, 1365 18; RV64I-NEXT: srliw a2, a0, 2 19; RV64I-NEXT: or a0, a0, a2 20; RV64I-NEXT: srliw a2, a0, 4 21; RV64I-NEXT: or a0, a0, a2 22; RV64I-NEXT: srliw a2, a0, 8 23; RV64I-NEXT: or a0, a0, a2 24; RV64I-NEXT: srliw a2, a0, 16 25; RV64I-NEXT: or a0, a0, a2 26; RV64I-NEXT: not a0, a0 27; RV64I-NEXT: srli a2, a0, 1 28; RV64I-NEXT: and a1, a2, a1 29; RV64I-NEXT: lui a2, 209715 30; RV64I-NEXT: addiw a2, a2, 819 31; RV64I-NEXT: sub a0, a0, a1 32; RV64I-NEXT: and a1, a0, a2 33; RV64I-NEXT: srli a0, a0, 2 34; RV64I-NEXT: and a0, a0, a2 35; RV64I-NEXT: lui a2, 61681 36; RV64I-NEXT: add a0, a1, a0 37; RV64I-NEXT: srli a1, a0, 4 38; RV64I-NEXT: add a0, a0, a1 39; RV64I-NEXT: addi a1, a2, -241 40; RV64I-NEXT: and a0, a0, a1 41; RV64I-NEXT: slli a1, a0, 8 42; RV64I-NEXT: add a0, a0, a1 43; RV64I-NEXT: slli a1, a0, 16 44; RV64I-NEXT: add a0, a0, a1 45; RV64I-NEXT: srliw a0, a0, 24 46; RV64I-NEXT: ret 47; RV64I-NEXT: .LBB0_2: 48; RV64I-NEXT: li a0, 32 49; RV64I-NEXT: ret 50; 51; RV64ZBB-LABEL: ctlz_i32: 52; RV64ZBB: # %bb.0: 53; RV64ZBB-NEXT: clzw a0, a0 54; RV64ZBB-NEXT: ret 55 %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 false) 56 ret i32 %1 57} 58 59define signext i32 @log2_i32(i32 signext %a) nounwind { 60; RV64I-LABEL: log2_i32: 61; RV64I: # %bb.0: 62; RV64I-NEXT: beqz a0, .LBB1_2 63; RV64I-NEXT: # %bb.1: # %cond.false 64; RV64I-NEXT: srliw a1, a0, 1 65; RV64I-NEXT: lui a2, 349525 66; RV64I-NEXT: or a0, a0, a1 67; RV64I-NEXT: addiw a1, a2, 1365 68; RV64I-NEXT: srliw a2, a0, 2 69; RV64I-NEXT: or a0, a0, a2 70; RV64I-NEXT: srliw a2, a0, 4 71; RV64I-NEXT: or a0, a0, a2 72; RV64I-NEXT: srliw a2, a0, 8 73; RV64I-NEXT: or a0, a0, a2 74; RV64I-NEXT: srliw a2, a0, 16 75; RV64I-NEXT: or a0, a0, a2 76; RV64I-NEXT: not a0, a0 77; RV64I-NEXT: srli a2, a0, 1 78; RV64I-NEXT: and a1, a2, a1 79; RV64I-NEXT: lui a2, 209715 80; RV64I-NEXT: addiw a2, a2, 819 81; RV64I-NEXT: sub a0, a0, a1 82; RV64I-NEXT: and a1, a0, a2 83; RV64I-NEXT: srli a0, a0, 2 84; RV64I-NEXT: and a0, a0, a2 85; RV64I-NEXT: lui a2, 61681 86; RV64I-NEXT: add a0, a1, a0 87; RV64I-NEXT: srli a1, a0, 4 88; RV64I-NEXT: add a0, a0, a1 89; RV64I-NEXT: addi a1, a2, -241 90; RV64I-NEXT: and a0, a0, a1 91; RV64I-NEXT: slli a1, a0, 8 92; RV64I-NEXT: add a0, a0, a1 93; RV64I-NEXT: slli a1, a0, 16 94; RV64I-NEXT: add a0, a0, a1 95; RV64I-NEXT: srliw a0, a0, 24 96; RV64I-NEXT: j .LBB1_3 97; RV64I-NEXT: .LBB1_2: 98; RV64I-NEXT: li a0, 32 99; RV64I-NEXT: .LBB1_3: # %cond.end 100; RV64I-NEXT: li a1, 31 101; RV64I-NEXT: sub a0, a1, a0 102; RV64I-NEXT: ret 103; 104; RV64ZBB-LABEL: log2_i32: 105; RV64ZBB: # %bb.0: 106; RV64ZBB-NEXT: clzw a0, a0 107; RV64ZBB-NEXT: li a1, 31 108; RV64ZBB-NEXT: sub a0, a1, a0 109; RV64ZBB-NEXT: ret 110 %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 false) 111 %2 = sub i32 31, %1 112 ret i32 %2 113} 114 115define signext i32 @log2_ceil_i32(i32 signext %a) nounwind { 116; RV64I-LABEL: log2_ceil_i32: 117; RV64I: # %bb.0: 118; RV64I-NEXT: addiw a1, a0, -1 119; RV64I-NEXT: li a0, 32 120; RV64I-NEXT: li a2, 32 121; RV64I-NEXT: beqz a1, .LBB2_2 122; RV64I-NEXT: # %bb.1: # %cond.false 123; RV64I-NEXT: srliw a2, a1, 1 124; RV64I-NEXT: lui a3, 349525 125; RV64I-NEXT: or a1, a1, a2 126; RV64I-NEXT: addiw a2, a3, 1365 127; RV64I-NEXT: srliw a3, a1, 2 128; RV64I-NEXT: or a1, a1, a3 129; RV64I-NEXT: srliw a3, a1, 4 130; RV64I-NEXT: or a1, a1, a3 131; RV64I-NEXT: srliw a3, a1, 8 132; RV64I-NEXT: or a1, a1, a3 133; RV64I-NEXT: srliw a3, a1, 16 134; RV64I-NEXT: or a1, a1, a3 135; RV64I-NEXT: not a1, a1 136; RV64I-NEXT: srli a3, a1, 1 137; RV64I-NEXT: and a2, a3, a2 138; RV64I-NEXT: lui a3, 209715 139; RV64I-NEXT: addiw a3, a3, 819 140; RV64I-NEXT: sub a1, a1, a2 141; RV64I-NEXT: and a2, a1, a3 142; RV64I-NEXT: srli a1, a1, 2 143; RV64I-NEXT: and a1, a1, a3 144; RV64I-NEXT: lui a3, 61681 145; RV64I-NEXT: add a1, a2, a1 146; RV64I-NEXT: srli a2, a1, 4 147; RV64I-NEXT: add a1, a1, a2 148; RV64I-NEXT: addi a2, a3, -241 149; RV64I-NEXT: and a1, a1, a2 150; RV64I-NEXT: slli a2, a1, 8 151; RV64I-NEXT: add a1, a1, a2 152; RV64I-NEXT: slli a2, a1, 16 153; RV64I-NEXT: add a1, a1, a2 154; RV64I-NEXT: srliw a2, a1, 24 155; RV64I-NEXT: .LBB2_2: # %cond.end 156; RV64I-NEXT: sub a0, a0, a2 157; RV64I-NEXT: ret 158; 159; RV64ZBB-LABEL: log2_ceil_i32: 160; RV64ZBB: # %bb.0: 161; RV64ZBB-NEXT: addi a0, a0, -1 162; RV64ZBB-NEXT: clzw a0, a0 163; RV64ZBB-NEXT: li a1, 32 164; RV64ZBB-NEXT: sub a0, a1, a0 165; RV64ZBB-NEXT: ret 166 %1 = sub i32 %a, 1 167 %2 = call i32 @llvm.ctlz.i32(i32 %1, i1 false) 168 %3 = sub i32 32, %2 169 ret i32 %3 170} 171 172define signext i32 @findLastSet_i32(i32 signext %a) nounwind { 173; RV64I-LABEL: findLastSet_i32: 174; RV64I: # %bb.0: 175; RV64I-NEXT: srliw a1, a0, 1 176; RV64I-NEXT: lui a2, 349525 177; RV64I-NEXT: or a1, a0, a1 178; RV64I-NEXT: addiw a2, a2, 1365 179; RV64I-NEXT: srliw a3, a1, 2 180; RV64I-NEXT: or a1, a1, a3 181; RV64I-NEXT: srliw a3, a1, 4 182; RV64I-NEXT: or a1, a1, a3 183; RV64I-NEXT: srliw a3, a1, 8 184; RV64I-NEXT: or a1, a1, a3 185; RV64I-NEXT: srliw a3, a1, 16 186; RV64I-NEXT: or a1, a1, a3 187; RV64I-NEXT: not a1, a1 188; RV64I-NEXT: srli a3, a1, 1 189; RV64I-NEXT: and a2, a3, a2 190; RV64I-NEXT: lui a3, 209715 191; RV64I-NEXT: addiw a3, a3, 819 192; RV64I-NEXT: sub a1, a1, a2 193; RV64I-NEXT: and a2, a1, a3 194; RV64I-NEXT: srli a1, a1, 2 195; RV64I-NEXT: and a1, a1, a3 196; RV64I-NEXT: lui a3, 61681 197; RV64I-NEXT: snez a0, a0 198; RV64I-NEXT: addi a3, a3, -241 199; RV64I-NEXT: add a1, a2, a1 200; RV64I-NEXT: srli a2, a1, 4 201; RV64I-NEXT: add a1, a1, a2 202; RV64I-NEXT: and a1, a1, a3 203; RV64I-NEXT: slli a2, a1, 8 204; RV64I-NEXT: add a1, a1, a2 205; RV64I-NEXT: slli a2, a1, 16 206; RV64I-NEXT: add a1, a1, a2 207; RV64I-NEXT: srliw a1, a1, 24 208; RV64I-NEXT: xori a1, a1, 31 209; RV64I-NEXT: addi a0, a0, -1 210; RV64I-NEXT: or a0, a0, a1 211; RV64I-NEXT: ret 212; 213; RV64ZBB-LABEL: findLastSet_i32: 214; RV64ZBB: # %bb.0: 215; RV64ZBB-NEXT: clzw a1, a0 216; RV64ZBB-NEXT: snez a0, a0 217; RV64ZBB-NEXT: xori a1, a1, 31 218; RV64ZBB-NEXT: addi a0, a0, -1 219; RV64ZBB-NEXT: or a0, a0, a1 220; RV64ZBB-NEXT: ret 221 %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 true) 222 %2 = xor i32 31, %1 223 %3 = icmp eq i32 %a, 0 224 %4 = select i1 %3, i32 -1, i32 %2 225 ret i32 %4 226} 227 228define i32 @ctlz_lshr_i32(i32 signext %a) { 229; RV64I-LABEL: ctlz_lshr_i32: 230; RV64I: # %bb.0: 231; RV64I-NEXT: srliw a0, a0, 1 232; RV64I-NEXT: beqz a0, .LBB4_2 233; RV64I-NEXT: # %bb.1: # %cond.false 234; RV64I-NEXT: srliw a1, a0, 1 235; RV64I-NEXT: lui a2, 349525 236; RV64I-NEXT: or a0, a0, a1 237; RV64I-NEXT: addiw a1, a2, 1365 238; RV64I-NEXT: srliw a2, a0, 2 239; RV64I-NEXT: or a0, a0, a2 240; RV64I-NEXT: srliw a2, a0, 4 241; RV64I-NEXT: or a0, a0, a2 242; RV64I-NEXT: srliw a2, a0, 8 243; RV64I-NEXT: or a0, a0, a2 244; RV64I-NEXT: srliw a2, a0, 16 245; RV64I-NEXT: or a0, a0, a2 246; RV64I-NEXT: not a0, a0 247; RV64I-NEXT: srli a2, a0, 1 248; RV64I-NEXT: and a1, a2, a1 249; RV64I-NEXT: lui a2, 209715 250; RV64I-NEXT: addiw a2, a2, 819 251; RV64I-NEXT: sub a0, a0, a1 252; RV64I-NEXT: and a1, a0, a2 253; RV64I-NEXT: srli a0, a0, 2 254; RV64I-NEXT: and a0, a0, a2 255; RV64I-NEXT: lui a2, 61681 256; RV64I-NEXT: add a0, a1, a0 257; RV64I-NEXT: srli a1, a0, 4 258; RV64I-NEXT: add a0, a0, a1 259; RV64I-NEXT: addi a1, a2, -241 260; RV64I-NEXT: and a0, a0, a1 261; RV64I-NEXT: slli a1, a0, 8 262; RV64I-NEXT: add a0, a0, a1 263; RV64I-NEXT: slli a1, a0, 16 264; RV64I-NEXT: add a0, a0, a1 265; RV64I-NEXT: srliw a0, a0, 24 266; RV64I-NEXT: ret 267; RV64I-NEXT: .LBB4_2: 268; RV64I-NEXT: li a0, 32 269; RV64I-NEXT: ret 270; 271; RV64ZBB-LABEL: ctlz_lshr_i32: 272; RV64ZBB: # %bb.0: 273; RV64ZBB-NEXT: srliw a0, a0, 1 274; RV64ZBB-NEXT: clzw a0, a0 275; RV64ZBB-NEXT: ret 276 %1 = lshr i32 %a, 1 277 %2 = call i32 @llvm.ctlz.i32(i32 %1, i1 false) 278 ret i32 %2 279} 280 281declare i64 @llvm.ctlz.i64(i64, i1) 282 283define i64 @ctlz_i64(i64 %a) nounwind { 284; RV64I-LABEL: ctlz_i64: 285; RV64I: # %bb.0: 286; RV64I-NEXT: beqz a0, .LBB5_2 287; RV64I-NEXT: # %bb.1: # %cond.false 288; RV64I-NEXT: srli a1, a0, 1 289; RV64I-NEXT: lui a2, 349525 290; RV64I-NEXT: lui a3, 209715 291; RV64I-NEXT: or a0, a0, a1 292; RV64I-NEXT: addiw a1, a2, 1365 293; RV64I-NEXT: addiw a2, a3, 819 294; RV64I-NEXT: srli a3, a0, 2 295; RV64I-NEXT: or a0, a0, a3 296; RV64I-NEXT: slli a3, a1, 32 297; RV64I-NEXT: add a1, a1, a3 298; RV64I-NEXT: slli a3, a2, 32 299; RV64I-NEXT: add a2, a2, a3 300; RV64I-NEXT: srli a3, a0, 4 301; RV64I-NEXT: or a0, a0, a3 302; RV64I-NEXT: srli a3, a0, 8 303; RV64I-NEXT: or a0, a0, a3 304; RV64I-NEXT: srli a3, a0, 16 305; RV64I-NEXT: or a0, a0, a3 306; RV64I-NEXT: srli a3, a0, 32 307; RV64I-NEXT: or a0, a0, a3 308; RV64I-NEXT: not a0, a0 309; RV64I-NEXT: srli a3, a0, 1 310; RV64I-NEXT: and a1, a3, a1 311; RV64I-NEXT: lui a3, 61681 312; RV64I-NEXT: addiw a3, a3, -241 313; RV64I-NEXT: sub a0, a0, a1 314; RV64I-NEXT: and a1, a0, a2 315; RV64I-NEXT: srli a0, a0, 2 316; RV64I-NEXT: and a0, a0, a2 317; RV64I-NEXT: slli a2, a3, 32 318; RV64I-NEXT: add a0, a1, a0 319; RV64I-NEXT: srli a1, a0, 4 320; RV64I-NEXT: add a0, a0, a1 321; RV64I-NEXT: add a2, a3, a2 322; RV64I-NEXT: and a0, a0, a2 323; RV64I-NEXT: slli a1, a0, 8 324; RV64I-NEXT: add a0, a0, a1 325; RV64I-NEXT: slli a1, a0, 16 326; RV64I-NEXT: add a0, a0, a1 327; RV64I-NEXT: slli a1, a0, 32 328; RV64I-NEXT: add a0, a0, a1 329; RV64I-NEXT: srli a0, a0, 56 330; RV64I-NEXT: ret 331; RV64I-NEXT: .LBB5_2: 332; RV64I-NEXT: li a0, 64 333; RV64I-NEXT: ret 334; 335; RV64ZBB-LABEL: ctlz_i64: 336; RV64ZBB: # %bb.0: 337; RV64ZBB-NEXT: clz a0, a0 338; RV64ZBB-NEXT: ret 339 %1 = call i64 @llvm.ctlz.i64(i64 %a, i1 false) 340 ret i64 %1 341} 342 343declare i32 @llvm.cttz.i32(i32, i1) 344 345define signext i32 @cttz_i32(i32 signext %a) nounwind { 346; RV64I-LABEL: cttz_i32: 347; RV64I: # %bb.0: 348; RV64I-NEXT: beqz a0, .LBB6_2 349; RV64I-NEXT: # %bb.1: # %cond.false 350; RV64I-NEXT: addi sp, sp, -16 351; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 352; RV64I-NEXT: neg a1, a0 353; RV64I-NEXT: and a0, a0, a1 354; RV64I-NEXT: lui a1, 30667 355; RV64I-NEXT: addiw a1, a1, 1329 356; RV64I-NEXT: call __muldi3 357; RV64I-NEXT: srliw a0, a0, 27 358; RV64I-NEXT: lui a1, %hi(.LCPI6_0) 359; RV64I-NEXT: addi a1, a1, %lo(.LCPI6_0) 360; RV64I-NEXT: add a0, a1, a0 361; RV64I-NEXT: lbu a0, 0(a0) 362; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 363; RV64I-NEXT: addi sp, sp, 16 364; RV64I-NEXT: ret 365; RV64I-NEXT: .LBB6_2: 366; RV64I-NEXT: li a0, 32 367; RV64I-NEXT: ret 368; 369; RV64ZBB-LABEL: cttz_i32: 370; RV64ZBB: # %bb.0: 371; RV64ZBB-NEXT: ctzw a0, a0 372; RV64ZBB-NEXT: ret 373 %1 = call i32 @llvm.cttz.i32(i32 %a, i1 false) 374 ret i32 %1 375} 376 377define signext i32 @cttz_zero_undef_i32(i32 signext %a) nounwind { 378; RV64I-LABEL: cttz_zero_undef_i32: 379; RV64I: # %bb.0: 380; RV64I-NEXT: addi sp, sp, -16 381; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 382; RV64I-NEXT: neg a1, a0 383; RV64I-NEXT: and a0, a0, a1 384; RV64I-NEXT: lui a1, 30667 385; RV64I-NEXT: addiw a1, a1, 1329 386; RV64I-NEXT: call __muldi3 387; RV64I-NEXT: srliw a0, a0, 27 388; RV64I-NEXT: lui a1, %hi(.LCPI7_0) 389; RV64I-NEXT: addi a1, a1, %lo(.LCPI7_0) 390; RV64I-NEXT: add a0, a1, a0 391; RV64I-NEXT: lbu a0, 0(a0) 392; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 393; RV64I-NEXT: addi sp, sp, 16 394; RV64I-NEXT: ret 395; 396; RV64ZBB-LABEL: cttz_zero_undef_i32: 397; RV64ZBB: # %bb.0: 398; RV64ZBB-NEXT: ctzw a0, a0 399; RV64ZBB-NEXT: ret 400 %1 = call i32 @llvm.cttz.i32(i32 %a, i1 true) 401 ret i32 %1 402} 403 404define signext i32 @findFirstSet_i32(i32 signext %a) nounwind { 405; RV64I-LABEL: findFirstSet_i32: 406; RV64I: # %bb.0: 407; RV64I-NEXT: addi sp, sp, -16 408; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 409; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 410; RV64I-NEXT: mv s0, a0 411; RV64I-NEXT: neg a0, a0 412; RV64I-NEXT: and a0, s0, a0 413; RV64I-NEXT: lui a1, 30667 414; RV64I-NEXT: addiw a1, a1, 1329 415; RV64I-NEXT: call __muldi3 416; RV64I-NEXT: srliw a0, a0, 27 417; RV64I-NEXT: lui a1, %hi(.LCPI8_0) 418; RV64I-NEXT: addi a1, a1, %lo(.LCPI8_0) 419; RV64I-NEXT: add a0, a1, a0 420; RV64I-NEXT: lbu a0, 0(a0) 421; RV64I-NEXT: snez a1, s0 422; RV64I-NEXT: addi a1, a1, -1 423; RV64I-NEXT: or a0, a1, a0 424; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 425; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 426; RV64I-NEXT: addi sp, sp, 16 427; RV64I-NEXT: ret 428; 429; RV64ZBB-LABEL: findFirstSet_i32: 430; RV64ZBB: # %bb.0: 431; RV64ZBB-NEXT: ctzw a1, a0 432; RV64ZBB-NEXT: snez a0, a0 433; RV64ZBB-NEXT: addi a0, a0, -1 434; RV64ZBB-NEXT: or a0, a0, a1 435; RV64ZBB-NEXT: ret 436 %1 = call i32 @llvm.cttz.i32(i32 %a, i1 true) 437 %2 = icmp eq i32 %a, 0 438 %3 = select i1 %2, i32 -1, i32 %1 439 ret i32 %3 440} 441 442define signext i32 @ffs_i32(i32 signext %a) nounwind { 443; RV64I-LABEL: ffs_i32: 444; RV64I: # %bb.0: 445; RV64I-NEXT: addi sp, sp, -16 446; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 447; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill 448; RV64I-NEXT: mv s0, a0 449; RV64I-NEXT: neg a0, a0 450; RV64I-NEXT: and a0, s0, a0 451; RV64I-NEXT: lui a1, 30667 452; RV64I-NEXT: addiw a1, a1, 1329 453; RV64I-NEXT: call __muldi3 454; RV64I-NEXT: srliw a0, a0, 27 455; RV64I-NEXT: lui a1, %hi(.LCPI9_0) 456; RV64I-NEXT: addi a1, a1, %lo(.LCPI9_0) 457; RV64I-NEXT: add a0, a1, a0 458; RV64I-NEXT: lbu a0, 0(a0) 459; RV64I-NEXT: seqz a1, s0 460; RV64I-NEXT: addi a0, a0, 1 461; RV64I-NEXT: addi a1, a1, -1 462; RV64I-NEXT: and a0, a1, a0 463; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 464; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload 465; RV64I-NEXT: addi sp, sp, 16 466; RV64I-NEXT: ret 467; 468; RV64ZBB-LABEL: ffs_i32: 469; RV64ZBB: # %bb.0: 470; RV64ZBB-NEXT: ctzw a1, a0 471; RV64ZBB-NEXT: seqz a0, a0 472; RV64ZBB-NEXT: addi a1, a1, 1 473; RV64ZBB-NEXT: addi a0, a0, -1 474; RV64ZBB-NEXT: and a0, a0, a1 475; RV64ZBB-NEXT: ret 476 %1 = call i32 @llvm.cttz.i32(i32 %a, i1 true) 477 %2 = add i32 %1, 1 478 %3 = icmp eq i32 %a, 0 479 %4 = select i1 %3, i32 0, i32 %2 480 ret i32 %4 481} 482 483declare i64 @llvm.cttz.i64(i64, i1) 484 485define i64 @cttz_i64(i64 %a) nounwind { 486; RV64I-LABEL: cttz_i64: 487; RV64I: # %bb.0: 488; RV64I-NEXT: beqz a0, .LBB10_2 489; RV64I-NEXT: # %bb.1: # %cond.false 490; RV64I-NEXT: addi sp, sp, -16 491; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 492; RV64I-NEXT: neg a1, a0 493; RV64I-NEXT: and a0, a0, a1 494; RV64I-NEXT: lui a1, %hi(.LCPI10_0) 495; RV64I-NEXT: ld a1, %lo(.LCPI10_0)(a1) 496; RV64I-NEXT: call __muldi3 497; RV64I-NEXT: srli a0, a0, 58 498; RV64I-NEXT: lui a1, %hi(.LCPI10_1) 499; RV64I-NEXT: addi a1, a1, %lo(.LCPI10_1) 500; RV64I-NEXT: add a0, a1, a0 501; RV64I-NEXT: lbu a0, 0(a0) 502; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 503; RV64I-NEXT: addi sp, sp, 16 504; RV64I-NEXT: ret 505; RV64I-NEXT: .LBB10_2: 506; RV64I-NEXT: li a0, 64 507; RV64I-NEXT: ret 508; 509; RV64ZBB-LABEL: cttz_i64: 510; RV64ZBB: # %bb.0: 511; RV64ZBB-NEXT: ctz a0, a0 512; RV64ZBB-NEXT: ret 513 %1 = call i64 @llvm.cttz.i64(i64 %a, i1 false) 514 ret i64 %1 515} 516 517declare i32 @llvm.ctpop.i32(i32) 518 519define signext i32 @ctpop_i32(i32 signext %a) nounwind { 520; RV64I-LABEL: ctpop_i32: 521; RV64I: # %bb.0: 522; RV64I-NEXT: srli a1, a0, 1 523; RV64I-NEXT: lui a2, 349525 524; RV64I-NEXT: addiw a2, a2, 1365 525; RV64I-NEXT: and a1, a1, a2 526; RV64I-NEXT: lui a2, 209715 527; RV64I-NEXT: addiw a2, a2, 819 528; RV64I-NEXT: sub a0, a0, a1 529; RV64I-NEXT: and a1, a0, a2 530; RV64I-NEXT: srli a0, a0, 2 531; RV64I-NEXT: and a0, a0, a2 532; RV64I-NEXT: lui a2, 61681 533; RV64I-NEXT: add a0, a1, a0 534; RV64I-NEXT: srli a1, a0, 4 535; RV64I-NEXT: add a0, a0, a1 536; RV64I-NEXT: addi a1, a2, -241 537; RV64I-NEXT: and a0, a0, a1 538; RV64I-NEXT: slli a1, a0, 8 539; RV64I-NEXT: add a0, a0, a1 540; RV64I-NEXT: slli a1, a0, 16 541; RV64I-NEXT: add a0, a0, a1 542; RV64I-NEXT: srliw a0, a0, 24 543; RV64I-NEXT: ret 544; 545; RV64ZBB-LABEL: ctpop_i32: 546; RV64ZBB: # %bb.0: 547; RV64ZBB-NEXT: cpopw a0, a0 548; RV64ZBB-NEXT: ret 549 %1 = call i32 @llvm.ctpop.i32(i32 %a) 550 ret i32 %1 551} 552 553define i1 @ctpop_i32_ult_two(i32 signext %a) nounwind { 554; RV64I-LABEL: ctpop_i32_ult_two: 555; RV64I: # %bb.0: 556; RV64I-NEXT: addiw a1, a0, -1 557; RV64I-NEXT: and a0, a0, a1 558; RV64I-NEXT: seqz a0, a0 559; RV64I-NEXT: ret 560; 561; RV64ZBB-LABEL: ctpop_i32_ult_two: 562; RV64ZBB: # %bb.0: 563; RV64ZBB-NEXT: cpopw a0, a0 564; RV64ZBB-NEXT: sltiu a0, a0, 2 565; RV64ZBB-NEXT: ret 566 %1 = call i32 @llvm.ctpop.i32(i32 %a) 567 %2 = icmp ult i32 %1, 2 568 ret i1 %2 569} 570 571define i1 @ctpop_i32_ugt_one(i32 signext %a) nounwind { 572; RV64I-LABEL: ctpop_i32_ugt_one: 573; RV64I: # %bb.0: 574; RV64I-NEXT: addiw a1, a0, -1 575; RV64I-NEXT: and a0, a0, a1 576; RV64I-NEXT: snez a0, a0 577; RV64I-NEXT: ret 578; 579; RV64ZBB-LABEL: ctpop_i32_ugt_one: 580; RV64ZBB: # %bb.0: 581; RV64ZBB-NEXT: cpopw a0, a0 582; RV64ZBB-NEXT: sltiu a0, a0, 2 583; RV64ZBB-NEXT: xori a0, a0, 1 584; RV64ZBB-NEXT: ret 585 %1 = call i32 @llvm.ctpop.i32(i32 %a) 586 %2 = icmp ugt i32 %1, 1 587 ret i1 %2 588} 589 590define i1 @ctpop_i32_eq_one(i32 signext %a) nounwind { 591; RV64I-LABEL: ctpop_i32_eq_one: 592; RV64I: # %bb.0: 593; RV64I-NEXT: addiw a1, a0, -1 594; RV64I-NEXT: xor a0, a0, a1 595; RV64I-NEXT: sltu a0, a1, a0 596; RV64I-NEXT: ret 597; 598; RV64ZBB-LABEL: ctpop_i32_eq_one: 599; RV64ZBB: # %bb.0: 600; RV64ZBB-NEXT: cpopw a0, a0 601; RV64ZBB-NEXT: addi a0, a0, -1 602; RV64ZBB-NEXT: seqz a0, a0 603; RV64ZBB-NEXT: ret 604 %1 = call i32 @llvm.ctpop.i32(i32 %a) 605 %2 = icmp eq i32 %1, 1 606 ret i1 %2 607} 608 609define i1 @ctpop_i32_ne_one(i32 signext %a) nounwind { 610; RV64I-LABEL: ctpop_i32_ne_one: 611; RV64I: # %bb.0: 612; RV64I-NEXT: addiw a1, a0, -1 613; RV64I-NEXT: xor a0, a0, a1 614; RV64I-NEXT: sltu a0, a1, a0 615; RV64I-NEXT: xori a0, a0, 1 616; RV64I-NEXT: ret 617; 618; RV64ZBB-LABEL: ctpop_i32_ne_one: 619; RV64ZBB: # %bb.0: 620; RV64ZBB-NEXT: cpopw a0, a0 621; RV64ZBB-NEXT: addi a0, a0, -1 622; RV64ZBB-NEXT: snez a0, a0 623; RV64ZBB-NEXT: ret 624 %1 = call i32 @llvm.ctpop.i32(i32 %a) 625 %2 = icmp ne i32 %1, 1 626 ret i1 %2 627} 628 629define signext i32 @ctpop_i32_load(ptr %p) nounwind { 630; RV64I-LABEL: ctpop_i32_load: 631; RV64I: # %bb.0: 632; RV64I-NEXT: lw a0, 0(a0) 633; RV64I-NEXT: lui a1, 349525 634; RV64I-NEXT: addiw a1, a1, 1365 635; RV64I-NEXT: srli a2, a0, 1 636; RV64I-NEXT: and a1, a2, a1 637; RV64I-NEXT: lui a2, 209715 638; RV64I-NEXT: addiw a2, a2, 819 639; RV64I-NEXT: sub a0, a0, a1 640; RV64I-NEXT: and a1, a0, a2 641; RV64I-NEXT: srli a0, a0, 2 642; RV64I-NEXT: and a0, a0, a2 643; RV64I-NEXT: lui a2, 61681 644; RV64I-NEXT: add a0, a1, a0 645; RV64I-NEXT: srli a1, a0, 4 646; RV64I-NEXT: add a0, a0, a1 647; RV64I-NEXT: addi a1, a2, -241 648; RV64I-NEXT: and a0, a0, a1 649; RV64I-NEXT: slli a1, a0, 8 650; RV64I-NEXT: add a0, a0, a1 651; RV64I-NEXT: slli a1, a0, 16 652; RV64I-NEXT: add a0, a0, a1 653; RV64I-NEXT: srliw a0, a0, 24 654; RV64I-NEXT: ret 655; 656; RV64ZBB-LABEL: ctpop_i32_load: 657; RV64ZBB: # %bb.0: 658; RV64ZBB-NEXT: lwu a0, 0(a0) 659; RV64ZBB-NEXT: cpopw a0, a0 660; RV64ZBB-NEXT: ret 661 %a = load i32, ptr %p 662 %1 = call i32 @llvm.ctpop.i32(i32 %a) 663 ret i32 %1 664} 665 666declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>) 667 668define <2 x i32> @ctpop_v2i32(<2 x i32> %a) nounwind { 669; RV64I-LABEL: ctpop_v2i32: 670; RV64I: # %bb.0: 671; RV64I-NEXT: srli a2, a0, 1 672; RV64I-NEXT: lui a3, 349525 673; RV64I-NEXT: lui a4, 209715 674; RV64I-NEXT: srli a5, a1, 1 675; RV64I-NEXT: addiw a3, a3, 1365 676; RV64I-NEXT: and a2, a2, a3 677; RV64I-NEXT: and a3, a5, a3 678; RV64I-NEXT: lui a5, 61681 679; RV64I-NEXT: addiw a4, a4, 819 680; RV64I-NEXT: addi a5, a5, -241 681; RV64I-NEXT: sub a0, a0, a2 682; RV64I-NEXT: sub a1, a1, a3 683; RV64I-NEXT: and a2, a0, a4 684; RV64I-NEXT: srli a0, a0, 2 685; RV64I-NEXT: and a3, a1, a4 686; RV64I-NEXT: srli a1, a1, 2 687; RV64I-NEXT: and a0, a0, a4 688; RV64I-NEXT: and a1, a1, a4 689; RV64I-NEXT: add a0, a2, a0 690; RV64I-NEXT: add a1, a3, a1 691; RV64I-NEXT: srli a2, a0, 4 692; RV64I-NEXT: srli a3, a1, 4 693; RV64I-NEXT: add a0, a0, a2 694; RV64I-NEXT: add a1, a1, a3 695; RV64I-NEXT: and a0, a0, a5 696; RV64I-NEXT: and a1, a1, a5 697; RV64I-NEXT: slli a2, a0, 8 698; RV64I-NEXT: slli a3, a1, 8 699; RV64I-NEXT: add a0, a0, a2 700; RV64I-NEXT: add a1, a1, a3 701; RV64I-NEXT: slli a2, a0, 16 702; RV64I-NEXT: slli a3, a1, 16 703; RV64I-NEXT: add a0, a0, a2 704; RV64I-NEXT: add a1, a1, a3 705; RV64I-NEXT: srliw a0, a0, 24 706; RV64I-NEXT: srliw a1, a1, 24 707; RV64I-NEXT: ret 708; 709; RV64ZBB-LABEL: ctpop_v2i32: 710; RV64ZBB: # %bb.0: 711; RV64ZBB-NEXT: cpopw a0, a0 712; RV64ZBB-NEXT: cpopw a1, a1 713; RV64ZBB-NEXT: ret 714 %1 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) 715 ret <2 x i32> %1 716} 717 718define <2 x i1> @ctpop_v2i32_ult_two(<2 x i32> %a) nounwind { 719; RV64I-LABEL: ctpop_v2i32_ult_two: 720; RV64I: # %bb.0: 721; RV64I-NEXT: addi a2, a0, -1 722; RV64I-NEXT: and a0, a0, a2 723; RV64I-NEXT: addi a2, a1, -1 724; RV64I-NEXT: and a1, a1, a2 725; RV64I-NEXT: sext.w a0, a0 726; RV64I-NEXT: sext.w a1, a1 727; RV64I-NEXT: seqz a0, a0 728; RV64I-NEXT: seqz a1, a1 729; RV64I-NEXT: ret 730; 731; RV64ZBB-LABEL: ctpop_v2i32_ult_two: 732; RV64ZBB: # %bb.0: 733; RV64ZBB-NEXT: cpopw a1, a1 734; RV64ZBB-NEXT: cpopw a0, a0 735; RV64ZBB-NEXT: sltiu a0, a0, 2 736; RV64ZBB-NEXT: sltiu a1, a1, 2 737; RV64ZBB-NEXT: ret 738 %1 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) 739 %2 = icmp ult <2 x i32> %1, <i32 2, i32 2> 740 ret <2 x i1> %2 741} 742 743define <2 x i1> @ctpop_v2i32_ugt_one(<2 x i32> %a) nounwind { 744; RV64I-LABEL: ctpop_v2i32_ugt_one: 745; RV64I: # %bb.0: 746; RV64I-NEXT: addi a2, a0, -1 747; RV64I-NEXT: and a0, a0, a2 748; RV64I-NEXT: addi a2, a1, -1 749; RV64I-NEXT: and a1, a1, a2 750; RV64I-NEXT: sext.w a0, a0 751; RV64I-NEXT: sext.w a1, a1 752; RV64I-NEXT: snez a0, a0 753; RV64I-NEXT: snez a1, a1 754; RV64I-NEXT: ret 755; 756; RV64ZBB-LABEL: ctpop_v2i32_ugt_one: 757; RV64ZBB: # %bb.0: 758; RV64ZBB-NEXT: cpopw a1, a1 759; RV64ZBB-NEXT: cpopw a0, a0 760; RV64ZBB-NEXT: sltiu a0, a0, 2 761; RV64ZBB-NEXT: sltiu a1, a1, 2 762; RV64ZBB-NEXT: xori a0, a0, 1 763; RV64ZBB-NEXT: xori a1, a1, 1 764; RV64ZBB-NEXT: ret 765 %1 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) 766 %2 = icmp ugt <2 x i32> %1, <i32 1, i32 1> 767 ret <2 x i1> %2 768} 769 770define <2 x i1> @ctpop_v2i32_eq_one(<2 x i32> %a) nounwind { 771; RV64I-LABEL: ctpop_v2i32_eq_one: 772; RV64I: # %bb.0: 773; RV64I-NEXT: addiw a2, a0, -1 774; RV64I-NEXT: xor a0, a0, a2 775; RV64I-NEXT: sext.w a0, a0 776; RV64I-NEXT: sltu a0, a2, a0 777; RV64I-NEXT: addiw a2, a1, -1 778; RV64I-NEXT: xor a1, a1, a2 779; RV64I-NEXT: sext.w a1, a1 780; RV64I-NEXT: sltu a1, a2, a1 781; RV64I-NEXT: ret 782; 783; RV64ZBB-LABEL: ctpop_v2i32_eq_one: 784; RV64ZBB: # %bb.0: 785; RV64ZBB-NEXT: cpopw a1, a1 786; RV64ZBB-NEXT: cpopw a0, a0 787; RV64ZBB-NEXT: addi a0, a0, -1 788; RV64ZBB-NEXT: addi a1, a1, -1 789; RV64ZBB-NEXT: seqz a0, a0 790; RV64ZBB-NEXT: seqz a1, a1 791; RV64ZBB-NEXT: ret 792 %1 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) 793 %2 = icmp eq <2 x i32> %1, <i32 1, i32 1> 794 ret <2 x i1> %2 795} 796 797define <2 x i1> @ctpop_v2i32_ne_one(<2 x i32> %a) nounwind { 798; RV64I-LABEL: ctpop_v2i32_ne_one: 799; RV64I: # %bb.0: 800; RV64I-NEXT: addiw a2, a0, -1 801; RV64I-NEXT: xor a0, a0, a2 802; RV64I-NEXT: sext.w a0, a0 803; RV64I-NEXT: sltu a0, a2, a0 804; RV64I-NEXT: addiw a2, a1, -1 805; RV64I-NEXT: xor a1, a1, a2 806; RV64I-NEXT: sext.w a1, a1 807; RV64I-NEXT: sltu a1, a2, a1 808; RV64I-NEXT: xori a0, a0, 1 809; RV64I-NEXT: xori a1, a1, 1 810; RV64I-NEXT: ret 811; 812; RV64ZBB-LABEL: ctpop_v2i32_ne_one: 813; RV64ZBB: # %bb.0: 814; RV64ZBB-NEXT: cpopw a1, a1 815; RV64ZBB-NEXT: cpopw a0, a0 816; RV64ZBB-NEXT: addi a0, a0, -1 817; RV64ZBB-NEXT: addi a1, a1, -1 818; RV64ZBB-NEXT: snez a0, a0 819; RV64ZBB-NEXT: snez a1, a1 820; RV64ZBB-NEXT: ret 821 %1 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) 822 %2 = icmp ne <2 x i32> %1, <i32 1, i32 1> 823 ret <2 x i1> %2 824} 825 826declare i64 @llvm.ctpop.i64(i64) 827 828define i64 @ctpop_i64(i64 %a) nounwind { 829; RV64I-LABEL: ctpop_i64: 830; RV64I: # %bb.0: 831; RV64I-NEXT: lui a1, 349525 832; RV64I-NEXT: lui a2, 209715 833; RV64I-NEXT: addiw a1, a1, 1365 834; RV64I-NEXT: addiw a2, a2, 819 835; RV64I-NEXT: slli a3, a1, 32 836; RV64I-NEXT: add a1, a1, a3 837; RV64I-NEXT: slli a3, a2, 32 838; RV64I-NEXT: add a2, a2, a3 839; RV64I-NEXT: srli a3, a0, 1 840; RV64I-NEXT: and a1, a3, a1 841; RV64I-NEXT: lui a3, 61681 842; RV64I-NEXT: addiw a3, a3, -241 843; RV64I-NEXT: sub a0, a0, a1 844; RV64I-NEXT: and a1, a0, a2 845; RV64I-NEXT: srli a0, a0, 2 846; RV64I-NEXT: and a0, a0, a2 847; RV64I-NEXT: slli a2, a3, 32 848; RV64I-NEXT: add a0, a1, a0 849; RV64I-NEXT: srli a1, a0, 4 850; RV64I-NEXT: add a0, a0, a1 851; RV64I-NEXT: add a2, a3, a2 852; RV64I-NEXT: and a0, a0, a2 853; RV64I-NEXT: slli a1, a0, 8 854; RV64I-NEXT: add a0, a0, a1 855; RV64I-NEXT: slli a1, a0, 16 856; RV64I-NEXT: add a0, a0, a1 857; RV64I-NEXT: slli a1, a0, 32 858; RV64I-NEXT: add a0, a0, a1 859; RV64I-NEXT: srli a0, a0, 56 860; RV64I-NEXT: ret 861; 862; RV64ZBB-LABEL: ctpop_i64: 863; RV64ZBB: # %bb.0: 864; RV64ZBB-NEXT: cpop a0, a0 865; RV64ZBB-NEXT: ret 866 %1 = call i64 @llvm.ctpop.i64(i64 %a) 867 ret i64 %1 868} 869 870define i1 @ctpop_i64_ugt_two(i64 %a) nounwind { 871; RV64I-LABEL: ctpop_i64_ugt_two: 872; RV64I: # %bb.0: 873; RV64I-NEXT: addi a1, a0, -1 874; RV64I-NEXT: and a0, a0, a1 875; RV64I-NEXT: seqz a0, a0 876; RV64I-NEXT: ret 877; 878; RV64ZBB-LABEL: ctpop_i64_ugt_two: 879; RV64ZBB: # %bb.0: 880; RV64ZBB-NEXT: cpop a0, a0 881; RV64ZBB-NEXT: sltiu a0, a0, 2 882; RV64ZBB-NEXT: ret 883 %1 = call i64 @llvm.ctpop.i64(i64 %a) 884 %2 = icmp ult i64 %1, 2 885 ret i1 %2 886} 887 888define i1 @ctpop_i64_ugt_one(i64 %a) nounwind { 889; RV64I-LABEL: ctpop_i64_ugt_one: 890; RV64I: # %bb.0: 891; RV64I-NEXT: addi a1, a0, -1 892; RV64I-NEXT: and a0, a0, a1 893; RV64I-NEXT: snez a0, a0 894; RV64I-NEXT: ret 895; 896; RV64ZBB-LABEL: ctpop_i64_ugt_one: 897; RV64ZBB: # %bb.0: 898; RV64ZBB-NEXT: cpop a0, a0 899; RV64ZBB-NEXT: sltiu a0, a0, 2 900; RV64ZBB-NEXT: xori a0, a0, 1 901; RV64ZBB-NEXT: ret 902 %1 = call i64 @llvm.ctpop.i64(i64 %a) 903 %2 = icmp ugt i64 %1, 1 904 ret i1 %2 905} 906 907define i1 @ctpop_i64_eq_one(i64 %a) nounwind { 908; RV64I-LABEL: ctpop_i64_eq_one: 909; RV64I: # %bb.0: 910; RV64I-NEXT: addi a1, a0, -1 911; RV64I-NEXT: xor a0, a0, a1 912; RV64I-NEXT: sltu a0, a1, a0 913; RV64I-NEXT: ret 914; 915; RV64ZBB-LABEL: ctpop_i64_eq_one: 916; RV64ZBB: # %bb.0: 917; RV64ZBB-NEXT: cpop a0, a0 918; RV64ZBB-NEXT: addi a0, a0, -1 919; RV64ZBB-NEXT: seqz a0, a0 920; RV64ZBB-NEXT: ret 921 %1 = call i64 @llvm.ctpop.i64(i64 %a) 922 %2 = icmp eq i64 %1, 1 923 ret i1 %2 924} 925 926define i1 @ctpop_i64_ne_one(i64 %a) nounwind { 927; RV64I-LABEL: ctpop_i64_ne_one: 928; RV64I: # %bb.0: 929; RV64I-NEXT: addi a1, a0, -1 930; RV64I-NEXT: xor a0, a0, a1 931; RV64I-NEXT: sltu a0, a1, a0 932; RV64I-NEXT: xori a0, a0, 1 933; RV64I-NEXT: ret 934; 935; RV64ZBB-LABEL: ctpop_i64_ne_one: 936; RV64ZBB: # %bb.0: 937; RV64ZBB-NEXT: cpop a0, a0 938; RV64ZBB-NEXT: addi a0, a0, -1 939; RV64ZBB-NEXT: snez a0, a0 940; RV64ZBB-NEXT: ret 941 %1 = call i64 @llvm.ctpop.i64(i64 %a) 942 %2 = icmp ne i64 %1, 1 943 ret i1 %2 944} 945 946declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) 947 948define <2 x i64> @ctpop_v2i64(<2 x i64> %a) nounwind { 949; RV64I-LABEL: ctpop_v2i64: 950; RV64I: # %bb.0: 951; RV64I-NEXT: srli a2, a0, 1 952; RV64I-NEXT: lui a3, 349525 953; RV64I-NEXT: lui a4, 209715 954; RV64I-NEXT: lui a5, 61681 955; RV64I-NEXT: addiw a3, a3, 1365 956; RV64I-NEXT: addiw a4, a4, 819 957; RV64I-NEXT: addiw a5, a5, -241 958; RV64I-NEXT: slli a6, a3, 32 959; RV64I-NEXT: add a3, a3, a6 960; RV64I-NEXT: slli a6, a4, 32 961; RV64I-NEXT: add a4, a4, a6 962; RV64I-NEXT: slli a6, a5, 32 963; RV64I-NEXT: add a5, a5, a6 964; RV64I-NEXT: srli a6, a1, 1 965; RV64I-NEXT: and a2, a2, a3 966; RV64I-NEXT: and a3, a6, a3 967; RV64I-NEXT: sub a0, a0, a2 968; RV64I-NEXT: sub a1, a1, a3 969; RV64I-NEXT: and a2, a0, a4 970; RV64I-NEXT: srli a0, a0, 2 971; RV64I-NEXT: and a3, a1, a4 972; RV64I-NEXT: srli a1, a1, 2 973; RV64I-NEXT: and a0, a0, a4 974; RV64I-NEXT: and a1, a1, a4 975; RV64I-NEXT: add a0, a2, a0 976; RV64I-NEXT: add a1, a3, a1 977; RV64I-NEXT: srli a2, a0, 4 978; RV64I-NEXT: srli a3, a1, 4 979; RV64I-NEXT: add a0, a0, a2 980; RV64I-NEXT: add a1, a1, a3 981; RV64I-NEXT: and a0, a0, a5 982; RV64I-NEXT: and a1, a1, a5 983; RV64I-NEXT: slli a2, a0, 8 984; RV64I-NEXT: slli a3, a1, 8 985; RV64I-NEXT: add a0, a0, a2 986; RV64I-NEXT: add a1, a1, a3 987; RV64I-NEXT: slli a2, a0, 16 988; RV64I-NEXT: slli a3, a1, 16 989; RV64I-NEXT: add a0, a0, a2 990; RV64I-NEXT: add a1, a1, a3 991; RV64I-NEXT: slli a2, a0, 32 992; RV64I-NEXT: slli a3, a1, 32 993; RV64I-NEXT: add a0, a0, a2 994; RV64I-NEXT: add a1, a1, a3 995; RV64I-NEXT: srli a0, a0, 56 996; RV64I-NEXT: srli a1, a1, 56 997; RV64I-NEXT: ret 998; 999; RV64ZBB-LABEL: ctpop_v2i64: 1000; RV64ZBB: # %bb.0: 1001; RV64ZBB-NEXT: cpop a0, a0 1002; RV64ZBB-NEXT: cpop a1, a1 1003; RV64ZBB-NEXT: ret 1004 %1 = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a) 1005 ret <2 x i64> %1 1006} 1007 1008define <2 x i1> @ctpop_v2i64_ult_two(<2 x i64> %a) nounwind { 1009; RV64I-LABEL: ctpop_v2i64_ult_two: 1010; RV64I: # %bb.0: 1011; RV64I-NEXT: addi a2, a0, -1 1012; RV64I-NEXT: and a0, a0, a2 1013; RV64I-NEXT: addi a2, a1, -1 1014; RV64I-NEXT: and a1, a1, a2 1015; RV64I-NEXT: seqz a0, a0 1016; RV64I-NEXT: seqz a1, a1 1017; RV64I-NEXT: ret 1018; 1019; RV64ZBB-LABEL: ctpop_v2i64_ult_two: 1020; RV64ZBB: # %bb.0: 1021; RV64ZBB-NEXT: cpop a1, a1 1022; RV64ZBB-NEXT: cpop a0, a0 1023; RV64ZBB-NEXT: sltiu a0, a0, 2 1024; RV64ZBB-NEXT: sltiu a1, a1, 2 1025; RV64ZBB-NEXT: ret 1026 %1 = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a) 1027 %2 = icmp ult <2 x i64> %1, <i64 2, i64 2> 1028 ret <2 x i1> %2 1029} 1030 1031define <2 x i1> @ctpop_v2i64_ugt_one(<2 x i64> %a) nounwind { 1032; RV64I-LABEL: ctpop_v2i64_ugt_one: 1033; RV64I: # %bb.0: 1034; RV64I-NEXT: addi a2, a0, -1 1035; RV64I-NEXT: and a0, a0, a2 1036; RV64I-NEXT: addi a2, a1, -1 1037; RV64I-NEXT: and a1, a1, a2 1038; RV64I-NEXT: snez a0, a0 1039; RV64I-NEXT: snez a1, a1 1040; RV64I-NEXT: ret 1041; 1042; RV64ZBB-LABEL: ctpop_v2i64_ugt_one: 1043; RV64ZBB: # %bb.0: 1044; RV64ZBB-NEXT: cpop a1, a1 1045; RV64ZBB-NEXT: cpop a0, a0 1046; RV64ZBB-NEXT: sltiu a0, a0, 2 1047; RV64ZBB-NEXT: sltiu a1, a1, 2 1048; RV64ZBB-NEXT: xori a0, a0, 1 1049; RV64ZBB-NEXT: xori a1, a1, 1 1050; RV64ZBB-NEXT: ret 1051 %1 = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a) 1052 %2 = icmp ugt <2 x i64> %1, <i64 1, i64 1> 1053 ret <2 x i1> %2 1054} 1055 1056define <2 x i1> @ctpop_v2i64_eq_one(<2 x i64> %a) nounwind { 1057; RV64I-LABEL: ctpop_v2i64_eq_one: 1058; RV64I: # %bb.0: 1059; RV64I-NEXT: addi a2, a0, -1 1060; RV64I-NEXT: xor a0, a0, a2 1061; RV64I-NEXT: sltu a0, a2, a0 1062; RV64I-NEXT: addi a2, a1, -1 1063; RV64I-NEXT: xor a1, a1, a2 1064; RV64I-NEXT: sltu a1, a2, a1 1065; RV64I-NEXT: ret 1066; 1067; RV64ZBB-LABEL: ctpop_v2i64_eq_one: 1068; RV64ZBB: # %bb.0: 1069; RV64ZBB-NEXT: cpop a1, a1 1070; RV64ZBB-NEXT: cpop a0, a0 1071; RV64ZBB-NEXT: addi a0, a0, -1 1072; RV64ZBB-NEXT: addi a1, a1, -1 1073; RV64ZBB-NEXT: seqz a0, a0 1074; RV64ZBB-NEXT: seqz a1, a1 1075; RV64ZBB-NEXT: ret 1076 %1 = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a) 1077 %2 = icmp eq <2 x i64> %1, <i64 1, i64 1> 1078 ret <2 x i1> %2 1079} 1080 1081define <2 x i1> @ctpop_v2i64_ne_one(<2 x i64> %a) nounwind { 1082; RV64I-LABEL: ctpop_v2i64_ne_one: 1083; RV64I: # %bb.0: 1084; RV64I-NEXT: addi a2, a0, -1 1085; RV64I-NEXT: xor a0, a0, a2 1086; RV64I-NEXT: sltu a0, a2, a0 1087; RV64I-NEXT: addi a2, a1, -1 1088; RV64I-NEXT: xor a1, a1, a2 1089; RV64I-NEXT: sltu a1, a2, a1 1090; RV64I-NEXT: xori a0, a0, 1 1091; RV64I-NEXT: xori a1, a1, 1 1092; RV64I-NEXT: ret 1093; 1094; RV64ZBB-LABEL: ctpop_v2i64_ne_one: 1095; RV64ZBB: # %bb.0: 1096; RV64ZBB-NEXT: cpop a1, a1 1097; RV64ZBB-NEXT: cpop a0, a0 1098; RV64ZBB-NEXT: addi a0, a0, -1 1099; RV64ZBB-NEXT: addi a1, a1, -1 1100; RV64ZBB-NEXT: snez a0, a0 1101; RV64ZBB-NEXT: snez a1, a1 1102; RV64ZBB-NEXT: ret 1103 %1 = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a) 1104 %2 = icmp ne <2 x i64> %1, <i64 1, i64 1> 1105 ret <2 x i1> %2 1106} 1107 1108define signext i32 @sextb_i32(i32 signext %a) nounwind { 1109; RV64I-LABEL: sextb_i32: 1110; RV64I: # %bb.0: 1111; RV64I-NEXT: slli a0, a0, 56 1112; RV64I-NEXT: srai a0, a0, 56 1113; RV64I-NEXT: ret 1114; 1115; RV64ZBB-LABEL: sextb_i32: 1116; RV64ZBB: # %bb.0: 1117; RV64ZBB-NEXT: sext.b a0, a0 1118; RV64ZBB-NEXT: ret 1119 %shl = shl i32 %a, 24 1120 %shr = ashr exact i32 %shl, 24 1121 ret i32 %shr 1122} 1123 1124define i64 @sextb_i64(i64 %a) nounwind { 1125; RV64I-LABEL: sextb_i64: 1126; RV64I: # %bb.0: 1127; RV64I-NEXT: slli a0, a0, 56 1128; RV64I-NEXT: srai a0, a0, 56 1129; RV64I-NEXT: ret 1130; 1131; RV64ZBB-LABEL: sextb_i64: 1132; RV64ZBB: # %bb.0: 1133; RV64ZBB-NEXT: sext.b a0, a0 1134; RV64ZBB-NEXT: ret 1135 %shl = shl i64 %a, 56 1136 %shr = ashr exact i64 %shl, 56 1137 ret i64 %shr 1138} 1139 1140define signext i32 @sexth_i32(i32 signext %a) nounwind { 1141; RV64I-LABEL: sexth_i32: 1142; RV64I: # %bb.0: 1143; RV64I-NEXT: slli a0, a0, 48 1144; RV64I-NEXT: srai a0, a0, 48 1145; RV64I-NEXT: ret 1146; 1147; RV64ZBB-LABEL: sexth_i32: 1148; RV64ZBB: # %bb.0: 1149; RV64ZBB-NEXT: sext.h a0, a0 1150; RV64ZBB-NEXT: ret 1151 %shl = shl i32 %a, 16 1152 %shr = ashr exact i32 %shl, 16 1153 ret i32 %shr 1154} 1155 1156define i64 @sexth_i64(i64 %a) nounwind { 1157; RV64I-LABEL: sexth_i64: 1158; RV64I: # %bb.0: 1159; RV64I-NEXT: slli a0, a0, 48 1160; RV64I-NEXT: srai a0, a0, 48 1161; RV64I-NEXT: ret 1162; 1163; RV64ZBB-LABEL: sexth_i64: 1164; RV64ZBB: # %bb.0: 1165; RV64ZBB-NEXT: sext.h a0, a0 1166; RV64ZBB-NEXT: ret 1167 %shl = shl i64 %a, 48 1168 %shr = ashr exact i64 %shl, 48 1169 ret i64 %shr 1170} 1171 1172define signext i32 @min_i32(i32 signext %a, i32 signext %b) nounwind { 1173; RV64I-LABEL: min_i32: 1174; RV64I: # %bb.0: 1175; RV64I-NEXT: blt a0, a1, .LBB36_2 1176; RV64I-NEXT: # %bb.1: 1177; RV64I-NEXT: mv a0, a1 1178; RV64I-NEXT: .LBB36_2: 1179; RV64I-NEXT: ret 1180; 1181; RV64ZBB-LABEL: min_i32: 1182; RV64ZBB: # %bb.0: 1183; RV64ZBB-NEXT: min a0, a0, a1 1184; RV64ZBB-NEXT: ret 1185 %cmp = icmp slt i32 %a, %b 1186 %cond = select i1 %cmp, i32 %a, i32 %b 1187 ret i32 %cond 1188} 1189 1190define i64 @min_i64(i64 %a, i64 %b) nounwind { 1191; RV64I-LABEL: min_i64: 1192; RV64I: # %bb.0: 1193; RV64I-NEXT: blt a0, a1, .LBB37_2 1194; RV64I-NEXT: # %bb.1: 1195; RV64I-NEXT: mv a0, a1 1196; RV64I-NEXT: .LBB37_2: 1197; RV64I-NEXT: ret 1198; 1199; RV64ZBB-LABEL: min_i64: 1200; RV64ZBB: # %bb.0: 1201; RV64ZBB-NEXT: min a0, a0, a1 1202; RV64ZBB-NEXT: ret 1203 %cmp = icmp slt i64 %a, %b 1204 %cond = select i1 %cmp, i64 %a, i64 %b 1205 ret i64 %cond 1206} 1207 1208define signext i32 @max_i32(i32 signext %a, i32 signext %b) nounwind { 1209; RV64I-LABEL: max_i32: 1210; RV64I: # %bb.0: 1211; RV64I-NEXT: blt a1, a0, .LBB38_2 1212; RV64I-NEXT: # %bb.1: 1213; RV64I-NEXT: mv a0, a1 1214; RV64I-NEXT: .LBB38_2: 1215; RV64I-NEXT: ret 1216; 1217; RV64ZBB-LABEL: max_i32: 1218; RV64ZBB: # %bb.0: 1219; RV64ZBB-NEXT: max a0, a0, a1 1220; RV64ZBB-NEXT: ret 1221 %cmp = icmp sgt i32 %a, %b 1222 %cond = select i1 %cmp, i32 %a, i32 %b 1223 ret i32 %cond 1224} 1225 1226define i64 @max_i64(i64 %a, i64 %b) nounwind { 1227; RV64I-LABEL: max_i64: 1228; RV64I: # %bb.0: 1229; RV64I-NEXT: blt a1, a0, .LBB39_2 1230; RV64I-NEXT: # %bb.1: 1231; RV64I-NEXT: mv a0, a1 1232; RV64I-NEXT: .LBB39_2: 1233; RV64I-NEXT: ret 1234; 1235; RV64ZBB-LABEL: max_i64: 1236; RV64ZBB: # %bb.0: 1237; RV64ZBB-NEXT: max a0, a0, a1 1238; RV64ZBB-NEXT: ret 1239 %cmp = icmp sgt i64 %a, %b 1240 %cond = select i1 %cmp, i64 %a, i64 %b 1241 ret i64 %cond 1242} 1243 1244define signext i32 @minu_i32(i32 signext %a, i32 signext %b) nounwind { 1245; RV64I-LABEL: minu_i32: 1246; RV64I: # %bb.0: 1247; RV64I-NEXT: bltu a0, a1, .LBB40_2 1248; RV64I-NEXT: # %bb.1: 1249; RV64I-NEXT: mv a0, a1 1250; RV64I-NEXT: .LBB40_2: 1251; RV64I-NEXT: ret 1252; 1253; RV64ZBB-LABEL: minu_i32: 1254; RV64ZBB: # %bb.0: 1255; RV64ZBB-NEXT: minu a0, a0, a1 1256; RV64ZBB-NEXT: ret 1257 %cmp = icmp ult i32 %a, %b 1258 %cond = select i1 %cmp, i32 %a, i32 %b 1259 ret i32 %cond 1260} 1261 1262define i64 @minu_i64(i64 %a, i64 %b) nounwind { 1263; RV64I-LABEL: minu_i64: 1264; RV64I: # %bb.0: 1265; RV64I-NEXT: bltu a0, a1, .LBB41_2 1266; RV64I-NEXT: # %bb.1: 1267; RV64I-NEXT: mv a0, a1 1268; RV64I-NEXT: .LBB41_2: 1269; RV64I-NEXT: ret 1270; 1271; RV64ZBB-LABEL: minu_i64: 1272; RV64ZBB: # %bb.0: 1273; RV64ZBB-NEXT: minu a0, a0, a1 1274; RV64ZBB-NEXT: ret 1275 %cmp = icmp ult i64 %a, %b 1276 %cond = select i1 %cmp, i64 %a, i64 %b 1277 ret i64 %cond 1278} 1279 1280define signext i32 @maxu_i32(i32 signext %a, i32 signext %b) nounwind { 1281; RV64I-LABEL: maxu_i32: 1282; RV64I: # %bb.0: 1283; RV64I-NEXT: bltu a1, a0, .LBB42_2 1284; RV64I-NEXT: # %bb.1: 1285; RV64I-NEXT: mv a0, a1 1286; RV64I-NEXT: .LBB42_2: 1287; RV64I-NEXT: ret 1288; 1289; RV64ZBB-LABEL: maxu_i32: 1290; RV64ZBB: # %bb.0: 1291; RV64ZBB-NEXT: maxu a0, a0, a1 1292; RV64ZBB-NEXT: ret 1293 %cmp = icmp ugt i32 %a, %b 1294 %cond = select i1 %cmp, i32 %a, i32 %b 1295 ret i32 %cond 1296} 1297 1298define i64 @maxu_i64(i64 %a, i64 %b) nounwind { 1299; RV64I-LABEL: maxu_i64: 1300; RV64I: # %bb.0: 1301; RV64I-NEXT: bltu a1, a0, .LBB43_2 1302; RV64I-NEXT: # %bb.1: 1303; RV64I-NEXT: mv a0, a1 1304; RV64I-NEXT: .LBB43_2: 1305; RV64I-NEXT: ret 1306; 1307; RV64ZBB-LABEL: maxu_i64: 1308; RV64ZBB: # %bb.0: 1309; RV64ZBB-NEXT: maxu a0, a0, a1 1310; RV64ZBB-NEXT: ret 1311 %cmp = icmp ugt i64 %a, %b 1312 %cond = select i1 %cmp, i64 %a, i64 %b 1313 ret i64 %cond 1314} 1315 1316declare i32 @llvm.abs.i32(i32, i1 immarg) 1317 1318define i32 @abs_i32(i32 %x) { 1319; RV64I-LABEL: abs_i32: 1320; RV64I: # %bb.0: 1321; RV64I-NEXT: sraiw a1, a0, 31 1322; RV64I-NEXT: xor a0, a0, a1 1323; RV64I-NEXT: subw a0, a0, a1 1324; RV64I-NEXT: ret 1325; 1326; RV64ZBB-LABEL: abs_i32: 1327; RV64ZBB: # %bb.0: 1328; RV64ZBB-NEXT: sext.w a0, a0 1329; RV64ZBB-NEXT: negw a1, a0 1330; RV64ZBB-NEXT: max a0, a0, a1 1331; RV64ZBB-NEXT: ret 1332 %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true) 1333 ret i32 %abs 1334} 1335 1336define signext i32 @abs_i32_sext(i32 signext %x) { 1337; RV64I-LABEL: abs_i32_sext: 1338; RV64I: # %bb.0: 1339; RV64I-NEXT: sraiw a1, a0, 31 1340; RV64I-NEXT: xor a0, a0, a1 1341; RV64I-NEXT: subw a0, a0, a1 1342; RV64I-NEXT: ret 1343; 1344; RV64ZBB-LABEL: abs_i32_sext: 1345; RV64ZBB: # %bb.0: 1346; RV64ZBB-NEXT: negw a1, a0 1347; RV64ZBB-NEXT: max a0, a0, a1 1348; RV64ZBB-NEXT: ret 1349 %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true) 1350 ret i32 %abs 1351} 1352 1353declare i64 @llvm.abs.i64(i64, i1 immarg) 1354 1355define i64 @abs_i64(i64 %x) { 1356; RV64I-LABEL: abs_i64: 1357; RV64I: # %bb.0: 1358; RV64I-NEXT: srai a1, a0, 63 1359; RV64I-NEXT: xor a0, a0, a1 1360; RV64I-NEXT: sub a0, a0, a1 1361; RV64I-NEXT: ret 1362; 1363; RV64ZBB-LABEL: abs_i64: 1364; RV64ZBB: # %bb.0: 1365; RV64ZBB-NEXT: neg a1, a0 1366; RV64ZBB-NEXT: max a0, a0, a1 1367; RV64ZBB-NEXT: ret 1368 %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true) 1369 ret i64 %abs 1370} 1371 1372define i32 @zexth_i32(i32 %a) nounwind { 1373; RV64I-LABEL: zexth_i32: 1374; RV64I: # %bb.0: 1375; RV64I-NEXT: slli a0, a0, 48 1376; RV64I-NEXT: srli a0, a0, 48 1377; RV64I-NEXT: ret 1378; 1379; RV64ZBB-LABEL: zexth_i32: 1380; RV64ZBB: # %bb.0: 1381; RV64ZBB-NEXT: zext.h a0, a0 1382; RV64ZBB-NEXT: ret 1383 %and = and i32 %a, 65535 1384 ret i32 %and 1385} 1386 1387define i64 @zexth_i64(i64 %a) nounwind { 1388; RV64I-LABEL: zexth_i64: 1389; RV64I: # %bb.0: 1390; RV64I-NEXT: slli a0, a0, 48 1391; RV64I-NEXT: srli a0, a0, 48 1392; RV64I-NEXT: ret 1393; 1394; RV64ZBB-LABEL: zexth_i64: 1395; RV64ZBB: # %bb.0: 1396; RV64ZBB-NEXT: zext.h a0, a0 1397; RV64ZBB-NEXT: ret 1398 %and = and i64 %a, 65535 1399 ret i64 %and 1400} 1401 1402declare i32 @llvm.bswap.i32(i32) 1403 1404define signext i32 @bswap_i32(i32 signext %a) nounwind { 1405; RV64I-LABEL: bswap_i32: 1406; RV64I: # %bb.0: 1407; RV64I-NEXT: srli a1, a0, 8 1408; RV64I-NEXT: lui a2, 16 1409; RV64I-NEXT: srliw a3, a0, 24 1410; RV64I-NEXT: addiw a2, a2, -256 1411; RV64I-NEXT: and a1, a1, a2 1412; RV64I-NEXT: and a2, a0, a2 1413; RV64I-NEXT: or a1, a1, a3 1414; RV64I-NEXT: slli a2, a2, 8 1415; RV64I-NEXT: slliw a0, a0, 24 1416; RV64I-NEXT: or a0, a0, a2 1417; RV64I-NEXT: or a0, a0, a1 1418; RV64I-NEXT: ret 1419; 1420; RV64ZBB-LABEL: bswap_i32: 1421; RV64ZBB: # %bb.0: 1422; RV64ZBB-NEXT: rev8 a0, a0 1423; RV64ZBB-NEXT: srai a0, a0, 32 1424; RV64ZBB-NEXT: ret 1425 %1 = tail call i32 @llvm.bswap.i32(i32 %a) 1426 ret i32 %1 1427} 1428 1429; Similar to bswap_i32 but the result is not sign extended. 1430define void @bswap_i32_nosext(i32 signext %a, ptr %x) nounwind { 1431; RV64I-LABEL: bswap_i32_nosext: 1432; RV64I: # %bb.0: 1433; RV64I-NEXT: srli a2, a0, 8 1434; RV64I-NEXT: lui a3, 16 1435; RV64I-NEXT: srliw a4, a0, 24 1436; RV64I-NEXT: addi a3, a3, -256 1437; RV64I-NEXT: and a2, a2, a3 1438; RV64I-NEXT: and a3, a0, a3 1439; RV64I-NEXT: or a2, a2, a4 1440; RV64I-NEXT: slli a3, a3, 8 1441; RV64I-NEXT: slli a0, a0, 24 1442; RV64I-NEXT: or a0, a0, a3 1443; RV64I-NEXT: or a0, a0, a2 1444; RV64I-NEXT: sw a0, 0(a1) 1445; RV64I-NEXT: ret 1446; 1447; RV64ZBB-LABEL: bswap_i32_nosext: 1448; RV64ZBB: # %bb.0: 1449; RV64ZBB-NEXT: rev8 a0, a0 1450; RV64ZBB-NEXT: srli a0, a0, 32 1451; RV64ZBB-NEXT: sw a0, 0(a1) 1452; RV64ZBB-NEXT: ret 1453 %1 = tail call i32 @llvm.bswap.i32(i32 %a) 1454 store i32 %1, ptr %x 1455 ret void 1456} 1457 1458declare i64 @llvm.bswap.i64(i64) 1459 1460define i64 @bswap_i64(i64 %a) { 1461; RV64I-LABEL: bswap_i64: 1462; RV64I: # %bb.0: 1463; RV64I-NEXT: srli a1, a0, 40 1464; RV64I-NEXT: lui a2, 16 1465; RV64I-NEXT: srli a3, a0, 56 1466; RV64I-NEXT: srli a4, a0, 24 1467; RV64I-NEXT: lui a5, 4080 1468; RV64I-NEXT: addiw a2, a2, -256 1469; RV64I-NEXT: and a1, a1, a2 1470; RV64I-NEXT: or a1, a1, a3 1471; RV64I-NEXT: srli a3, a0, 8 1472; RV64I-NEXT: and a4, a4, a5 1473; RV64I-NEXT: srliw a3, a3, 24 1474; RV64I-NEXT: slli a3, a3, 24 1475; RV64I-NEXT: or a3, a3, a4 1476; RV64I-NEXT: srliw a4, a0, 24 1477; RV64I-NEXT: and a5, a0, a5 1478; RV64I-NEXT: and a2, a0, a2 1479; RV64I-NEXT: slli a0, a0, 56 1480; RV64I-NEXT: slli a4, a4, 32 1481; RV64I-NEXT: slli a5, a5, 24 1482; RV64I-NEXT: or a4, a5, a4 1483; RV64I-NEXT: slli a2, a2, 40 1484; RV64I-NEXT: or a1, a3, a1 1485; RV64I-NEXT: or a0, a0, a2 1486; RV64I-NEXT: or a0, a0, a4 1487; RV64I-NEXT: or a0, a0, a1 1488; RV64I-NEXT: ret 1489; 1490; RV64ZBB-LABEL: bswap_i64: 1491; RV64ZBB: # %bb.0: 1492; RV64ZBB-NEXT: rev8 a0, a0 1493; RV64ZBB-NEXT: ret 1494 %1 = call i64 @llvm.bswap.i64(i64 %a) 1495 ret i64 %1 1496} 1497 1498define i16 @orc_b_i16(i16 %a) { 1499; RV64I-LABEL: orc_b_i16: 1500; RV64I: # %bb.0: 1501; RV64I-NEXT: andi a0, a0, 257 1502; RV64I-NEXT: slli a1, a0, 8 1503; RV64I-NEXT: sub a0, a1, a0 1504; RV64I-NEXT: ret 1505; 1506; RV64ZBB-LABEL: orc_b_i16: 1507; RV64ZBB: # %bb.0: 1508; RV64ZBB-NEXT: andi a0, a0, 257 1509; RV64ZBB-NEXT: orc.b a0, a0 1510; RV64ZBB-NEXT: ret 1511 %1 = and i16 %a, 257 1512 %2 = mul nuw i16 %1, 255 1513 ret i16 %2 1514} 1515 1516define i32 @orc_b_i32(i32 %a) { 1517; RV64I-LABEL: orc_b_i32: 1518; RV64I: # %bb.0: 1519; RV64I-NEXT: lui a1, 4112 1520; RV64I-NEXT: addi a1, a1, 257 1521; RV64I-NEXT: and a0, a0, a1 1522; RV64I-NEXT: slli a1, a0, 8 1523; RV64I-NEXT: subw a0, a1, a0 1524; RV64I-NEXT: ret 1525; 1526; RV64ZBB-LABEL: orc_b_i32: 1527; RV64ZBB: # %bb.0: 1528; RV64ZBB-NEXT: lui a1, 4112 1529; RV64ZBB-NEXT: addiw a1, a1, 257 1530; RV64ZBB-NEXT: and a0, a0, a1 1531; RV64ZBB-NEXT: orc.b a0, a0 1532; RV64ZBB-NEXT: ret 1533 %1 = and i32 %a, 16843009 1534 %2 = mul nuw i32 %1, 255 1535 ret i32 %2 1536} 1537 1538define i64 @orc_b_i64(i64 %a) { 1539; RV64I-LABEL: orc_b_i64: 1540; RV64I: # %bb.0: 1541; RV64I-NEXT: lui a1, 4112 1542; RV64I-NEXT: addiw a1, a1, 257 1543; RV64I-NEXT: slli a2, a1, 32 1544; RV64I-NEXT: add a1, a1, a2 1545; RV64I-NEXT: and a0, a0, a1 1546; RV64I-NEXT: slli a1, a0, 8 1547; RV64I-NEXT: sub a0, a1, a0 1548; RV64I-NEXT: ret 1549; 1550; RV64ZBB-LABEL: orc_b_i64: 1551; RV64ZBB: # %bb.0: 1552; RV64ZBB-NEXT: lui a1, 4112 1553; RV64ZBB-NEXT: addiw a1, a1, 257 1554; RV64ZBB-NEXT: slli a2, a1, 32 1555; RV64ZBB-NEXT: add a1, a1, a2 1556; RV64ZBB-NEXT: and a0, a0, a1 1557; RV64ZBB-NEXT: orc.b a0, a0 1558; RV64ZBB-NEXT: ret 1559 %1 = and i64 %a, 72340172838076673 1560 %2 = mul nuw i64 %1, 255 1561 ret i64 %2 1562} 1563 1564define i64 @srai_slli(i16 signext %0) { 1565; RV64I-LABEL: srai_slli: 1566; RV64I: # %bb.0: 1567; RV64I-NEXT: slli a0, a0, 57 1568; RV64I-NEXT: srai a0, a0, 63 1569; RV64I-NEXT: ret 1570; 1571; RV64ZBB-LABEL: srai_slli: 1572; RV64ZBB: # %bb.0: 1573; RV64ZBB-NEXT: slli a0, a0, 57 1574; RV64ZBB-NEXT: srai a0, a0, 63 1575; RV64ZBB-NEXT: ret 1576 %2 = shl i16 %0, 9 1577 %sext = ashr i16 %2, 15 1578 %3 = sext i16 %sext to i64 1579 ret i64 %3 1580} 1581 1582define i64 @srai_slli2(i16 signext %0) { 1583; RV64I-LABEL: srai_slli2: 1584; RV64I: # %bb.0: 1585; RV64I-NEXT: slli a0, a0, 57 1586; RV64I-NEXT: srai a0, a0, 62 1587; RV64I-NEXT: ret 1588; 1589; RV64ZBB-LABEL: srai_slli2: 1590; RV64ZBB: # %bb.0: 1591; RV64ZBB-NEXT: slli a0, a0, 57 1592; RV64ZBB-NEXT: srai a0, a0, 62 1593; RV64ZBB-NEXT: ret 1594 %2 = shl i16 %0, 9 1595 %sext = ashr i16 %2, 14 1596 %3 = sext i16 %sext to i64 1597 ret i64 %3 1598} 1599 1600define signext i32 @func0000000000000001(i32 signext %0, i8 signext %1) #0 { 1601; RV64I-LABEL: func0000000000000001: 1602; RV64I: # %bb.0: # %entry 1603; RV64I-NEXT: slli a1, a1, 59 1604; RV64I-NEXT: srai a1, a1, 63 1605; RV64I-NEXT: addw a0, a1, a0 1606; RV64I-NEXT: ret 1607; 1608; RV64ZBB-LABEL: func0000000000000001: 1609; RV64ZBB: # %bb.0: # %entry 1610; RV64ZBB-NEXT: slli a1, a1, 59 1611; RV64ZBB-NEXT: srai a1, a1, 63 1612; RV64ZBB-NEXT: addw a0, a1, a0 1613; RV64ZBB-NEXT: ret 1614entry: 1615 %2 = shl i8 %1, 3 1616 %3 = ashr i8 %2, 7 1617 %4 = sext i8 %3 to i32 1618 %5 = add nsw i32 %4, %0 1619 ret i32 %5 1620} 1621 1622define i1 @ctpop32_eq_one_nonzero(i32 %x) { 1623; RV64I-LABEL: ctpop32_eq_one_nonzero: 1624; RV64I: # %bb.0: # %entry 1625; RV64I-NEXT: addi a1, a0, -1 1626; RV64I-NEXT: and a0, a0, a1 1627; RV64I-NEXT: sext.w a0, a0 1628; RV64I-NEXT: seqz a0, a0 1629; RV64I-NEXT: ret 1630; 1631; RV64ZBB-LABEL: ctpop32_eq_one_nonzero: 1632; RV64ZBB: # %bb.0: # %entry 1633; RV64ZBB-NEXT: cpopw a0, a0 1634; RV64ZBB-NEXT: sltiu a0, a0, 2 1635; RV64ZBB-NEXT: ret 1636entry: 1637 %popcnt = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x) 1638 %cmp = icmp eq i32 %popcnt, 1 1639 ret i1 %cmp 1640} 1641 1642define i1 @ctpop32_ne_one_nonzero(i32 %x) { 1643; RV64I-LABEL: ctpop32_ne_one_nonzero: 1644; RV64I: # %bb.0: # %entry 1645; RV64I-NEXT: addi a1, a0, -1 1646; RV64I-NEXT: and a0, a0, a1 1647; RV64I-NEXT: sext.w a0, a0 1648; RV64I-NEXT: snez a0, a0 1649; RV64I-NEXT: ret 1650; 1651; RV64ZBB-LABEL: ctpop32_ne_one_nonzero: 1652; RV64ZBB: # %bb.0: # %entry 1653; RV64ZBB-NEXT: cpopw a0, a0 1654; RV64ZBB-NEXT: sltiu a0, a0, 2 1655; RV64ZBB-NEXT: xori a0, a0, 1 1656; RV64ZBB-NEXT: ret 1657entry: 1658 %popcnt = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x) 1659 %cmp = icmp ne i32 %popcnt, 1 1660 ret i1 %cmp 1661} 1662 1663define i1 @ctpop64_eq_one_nonzero(i64 %x) { 1664; RV64I-LABEL: ctpop64_eq_one_nonzero: 1665; RV64I: # %bb.0: # %entry 1666; RV64I-NEXT: addi a1, a0, -1 1667; RV64I-NEXT: and a0, a0, a1 1668; RV64I-NEXT: seqz a0, a0 1669; RV64I-NEXT: ret 1670; 1671; RV64ZBB-LABEL: ctpop64_eq_one_nonzero: 1672; RV64ZBB: # %bb.0: # %entry 1673; RV64ZBB-NEXT: cpop a0, a0 1674; RV64ZBB-NEXT: sltiu a0, a0, 2 1675; RV64ZBB-NEXT: ret 1676entry: 1677 %popcnt = call range(i64 1, 65) i64 @llvm.ctpop.i64(i64 %x) 1678 %cmp = icmp eq i64 %popcnt, 1 1679 ret i1 %cmp 1680} 1681 1682define i1 @ctpop32_eq_one_maybezero(i32 %x) { 1683; RV64I-LABEL: ctpop32_eq_one_maybezero: 1684; RV64I: # %bb.0: # %entry 1685; RV64I-NEXT: addiw a1, a0, -1 1686; RV64I-NEXT: xor a0, a0, a1 1687; RV64I-NEXT: sext.w a0, a0 1688; RV64I-NEXT: sltu a0, a1, a0 1689; RV64I-NEXT: ret 1690; 1691; RV64ZBB-LABEL: ctpop32_eq_one_maybezero: 1692; RV64ZBB: # %bb.0: # %entry 1693; RV64ZBB-NEXT: cpopw a0, a0 1694; RV64ZBB-NEXT: addi a0, a0, -1 1695; RV64ZBB-NEXT: seqz a0, a0 1696; RV64ZBB-NEXT: ret 1697entry: 1698 %popcnt = call range(i32 0, 16) i32 @llvm.ctpop.i32(i32 %x) 1699 %cmp = icmp eq i32 %popcnt, 1 1700 ret i1 %cmp 1701} 1702