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-prefix=RV32I 4; RUN: llc -mtriple=riscv64 -verify-machineinstrs -enable-legalize-types-checking < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64I 6; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs < %s \ 7; RUN: | FileCheck %s -check-prefix=RV32ZBB 8; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \ 9; RUN: | FileCheck %s -check-prefix=RV64ZBB 10; RUN: llc -mtriple=riscv32 -mattr=+xtheadbb -verify-machineinstrs < %s \ 11; RUN: | FileCheck %s -check-prefix=RV32XTHEADBB 12; RUN: llc -mtriple=riscv64 -mattr=+xtheadbb -verify-machineinstrs < %s \ 13; RUN: | FileCheck %s -check-prefix=RV64XTHEADBB 14 15; NOTE: -enable-legalize-types-checking is on one command line due to a previous 16; assertion failure on an expensive checks build for @rotr_32_mask_multiple. 17 18; These IR sequences are idioms for rotates. If rotate instructions are 19; supported, they will be turned into ISD::ROTL or ISD::ROTR. 20 21define i32 @rotl_32(i32 %x, i32 %y) nounwind { 22; RV32I-LABEL: rotl_32: 23; RV32I: # %bb.0: 24; RV32I-NEXT: neg a2, a1 25; RV32I-NEXT: sll a1, a0, a1 26; RV32I-NEXT: srl a0, a0, a2 27; RV32I-NEXT: or a0, a1, a0 28; RV32I-NEXT: ret 29; 30; RV64I-LABEL: rotl_32: 31; RV64I: # %bb.0: 32; RV64I-NEXT: negw a2, a1 33; RV64I-NEXT: sllw a1, a0, a1 34; RV64I-NEXT: srlw a0, a0, a2 35; RV64I-NEXT: or a0, a1, a0 36; RV64I-NEXT: ret 37; 38; RV32ZBB-LABEL: rotl_32: 39; RV32ZBB: # %bb.0: 40; RV32ZBB-NEXT: rol a0, a0, a1 41; RV32ZBB-NEXT: ret 42; 43; RV64ZBB-LABEL: rotl_32: 44; RV64ZBB: # %bb.0: 45; RV64ZBB-NEXT: rolw a0, a0, a1 46; RV64ZBB-NEXT: ret 47; 48; RV32XTHEADBB-LABEL: rotl_32: 49; RV32XTHEADBB: # %bb.0: 50; RV32XTHEADBB-NEXT: sll a2, a0, a1 51; RV32XTHEADBB-NEXT: neg a1, a1 52; RV32XTHEADBB-NEXT: srl a0, a0, a1 53; RV32XTHEADBB-NEXT: or a0, a2, a0 54; RV32XTHEADBB-NEXT: ret 55; 56; RV64XTHEADBB-LABEL: rotl_32: 57; RV64XTHEADBB: # %bb.0: 58; RV64XTHEADBB-NEXT: sllw a2, a0, a1 59; RV64XTHEADBB-NEXT: negw a1, a1 60; RV64XTHEADBB-NEXT: srlw a0, a0, a1 61; RV64XTHEADBB-NEXT: or a0, a2, a0 62; RV64XTHEADBB-NEXT: ret 63 %z = sub i32 32, %y 64 %b = shl i32 %x, %y 65 %c = lshr i32 %x, %z 66 %d = or i32 %b, %c 67 ret i32 %d 68} 69 70define i32 @rotr_32(i32 %x, i32 %y) nounwind { 71; RV32I-LABEL: rotr_32: 72; RV32I: # %bb.0: 73; RV32I-NEXT: neg a2, a1 74; RV32I-NEXT: srl a1, a0, a1 75; RV32I-NEXT: sll a0, a0, a2 76; RV32I-NEXT: or a0, a1, a0 77; RV32I-NEXT: ret 78; 79; RV64I-LABEL: rotr_32: 80; RV64I: # %bb.0: 81; RV64I-NEXT: negw a2, a1 82; RV64I-NEXT: srlw a1, a0, a1 83; RV64I-NEXT: sllw a0, a0, a2 84; RV64I-NEXT: or a0, a1, a0 85; RV64I-NEXT: ret 86; 87; RV32ZBB-LABEL: rotr_32: 88; RV32ZBB: # %bb.0: 89; RV32ZBB-NEXT: ror a0, a0, a1 90; RV32ZBB-NEXT: ret 91; 92; RV64ZBB-LABEL: rotr_32: 93; RV64ZBB: # %bb.0: 94; RV64ZBB-NEXT: rorw a0, a0, a1 95; RV64ZBB-NEXT: ret 96; 97; RV32XTHEADBB-LABEL: rotr_32: 98; RV32XTHEADBB: # %bb.0: 99; RV32XTHEADBB-NEXT: srl a2, a0, a1 100; RV32XTHEADBB-NEXT: neg a1, a1 101; RV32XTHEADBB-NEXT: sll a0, a0, a1 102; RV32XTHEADBB-NEXT: or a0, a2, a0 103; RV32XTHEADBB-NEXT: ret 104; 105; RV64XTHEADBB-LABEL: rotr_32: 106; RV64XTHEADBB: # %bb.0: 107; RV64XTHEADBB-NEXT: srlw a2, a0, a1 108; RV64XTHEADBB-NEXT: negw a1, a1 109; RV64XTHEADBB-NEXT: sllw a0, a0, a1 110; RV64XTHEADBB-NEXT: or a0, a2, a0 111; RV64XTHEADBB-NEXT: ret 112 %z = sub i32 32, %y 113 %b = lshr i32 %x, %y 114 %c = shl i32 %x, %z 115 %d = or i32 %b, %c 116 ret i32 %d 117} 118 119define i64 @rotl_64(i64 %x, i64 %y) nounwind { 120; RV32I-LABEL: rotl_64: 121; RV32I: # %bb.0: 122; RV32I-NEXT: addi a5, a2, -32 123; RV32I-NEXT: sll a4, a0, a2 124; RV32I-NEXT: bltz a5, .LBB2_2 125; RV32I-NEXT: # %bb.1: 126; RV32I-NEXT: mv a3, a4 127; RV32I-NEXT: j .LBB2_3 128; RV32I-NEXT: .LBB2_2: 129; RV32I-NEXT: sll a3, a1, a2 130; RV32I-NEXT: not a6, a2 131; RV32I-NEXT: srli a7, a0, 1 132; RV32I-NEXT: srl a6, a7, a6 133; RV32I-NEXT: or a3, a3, a6 134; RV32I-NEXT: .LBB2_3: 135; RV32I-NEXT: srai a5, a5, 31 136; RV32I-NEXT: neg a7, a2 137; RV32I-NEXT: li a6, 32 138; RV32I-NEXT: and a4, a5, a4 139; RV32I-NEXT: sub a5, a6, a2 140; RV32I-NEXT: srl a6, a1, a7 141; RV32I-NEXT: bltz a5, .LBB2_5 142; RV32I-NEXT: # %bb.4: 143; RV32I-NEXT: mv a0, a6 144; RV32I-NEXT: j .LBB2_6 145; RV32I-NEXT: .LBB2_5: 146; RV32I-NEXT: srl a0, a0, a7 147; RV32I-NEXT: li a7, 64 148; RV32I-NEXT: sub a2, a7, a2 149; RV32I-NEXT: not a2, a2 150; RV32I-NEXT: slli a1, a1, 1 151; RV32I-NEXT: sll a1, a1, a2 152; RV32I-NEXT: or a0, a0, a1 153; RV32I-NEXT: .LBB2_6: 154; RV32I-NEXT: srai a5, a5, 31 155; RV32I-NEXT: and a1, a5, a6 156; RV32I-NEXT: or a1, a3, a1 157; RV32I-NEXT: or a0, a4, a0 158; RV32I-NEXT: ret 159; 160; RV64I-LABEL: rotl_64: 161; RV64I: # %bb.0: 162; RV64I-NEXT: negw a2, a1 163; RV64I-NEXT: sll a1, a0, a1 164; RV64I-NEXT: srl a0, a0, a2 165; RV64I-NEXT: or a0, a1, a0 166; RV64I-NEXT: ret 167; 168; RV32ZBB-LABEL: rotl_64: 169; RV32ZBB: # %bb.0: 170; RV32ZBB-NEXT: addi a5, a2, -32 171; RV32ZBB-NEXT: sll a4, a0, a2 172; RV32ZBB-NEXT: bltz a5, .LBB2_2 173; RV32ZBB-NEXT: # %bb.1: 174; RV32ZBB-NEXT: mv a3, a4 175; RV32ZBB-NEXT: j .LBB2_3 176; RV32ZBB-NEXT: .LBB2_2: 177; RV32ZBB-NEXT: sll a3, a1, a2 178; RV32ZBB-NEXT: not a6, a2 179; RV32ZBB-NEXT: srli a7, a0, 1 180; RV32ZBB-NEXT: srl a6, a7, a6 181; RV32ZBB-NEXT: or a3, a3, a6 182; RV32ZBB-NEXT: .LBB2_3: 183; RV32ZBB-NEXT: srai a5, a5, 31 184; RV32ZBB-NEXT: neg a7, a2 185; RV32ZBB-NEXT: li a6, 32 186; RV32ZBB-NEXT: and a4, a5, a4 187; RV32ZBB-NEXT: sub a5, a6, a2 188; RV32ZBB-NEXT: srl a6, a1, a7 189; RV32ZBB-NEXT: bltz a5, .LBB2_5 190; RV32ZBB-NEXT: # %bb.4: 191; RV32ZBB-NEXT: mv a0, a6 192; RV32ZBB-NEXT: j .LBB2_6 193; RV32ZBB-NEXT: .LBB2_5: 194; RV32ZBB-NEXT: srl a0, a0, a7 195; RV32ZBB-NEXT: li a7, 64 196; RV32ZBB-NEXT: sub a2, a7, a2 197; RV32ZBB-NEXT: not a2, a2 198; RV32ZBB-NEXT: slli a1, a1, 1 199; RV32ZBB-NEXT: sll a1, a1, a2 200; RV32ZBB-NEXT: or a0, a0, a1 201; RV32ZBB-NEXT: .LBB2_6: 202; RV32ZBB-NEXT: srai a5, a5, 31 203; RV32ZBB-NEXT: and a1, a5, a6 204; RV32ZBB-NEXT: or a1, a3, a1 205; RV32ZBB-NEXT: or a0, a4, a0 206; RV32ZBB-NEXT: ret 207; 208; RV64ZBB-LABEL: rotl_64: 209; RV64ZBB: # %bb.0: 210; RV64ZBB-NEXT: rol a0, a0, a1 211; RV64ZBB-NEXT: ret 212; 213; RV32XTHEADBB-LABEL: rotl_64: 214; RV32XTHEADBB: # %bb.0: 215; RV32XTHEADBB-NEXT: addi a5, a2, -32 216; RV32XTHEADBB-NEXT: sll a4, a0, a2 217; RV32XTHEADBB-NEXT: bltz a5, .LBB2_2 218; RV32XTHEADBB-NEXT: # %bb.1: 219; RV32XTHEADBB-NEXT: mv a3, a4 220; RV32XTHEADBB-NEXT: j .LBB2_3 221; RV32XTHEADBB-NEXT: .LBB2_2: 222; RV32XTHEADBB-NEXT: sll a3, a1, a2 223; RV32XTHEADBB-NEXT: not a6, a2 224; RV32XTHEADBB-NEXT: srli a7, a0, 1 225; RV32XTHEADBB-NEXT: srl a6, a7, a6 226; RV32XTHEADBB-NEXT: or a3, a3, a6 227; RV32XTHEADBB-NEXT: .LBB2_3: 228; RV32XTHEADBB-NEXT: srai a5, a5, 31 229; RV32XTHEADBB-NEXT: neg a7, a2 230; RV32XTHEADBB-NEXT: li a6, 32 231; RV32XTHEADBB-NEXT: and a4, a5, a4 232; RV32XTHEADBB-NEXT: sub a5, a6, a2 233; RV32XTHEADBB-NEXT: srl a6, a1, a7 234; RV32XTHEADBB-NEXT: bltz a5, .LBB2_5 235; RV32XTHEADBB-NEXT: # %bb.4: 236; RV32XTHEADBB-NEXT: mv a0, a6 237; RV32XTHEADBB-NEXT: j .LBB2_6 238; RV32XTHEADBB-NEXT: .LBB2_5: 239; RV32XTHEADBB-NEXT: srl a0, a0, a7 240; RV32XTHEADBB-NEXT: li a7, 64 241; RV32XTHEADBB-NEXT: sub a2, a7, a2 242; RV32XTHEADBB-NEXT: not a2, a2 243; RV32XTHEADBB-NEXT: slli a1, a1, 1 244; RV32XTHEADBB-NEXT: sll a1, a1, a2 245; RV32XTHEADBB-NEXT: or a0, a0, a1 246; RV32XTHEADBB-NEXT: .LBB2_6: 247; RV32XTHEADBB-NEXT: srai a5, a5, 31 248; RV32XTHEADBB-NEXT: and a1, a5, a6 249; RV32XTHEADBB-NEXT: or a1, a3, a1 250; RV32XTHEADBB-NEXT: or a0, a4, a0 251; RV32XTHEADBB-NEXT: ret 252; 253; RV64XTHEADBB-LABEL: rotl_64: 254; RV64XTHEADBB: # %bb.0: 255; RV64XTHEADBB-NEXT: sll a2, a0, a1 256; RV64XTHEADBB-NEXT: negw a1, a1 257; RV64XTHEADBB-NEXT: srl a0, a0, a1 258; RV64XTHEADBB-NEXT: or a0, a2, a0 259; RV64XTHEADBB-NEXT: ret 260 %z = sub i64 64, %y 261 %b = shl i64 %x, %y 262 %c = lshr i64 %x, %z 263 %d = or i64 %b, %c 264 ret i64 %d 265} 266 267define i64 @rotr_64(i64 %x, i64 %y) nounwind { 268; RV32I-LABEL: rotr_64: 269; RV32I: # %bb.0: 270; RV32I-NEXT: addi a5, a2, -32 271; RV32I-NEXT: srl a4, a1, a2 272; RV32I-NEXT: bltz a5, .LBB3_2 273; RV32I-NEXT: # %bb.1: 274; RV32I-NEXT: mv a3, a4 275; RV32I-NEXT: j .LBB3_3 276; RV32I-NEXT: .LBB3_2: 277; RV32I-NEXT: srl a3, a0, a2 278; RV32I-NEXT: not a6, a2 279; RV32I-NEXT: slli a7, a1, 1 280; RV32I-NEXT: sll a6, a7, a6 281; RV32I-NEXT: or a3, a3, a6 282; RV32I-NEXT: .LBB3_3: 283; RV32I-NEXT: srai a5, a5, 31 284; RV32I-NEXT: neg a7, a2 285; RV32I-NEXT: li a6, 32 286; RV32I-NEXT: and a4, a5, a4 287; RV32I-NEXT: sub a5, a6, a2 288; RV32I-NEXT: sll a6, a0, a7 289; RV32I-NEXT: bltz a5, .LBB3_5 290; RV32I-NEXT: # %bb.4: 291; RV32I-NEXT: mv a1, a6 292; RV32I-NEXT: j .LBB3_6 293; RV32I-NEXT: .LBB3_5: 294; RV32I-NEXT: sll a1, a1, a7 295; RV32I-NEXT: li a7, 64 296; RV32I-NEXT: sub a2, a7, a2 297; RV32I-NEXT: not a2, a2 298; RV32I-NEXT: srli a0, a0, 1 299; RV32I-NEXT: srl a0, a0, a2 300; RV32I-NEXT: or a1, a1, a0 301; RV32I-NEXT: .LBB3_6: 302; RV32I-NEXT: srai a5, a5, 31 303; RV32I-NEXT: and a0, a5, a6 304; RV32I-NEXT: or a0, a3, a0 305; RV32I-NEXT: or a1, a4, a1 306; RV32I-NEXT: ret 307; 308; RV64I-LABEL: rotr_64: 309; RV64I: # %bb.0: 310; RV64I-NEXT: negw a2, a1 311; RV64I-NEXT: srl a1, a0, a1 312; RV64I-NEXT: sll a0, a0, a2 313; RV64I-NEXT: or a0, a1, a0 314; RV64I-NEXT: ret 315; 316; RV32ZBB-LABEL: rotr_64: 317; RV32ZBB: # %bb.0: 318; RV32ZBB-NEXT: addi a5, a2, -32 319; RV32ZBB-NEXT: srl a4, a1, a2 320; RV32ZBB-NEXT: bltz a5, .LBB3_2 321; RV32ZBB-NEXT: # %bb.1: 322; RV32ZBB-NEXT: mv a3, a4 323; RV32ZBB-NEXT: j .LBB3_3 324; RV32ZBB-NEXT: .LBB3_2: 325; RV32ZBB-NEXT: srl a3, a0, a2 326; RV32ZBB-NEXT: not a6, a2 327; RV32ZBB-NEXT: slli a7, a1, 1 328; RV32ZBB-NEXT: sll a6, a7, a6 329; RV32ZBB-NEXT: or a3, a3, a6 330; RV32ZBB-NEXT: .LBB3_3: 331; RV32ZBB-NEXT: srai a5, a5, 31 332; RV32ZBB-NEXT: neg a7, a2 333; RV32ZBB-NEXT: li a6, 32 334; RV32ZBB-NEXT: and a4, a5, a4 335; RV32ZBB-NEXT: sub a5, a6, a2 336; RV32ZBB-NEXT: sll a6, a0, a7 337; RV32ZBB-NEXT: bltz a5, .LBB3_5 338; RV32ZBB-NEXT: # %bb.4: 339; RV32ZBB-NEXT: mv a1, a6 340; RV32ZBB-NEXT: j .LBB3_6 341; RV32ZBB-NEXT: .LBB3_5: 342; RV32ZBB-NEXT: sll a1, a1, a7 343; RV32ZBB-NEXT: li a7, 64 344; RV32ZBB-NEXT: sub a2, a7, a2 345; RV32ZBB-NEXT: not a2, a2 346; RV32ZBB-NEXT: srli a0, a0, 1 347; RV32ZBB-NEXT: srl a0, a0, a2 348; RV32ZBB-NEXT: or a1, a1, a0 349; RV32ZBB-NEXT: .LBB3_6: 350; RV32ZBB-NEXT: srai a5, a5, 31 351; RV32ZBB-NEXT: and a0, a5, a6 352; RV32ZBB-NEXT: or a0, a3, a0 353; RV32ZBB-NEXT: or a1, a4, a1 354; RV32ZBB-NEXT: ret 355; 356; RV64ZBB-LABEL: rotr_64: 357; RV64ZBB: # %bb.0: 358; RV64ZBB-NEXT: ror a0, a0, a1 359; RV64ZBB-NEXT: ret 360; 361; RV32XTHEADBB-LABEL: rotr_64: 362; RV32XTHEADBB: # %bb.0: 363; RV32XTHEADBB-NEXT: addi a5, a2, -32 364; RV32XTHEADBB-NEXT: srl a4, a1, a2 365; RV32XTHEADBB-NEXT: bltz a5, .LBB3_2 366; RV32XTHEADBB-NEXT: # %bb.1: 367; RV32XTHEADBB-NEXT: mv a3, a4 368; RV32XTHEADBB-NEXT: j .LBB3_3 369; RV32XTHEADBB-NEXT: .LBB3_2: 370; RV32XTHEADBB-NEXT: srl a3, a0, a2 371; RV32XTHEADBB-NEXT: not a6, a2 372; RV32XTHEADBB-NEXT: slli a7, a1, 1 373; RV32XTHEADBB-NEXT: sll a6, a7, a6 374; RV32XTHEADBB-NEXT: or a3, a3, a6 375; RV32XTHEADBB-NEXT: .LBB3_3: 376; RV32XTHEADBB-NEXT: srai a5, a5, 31 377; RV32XTHEADBB-NEXT: neg a7, a2 378; RV32XTHEADBB-NEXT: li a6, 32 379; RV32XTHEADBB-NEXT: and a4, a5, a4 380; RV32XTHEADBB-NEXT: sub a5, a6, a2 381; RV32XTHEADBB-NEXT: sll a6, a0, a7 382; RV32XTHEADBB-NEXT: bltz a5, .LBB3_5 383; RV32XTHEADBB-NEXT: # %bb.4: 384; RV32XTHEADBB-NEXT: mv a1, a6 385; RV32XTHEADBB-NEXT: j .LBB3_6 386; RV32XTHEADBB-NEXT: .LBB3_5: 387; RV32XTHEADBB-NEXT: sll a1, a1, a7 388; RV32XTHEADBB-NEXT: li a7, 64 389; RV32XTHEADBB-NEXT: sub a2, a7, a2 390; RV32XTHEADBB-NEXT: not a2, a2 391; RV32XTHEADBB-NEXT: srli a0, a0, 1 392; RV32XTHEADBB-NEXT: srl a0, a0, a2 393; RV32XTHEADBB-NEXT: or a1, a1, a0 394; RV32XTHEADBB-NEXT: .LBB3_6: 395; RV32XTHEADBB-NEXT: srai a5, a5, 31 396; RV32XTHEADBB-NEXT: and a0, a5, a6 397; RV32XTHEADBB-NEXT: or a0, a3, a0 398; RV32XTHEADBB-NEXT: or a1, a4, a1 399; RV32XTHEADBB-NEXT: ret 400; 401; RV64XTHEADBB-LABEL: rotr_64: 402; RV64XTHEADBB: # %bb.0: 403; RV64XTHEADBB-NEXT: srl a2, a0, a1 404; RV64XTHEADBB-NEXT: negw a1, a1 405; RV64XTHEADBB-NEXT: sll a0, a0, a1 406; RV64XTHEADBB-NEXT: or a0, a2, a0 407; RV64XTHEADBB-NEXT: ret 408 %z = sub i64 64, %y 409 %b = lshr i64 %x, %y 410 %c = shl i64 %x, %z 411 %d = or i64 %b, %c 412 ret i64 %d 413} 414 415define i32 @rotl_32_mask(i32 %x, i32 %y) nounwind { 416; RV32I-LABEL: rotl_32_mask: 417; RV32I: # %bb.0: 418; RV32I-NEXT: neg a2, a1 419; RV32I-NEXT: sll a1, a0, a1 420; RV32I-NEXT: srl a0, a0, a2 421; RV32I-NEXT: or a0, a1, a0 422; RV32I-NEXT: ret 423; 424; RV64I-LABEL: rotl_32_mask: 425; RV64I: # %bb.0: 426; RV64I-NEXT: negw a2, a1 427; RV64I-NEXT: sllw a1, a0, a1 428; RV64I-NEXT: srlw a0, a0, a2 429; RV64I-NEXT: or a0, a1, a0 430; RV64I-NEXT: ret 431; 432; RV32ZBB-LABEL: rotl_32_mask: 433; RV32ZBB: # %bb.0: 434; RV32ZBB-NEXT: rol a0, a0, a1 435; RV32ZBB-NEXT: ret 436; 437; RV64ZBB-LABEL: rotl_32_mask: 438; RV64ZBB: # %bb.0: 439; RV64ZBB-NEXT: rolw a0, a0, a1 440; RV64ZBB-NEXT: ret 441; 442; RV32XTHEADBB-LABEL: rotl_32_mask: 443; RV32XTHEADBB: # %bb.0: 444; RV32XTHEADBB-NEXT: sll a2, a0, a1 445; RV32XTHEADBB-NEXT: neg a1, a1 446; RV32XTHEADBB-NEXT: srl a0, a0, a1 447; RV32XTHEADBB-NEXT: or a0, a2, a0 448; RV32XTHEADBB-NEXT: ret 449; 450; RV64XTHEADBB-LABEL: rotl_32_mask: 451; RV64XTHEADBB: # %bb.0: 452; RV64XTHEADBB-NEXT: sllw a2, a0, a1 453; RV64XTHEADBB-NEXT: negw a1, a1 454; RV64XTHEADBB-NEXT: srlw a0, a0, a1 455; RV64XTHEADBB-NEXT: or a0, a2, a0 456; RV64XTHEADBB-NEXT: ret 457 %z = sub i32 0, %y 458 %and = and i32 %z, 31 459 %b = shl i32 %x, %y 460 %c = lshr i32 %x, %and 461 %d = or i32 %b, %c 462 ret i32 %d 463} 464 465define i32 @rotl_32_mask_and_63_and_31(i32 %x, i32 %y) nounwind { 466; RV32I-LABEL: rotl_32_mask_and_63_and_31: 467; RV32I: # %bb.0: 468; RV32I-NEXT: sll a2, a0, a1 469; RV32I-NEXT: neg a1, a1 470; RV32I-NEXT: srl a0, a0, a1 471; RV32I-NEXT: or a0, a2, a0 472; RV32I-NEXT: ret 473; 474; RV64I-LABEL: rotl_32_mask_and_63_and_31: 475; RV64I: # %bb.0: 476; RV64I-NEXT: sllw a2, a0, a1 477; RV64I-NEXT: negw a1, a1 478; RV64I-NEXT: srlw a0, a0, a1 479; RV64I-NEXT: or a0, a2, a0 480; RV64I-NEXT: ret 481; 482; RV32ZBB-LABEL: rotl_32_mask_and_63_and_31: 483; RV32ZBB: # %bb.0: 484; RV32ZBB-NEXT: rol a0, a0, a1 485; RV32ZBB-NEXT: ret 486; 487; RV64ZBB-LABEL: rotl_32_mask_and_63_and_31: 488; RV64ZBB: # %bb.0: 489; RV64ZBB-NEXT: rolw a0, a0, a1 490; RV64ZBB-NEXT: ret 491; 492; RV32XTHEADBB-LABEL: rotl_32_mask_and_63_and_31: 493; RV32XTHEADBB: # %bb.0: 494; RV32XTHEADBB-NEXT: sll a2, a0, a1 495; RV32XTHEADBB-NEXT: neg a1, a1 496; RV32XTHEADBB-NEXT: srl a0, a0, a1 497; RV32XTHEADBB-NEXT: or a0, a2, a0 498; RV32XTHEADBB-NEXT: ret 499; 500; RV64XTHEADBB-LABEL: rotl_32_mask_and_63_and_31: 501; RV64XTHEADBB: # %bb.0: 502; RV64XTHEADBB-NEXT: sllw a2, a0, a1 503; RV64XTHEADBB-NEXT: negw a1, a1 504; RV64XTHEADBB-NEXT: srlw a0, a0, a1 505; RV64XTHEADBB-NEXT: or a0, a2, a0 506; RV64XTHEADBB-NEXT: ret 507 %a = and i32 %y, 63 508 %b = shl i32 %x, %a 509 %c = sub i32 0, %y 510 %d = and i32 %c, 31 511 %e = lshr i32 %x, %d 512 %f = or i32 %b, %e 513 ret i32 %f 514} 515 516define i32 @rotl_32_mask_or_64_or_32(i32 %x, i32 %y) nounwind { 517; RV32I-LABEL: rotl_32_mask_or_64_or_32: 518; RV32I: # %bb.0: 519; RV32I-NEXT: li a0, 0 520; RV32I-NEXT: ret 521; 522; RV64I-LABEL: rotl_32_mask_or_64_or_32: 523; RV64I: # %bb.0: 524; RV64I-NEXT: li a0, 0 525; RV64I-NEXT: ret 526; 527; RV32ZBB-LABEL: rotl_32_mask_or_64_or_32: 528; RV32ZBB: # %bb.0: 529; RV32ZBB-NEXT: rol a0, a0, a1 530; RV32ZBB-NEXT: ret 531; 532; RV64ZBB-LABEL: rotl_32_mask_or_64_or_32: 533; RV64ZBB: # %bb.0: 534; RV64ZBB-NEXT: rolw a0, a0, a1 535; RV64ZBB-NEXT: ret 536; 537; RV32XTHEADBB-LABEL: rotl_32_mask_or_64_or_32: 538; RV32XTHEADBB: # %bb.0: 539; RV32XTHEADBB-NEXT: sll a2, a0, a1 540; RV32XTHEADBB-NEXT: neg a1, a1 541; RV32XTHEADBB-NEXT: srl a0, a0, a1 542; RV32XTHEADBB-NEXT: or a0, a2, a0 543; RV32XTHEADBB-NEXT: ret 544; 545; RV64XTHEADBB-LABEL: rotl_32_mask_or_64_or_32: 546; RV64XTHEADBB: # %bb.0: 547; RV64XTHEADBB-NEXT: sllw a2, a0, a1 548; RV64XTHEADBB-NEXT: negw a1, a1 549; RV64XTHEADBB-NEXT: srlw a0, a0, a1 550; RV64XTHEADBB-NEXT: or a0, a2, a0 551; RV64XTHEADBB-NEXT: ret 552 %a = or i32 %y, 64 553 %b = shl i32 %x, %a 554 %c = sub i32 0, %y 555 %d = or i32 %c, 32 556 %e = lshr i32 %x, %d 557 %f = or i32 %b, %e 558 ret i32 %f 559} 560 561define i32 @rotr_32_mask(i32 %x, i32 %y) nounwind { 562; RV32I-LABEL: rotr_32_mask: 563; RV32I: # %bb.0: 564; RV32I-NEXT: neg a2, a1 565; RV32I-NEXT: srl a1, a0, a1 566; RV32I-NEXT: sll a0, a0, a2 567; RV32I-NEXT: or a0, a1, a0 568; RV32I-NEXT: ret 569; 570; RV64I-LABEL: rotr_32_mask: 571; RV64I: # %bb.0: 572; RV64I-NEXT: negw a2, a1 573; RV64I-NEXT: srlw a1, a0, a1 574; RV64I-NEXT: sllw a0, a0, a2 575; RV64I-NEXT: or a0, a1, a0 576; RV64I-NEXT: ret 577; 578; RV32ZBB-LABEL: rotr_32_mask: 579; RV32ZBB: # %bb.0: 580; RV32ZBB-NEXT: ror a0, a0, a1 581; RV32ZBB-NEXT: ret 582; 583; RV64ZBB-LABEL: rotr_32_mask: 584; RV64ZBB: # %bb.0: 585; RV64ZBB-NEXT: rorw a0, a0, a1 586; RV64ZBB-NEXT: ret 587; 588; RV32XTHEADBB-LABEL: rotr_32_mask: 589; RV32XTHEADBB: # %bb.0: 590; RV32XTHEADBB-NEXT: srl a2, a0, a1 591; RV32XTHEADBB-NEXT: neg a1, a1 592; RV32XTHEADBB-NEXT: sll a0, a0, a1 593; RV32XTHEADBB-NEXT: or a0, a2, a0 594; RV32XTHEADBB-NEXT: ret 595; 596; RV64XTHEADBB-LABEL: rotr_32_mask: 597; RV64XTHEADBB: # %bb.0: 598; RV64XTHEADBB-NEXT: srlw a2, a0, a1 599; RV64XTHEADBB-NEXT: negw a1, a1 600; RV64XTHEADBB-NEXT: sllw a0, a0, a1 601; RV64XTHEADBB-NEXT: or a0, a2, a0 602; RV64XTHEADBB-NEXT: ret 603 %z = sub i32 0, %y 604 %and = and i32 %z, 31 605 %b = lshr i32 %x, %y 606 %c = shl i32 %x, %and 607 %d = or i32 %b, %c 608 ret i32 %d 609} 610 611define i32 @rotr_32_mask_and_63_and_31(i32 %x, i32 %y) nounwind { 612; RV32I-LABEL: rotr_32_mask_and_63_and_31: 613; RV32I: # %bb.0: 614; RV32I-NEXT: srl a2, a0, a1 615; RV32I-NEXT: neg a1, a1 616; RV32I-NEXT: sll a0, a0, a1 617; RV32I-NEXT: or a0, a2, a0 618; RV32I-NEXT: ret 619; 620; RV64I-LABEL: rotr_32_mask_and_63_and_31: 621; RV64I: # %bb.0: 622; RV64I-NEXT: srlw a2, a0, a1 623; RV64I-NEXT: negw a1, a1 624; RV64I-NEXT: sllw a0, a0, a1 625; RV64I-NEXT: or a0, a2, a0 626; RV64I-NEXT: ret 627; 628; RV32ZBB-LABEL: rotr_32_mask_and_63_and_31: 629; RV32ZBB: # %bb.0: 630; RV32ZBB-NEXT: ror a0, a0, a1 631; RV32ZBB-NEXT: ret 632; 633; RV64ZBB-LABEL: rotr_32_mask_and_63_and_31: 634; RV64ZBB: # %bb.0: 635; RV64ZBB-NEXT: rorw a0, a0, a1 636; RV64ZBB-NEXT: ret 637; 638; RV32XTHEADBB-LABEL: rotr_32_mask_and_63_and_31: 639; RV32XTHEADBB: # %bb.0: 640; RV32XTHEADBB-NEXT: srl a2, a0, a1 641; RV32XTHEADBB-NEXT: neg a1, a1 642; RV32XTHEADBB-NEXT: sll a0, a0, a1 643; RV32XTHEADBB-NEXT: or a0, a2, a0 644; RV32XTHEADBB-NEXT: ret 645; 646; RV64XTHEADBB-LABEL: rotr_32_mask_and_63_and_31: 647; RV64XTHEADBB: # %bb.0: 648; RV64XTHEADBB-NEXT: srlw a2, a0, a1 649; RV64XTHEADBB-NEXT: negw a1, a1 650; RV64XTHEADBB-NEXT: sllw a0, a0, a1 651; RV64XTHEADBB-NEXT: or a0, a2, a0 652; RV64XTHEADBB-NEXT: ret 653 %a = and i32 %y, 63 654 %b = lshr i32 %x, %a 655 %c = sub i32 0, %y 656 %d = and i32 %c, 31 657 %e = shl i32 %x, %d 658 %f = or i32 %b, %e 659 ret i32 %f 660} 661 662define i32 @rotr_32_mask_or_64_or_32(i32 %x, i32 %y) nounwind { 663; RV32I-LABEL: rotr_32_mask_or_64_or_32: 664; RV32I: # %bb.0: 665; RV32I-NEXT: li a0, 0 666; RV32I-NEXT: ret 667; 668; RV64I-LABEL: rotr_32_mask_or_64_or_32: 669; RV64I: # %bb.0: 670; RV64I-NEXT: li a0, 0 671; RV64I-NEXT: ret 672; 673; RV32ZBB-LABEL: rotr_32_mask_or_64_or_32: 674; RV32ZBB: # %bb.0: 675; RV32ZBB-NEXT: ror a0, a0, a1 676; RV32ZBB-NEXT: ret 677; 678; RV64ZBB-LABEL: rotr_32_mask_or_64_or_32: 679; RV64ZBB: # %bb.0: 680; RV64ZBB-NEXT: rorw a0, a0, a1 681; RV64ZBB-NEXT: ret 682; 683; RV32XTHEADBB-LABEL: rotr_32_mask_or_64_or_32: 684; RV32XTHEADBB: # %bb.0: 685; RV32XTHEADBB-NEXT: srl a2, a0, a1 686; RV32XTHEADBB-NEXT: neg a1, a1 687; RV32XTHEADBB-NEXT: sll a0, a0, a1 688; RV32XTHEADBB-NEXT: or a0, a2, a0 689; RV32XTHEADBB-NEXT: ret 690; 691; RV64XTHEADBB-LABEL: rotr_32_mask_or_64_or_32: 692; RV64XTHEADBB: # %bb.0: 693; RV64XTHEADBB-NEXT: srlw a2, a0, a1 694; RV64XTHEADBB-NEXT: negw a1, a1 695; RV64XTHEADBB-NEXT: sllw a0, a0, a1 696; RV64XTHEADBB-NEXT: or a0, a2, a0 697; RV64XTHEADBB-NEXT: ret 698 %a = or i32 %y, 64 699 %b = lshr i32 %x, %a 700 %c = sub i32 0, %y 701 %d = or i32 %c, 32 702 %e = shl i32 %x, %d 703 %f = or i32 %b, %e 704 ret i32 %f 705} 706 707define i64 @rotl_64_mask(i64 %x, i64 %y) nounwind { 708; RV32I-LABEL: rotl_64_mask: 709; RV32I: # %bb.0: 710; RV32I-NEXT: addi a5, a2, -32 711; RV32I-NEXT: sll a4, a0, a2 712; RV32I-NEXT: bltz a5, .LBB10_2 713; RV32I-NEXT: # %bb.1: 714; RV32I-NEXT: mv a3, a4 715; RV32I-NEXT: j .LBB10_3 716; RV32I-NEXT: .LBB10_2: 717; RV32I-NEXT: sll a3, a1, a2 718; RV32I-NEXT: not a6, a2 719; RV32I-NEXT: srli a7, a0, 1 720; RV32I-NEXT: srl a6, a7, a6 721; RV32I-NEXT: or a3, a3, a6 722; RV32I-NEXT: .LBB10_3: 723; RV32I-NEXT: srai t0, a5, 31 724; RV32I-NEXT: neg a5, a2 725; RV32I-NEXT: andi a7, a5, 63 726; RV32I-NEXT: addi a6, a7, -32 727; RV32I-NEXT: and a2, t0, a4 728; RV32I-NEXT: bltz a6, .LBB10_5 729; RV32I-NEXT: # %bb.4: 730; RV32I-NEXT: srl a0, a1, a7 731; RV32I-NEXT: j .LBB10_6 732; RV32I-NEXT: .LBB10_5: 733; RV32I-NEXT: srl a0, a0, a5 734; RV32I-NEXT: not a4, a7 735; RV32I-NEXT: slli a7, a1, 1 736; RV32I-NEXT: sll a4, a7, a4 737; RV32I-NEXT: or a0, a0, a4 738; RV32I-NEXT: .LBB10_6: 739; RV32I-NEXT: srl a1, a1, a5 740; RV32I-NEXT: srai a4, a6, 31 741; RV32I-NEXT: and a1, a4, a1 742; RV32I-NEXT: or a1, a3, a1 743; RV32I-NEXT: or a0, a2, a0 744; RV32I-NEXT: ret 745; 746; RV64I-LABEL: rotl_64_mask: 747; RV64I: # %bb.0: 748; RV64I-NEXT: negw a2, a1 749; RV64I-NEXT: sll a1, a0, a1 750; RV64I-NEXT: srl a0, a0, a2 751; RV64I-NEXT: or a0, a1, a0 752; RV64I-NEXT: ret 753; 754; RV32ZBB-LABEL: rotl_64_mask: 755; RV32ZBB: # %bb.0: 756; RV32ZBB-NEXT: addi a5, a2, -32 757; RV32ZBB-NEXT: sll a4, a0, a2 758; RV32ZBB-NEXT: bltz a5, .LBB10_2 759; RV32ZBB-NEXT: # %bb.1: 760; RV32ZBB-NEXT: mv a3, a4 761; RV32ZBB-NEXT: j .LBB10_3 762; RV32ZBB-NEXT: .LBB10_2: 763; RV32ZBB-NEXT: sll a3, a1, a2 764; RV32ZBB-NEXT: not a6, a2 765; RV32ZBB-NEXT: srli a7, a0, 1 766; RV32ZBB-NEXT: srl a6, a7, a6 767; RV32ZBB-NEXT: or a3, a3, a6 768; RV32ZBB-NEXT: .LBB10_3: 769; RV32ZBB-NEXT: srai t0, a5, 31 770; RV32ZBB-NEXT: neg a5, a2 771; RV32ZBB-NEXT: andi a7, a5, 63 772; RV32ZBB-NEXT: addi a6, a7, -32 773; RV32ZBB-NEXT: and a2, t0, a4 774; RV32ZBB-NEXT: bltz a6, .LBB10_5 775; RV32ZBB-NEXT: # %bb.4: 776; RV32ZBB-NEXT: srl a0, a1, a7 777; RV32ZBB-NEXT: j .LBB10_6 778; RV32ZBB-NEXT: .LBB10_5: 779; RV32ZBB-NEXT: srl a0, a0, a5 780; RV32ZBB-NEXT: not a4, a7 781; RV32ZBB-NEXT: slli a7, a1, 1 782; RV32ZBB-NEXT: sll a4, a7, a4 783; RV32ZBB-NEXT: or a0, a0, a4 784; RV32ZBB-NEXT: .LBB10_6: 785; RV32ZBB-NEXT: srl a1, a1, a5 786; RV32ZBB-NEXT: srai a4, a6, 31 787; RV32ZBB-NEXT: and a1, a4, a1 788; RV32ZBB-NEXT: or a1, a3, a1 789; RV32ZBB-NEXT: or a0, a2, a0 790; RV32ZBB-NEXT: ret 791; 792; RV64ZBB-LABEL: rotl_64_mask: 793; RV64ZBB: # %bb.0: 794; RV64ZBB-NEXT: rol a0, a0, a1 795; RV64ZBB-NEXT: ret 796; 797; RV32XTHEADBB-LABEL: rotl_64_mask: 798; RV32XTHEADBB: # %bb.0: 799; RV32XTHEADBB-NEXT: addi a5, a2, -32 800; RV32XTHEADBB-NEXT: sll a4, a0, a2 801; RV32XTHEADBB-NEXT: bltz a5, .LBB10_2 802; RV32XTHEADBB-NEXT: # %bb.1: 803; RV32XTHEADBB-NEXT: mv a3, a4 804; RV32XTHEADBB-NEXT: j .LBB10_3 805; RV32XTHEADBB-NEXT: .LBB10_2: 806; RV32XTHEADBB-NEXT: sll a3, a1, a2 807; RV32XTHEADBB-NEXT: not a6, a2 808; RV32XTHEADBB-NEXT: srli a7, a0, 1 809; RV32XTHEADBB-NEXT: srl a6, a7, a6 810; RV32XTHEADBB-NEXT: or a3, a3, a6 811; RV32XTHEADBB-NEXT: .LBB10_3: 812; RV32XTHEADBB-NEXT: srai t0, a5, 31 813; RV32XTHEADBB-NEXT: neg a5, a2 814; RV32XTHEADBB-NEXT: andi a7, a5, 63 815; RV32XTHEADBB-NEXT: addi a6, a7, -32 816; RV32XTHEADBB-NEXT: and a2, t0, a4 817; RV32XTHEADBB-NEXT: bltz a6, .LBB10_5 818; RV32XTHEADBB-NEXT: # %bb.4: 819; RV32XTHEADBB-NEXT: srl a0, a1, a7 820; RV32XTHEADBB-NEXT: j .LBB10_6 821; RV32XTHEADBB-NEXT: .LBB10_5: 822; RV32XTHEADBB-NEXT: srl a0, a0, a5 823; RV32XTHEADBB-NEXT: not a4, a7 824; RV32XTHEADBB-NEXT: slli a7, a1, 1 825; RV32XTHEADBB-NEXT: sll a4, a7, a4 826; RV32XTHEADBB-NEXT: or a0, a0, a4 827; RV32XTHEADBB-NEXT: .LBB10_6: 828; RV32XTHEADBB-NEXT: srl a1, a1, a5 829; RV32XTHEADBB-NEXT: srai a4, a6, 31 830; RV32XTHEADBB-NEXT: and a1, a4, a1 831; RV32XTHEADBB-NEXT: or a1, a3, a1 832; RV32XTHEADBB-NEXT: or a0, a2, a0 833; RV32XTHEADBB-NEXT: ret 834; 835; RV64XTHEADBB-LABEL: rotl_64_mask: 836; RV64XTHEADBB: # %bb.0: 837; RV64XTHEADBB-NEXT: sll a2, a0, a1 838; RV64XTHEADBB-NEXT: negw a1, a1 839; RV64XTHEADBB-NEXT: srl a0, a0, a1 840; RV64XTHEADBB-NEXT: or a0, a2, a0 841; RV64XTHEADBB-NEXT: ret 842 %z = sub i64 0, %y 843 %and = and i64 %z, 63 844 %b = shl i64 %x, %y 845 %c = lshr i64 %x, %and 846 %d = or i64 %b, %c 847 ret i64 %d 848} 849 850define i64 @rotl_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind { 851; RV32I-LABEL: rotl_64_mask_and_127_and_63: 852; RV32I: # %bb.0: 853; RV32I-NEXT: andi a3, a2, 127 854; RV32I-NEXT: addi a4, a3, -32 855; RV32I-NEXT: bltz a4, .LBB11_2 856; RV32I-NEXT: # %bb.1: 857; RV32I-NEXT: sll a3, a0, a3 858; RV32I-NEXT: j .LBB11_3 859; RV32I-NEXT: .LBB11_2: 860; RV32I-NEXT: sll a5, a1, a2 861; RV32I-NEXT: srli a6, a0, 1 862; RV32I-NEXT: not a3, a3 863; RV32I-NEXT: srl a3, a6, a3 864; RV32I-NEXT: or a3, a5, a3 865; RV32I-NEXT: .LBB11_3: 866; RV32I-NEXT: sll a7, a0, a2 867; RV32I-NEXT: srai t0, a4, 31 868; RV32I-NEXT: neg a4, a2 869; RV32I-NEXT: andi a6, a4, 63 870; RV32I-NEXT: addi a5, a6, -32 871; RV32I-NEXT: and a2, t0, a7 872; RV32I-NEXT: bltz a5, .LBB11_5 873; RV32I-NEXT: # %bb.4: 874; RV32I-NEXT: srl a0, a1, a6 875; RV32I-NEXT: j .LBB11_6 876; RV32I-NEXT: .LBB11_5: 877; RV32I-NEXT: srl a0, a0, a4 878; RV32I-NEXT: not a6, a6 879; RV32I-NEXT: slli a7, a1, 1 880; RV32I-NEXT: sll a6, a7, a6 881; RV32I-NEXT: or a0, a0, a6 882; RV32I-NEXT: .LBB11_6: 883; RV32I-NEXT: srl a1, a1, a4 884; RV32I-NEXT: srai a5, a5, 31 885; RV32I-NEXT: and a1, a5, a1 886; RV32I-NEXT: or a1, a3, a1 887; RV32I-NEXT: or a0, a2, a0 888; RV32I-NEXT: ret 889; 890; RV64I-LABEL: rotl_64_mask_and_127_and_63: 891; RV64I: # %bb.0: 892; RV64I-NEXT: sll a2, a0, a1 893; RV64I-NEXT: negw a1, a1 894; RV64I-NEXT: srl a0, a0, a1 895; RV64I-NEXT: or a0, a2, a0 896; RV64I-NEXT: ret 897; 898; RV32ZBB-LABEL: rotl_64_mask_and_127_and_63: 899; RV32ZBB: # %bb.0: 900; RV32ZBB-NEXT: andi a3, a2, 127 901; RV32ZBB-NEXT: addi a4, a3, -32 902; RV32ZBB-NEXT: bltz a4, .LBB11_2 903; RV32ZBB-NEXT: # %bb.1: 904; RV32ZBB-NEXT: sll a3, a0, a3 905; RV32ZBB-NEXT: j .LBB11_3 906; RV32ZBB-NEXT: .LBB11_2: 907; RV32ZBB-NEXT: sll a5, a1, a2 908; RV32ZBB-NEXT: srli a6, a0, 1 909; RV32ZBB-NEXT: not a3, a3 910; RV32ZBB-NEXT: srl a3, a6, a3 911; RV32ZBB-NEXT: or a3, a5, a3 912; RV32ZBB-NEXT: .LBB11_3: 913; RV32ZBB-NEXT: sll a7, a0, a2 914; RV32ZBB-NEXT: srai t0, a4, 31 915; RV32ZBB-NEXT: neg a4, a2 916; RV32ZBB-NEXT: andi a6, a4, 63 917; RV32ZBB-NEXT: addi a5, a6, -32 918; RV32ZBB-NEXT: and a2, t0, a7 919; RV32ZBB-NEXT: bltz a5, .LBB11_5 920; RV32ZBB-NEXT: # %bb.4: 921; RV32ZBB-NEXT: srl a0, a1, a6 922; RV32ZBB-NEXT: j .LBB11_6 923; RV32ZBB-NEXT: .LBB11_5: 924; RV32ZBB-NEXT: srl a0, a0, a4 925; RV32ZBB-NEXT: not a6, a6 926; RV32ZBB-NEXT: slli a7, a1, 1 927; RV32ZBB-NEXT: sll a6, a7, a6 928; RV32ZBB-NEXT: or a0, a0, a6 929; RV32ZBB-NEXT: .LBB11_6: 930; RV32ZBB-NEXT: srl a1, a1, a4 931; RV32ZBB-NEXT: srai a5, a5, 31 932; RV32ZBB-NEXT: and a1, a5, a1 933; RV32ZBB-NEXT: or a1, a3, a1 934; RV32ZBB-NEXT: or a0, a2, a0 935; RV32ZBB-NEXT: ret 936; 937; RV64ZBB-LABEL: rotl_64_mask_and_127_and_63: 938; RV64ZBB: # %bb.0: 939; RV64ZBB-NEXT: rol a0, a0, a1 940; RV64ZBB-NEXT: ret 941; 942; RV32XTHEADBB-LABEL: rotl_64_mask_and_127_and_63: 943; RV32XTHEADBB: # %bb.0: 944; RV32XTHEADBB-NEXT: andi a3, a2, 127 945; RV32XTHEADBB-NEXT: addi a4, a3, -32 946; RV32XTHEADBB-NEXT: bltz a4, .LBB11_2 947; RV32XTHEADBB-NEXT: # %bb.1: 948; RV32XTHEADBB-NEXT: sll a3, a0, a3 949; RV32XTHEADBB-NEXT: j .LBB11_3 950; RV32XTHEADBB-NEXT: .LBB11_2: 951; RV32XTHEADBB-NEXT: sll a5, a1, a2 952; RV32XTHEADBB-NEXT: srli a6, a0, 1 953; RV32XTHEADBB-NEXT: not a3, a3 954; RV32XTHEADBB-NEXT: srl a3, a6, a3 955; RV32XTHEADBB-NEXT: or a3, a5, a3 956; RV32XTHEADBB-NEXT: .LBB11_3: 957; RV32XTHEADBB-NEXT: sll a7, a0, a2 958; RV32XTHEADBB-NEXT: srai t0, a4, 31 959; RV32XTHEADBB-NEXT: neg a4, a2 960; RV32XTHEADBB-NEXT: andi a6, a4, 63 961; RV32XTHEADBB-NEXT: addi a5, a6, -32 962; RV32XTHEADBB-NEXT: and a2, t0, a7 963; RV32XTHEADBB-NEXT: bltz a5, .LBB11_5 964; RV32XTHEADBB-NEXT: # %bb.4: 965; RV32XTHEADBB-NEXT: srl a0, a1, a6 966; RV32XTHEADBB-NEXT: j .LBB11_6 967; RV32XTHEADBB-NEXT: .LBB11_5: 968; RV32XTHEADBB-NEXT: srl a0, a0, a4 969; RV32XTHEADBB-NEXT: not a6, a6 970; RV32XTHEADBB-NEXT: slli a7, a1, 1 971; RV32XTHEADBB-NEXT: sll a6, a7, a6 972; RV32XTHEADBB-NEXT: or a0, a0, a6 973; RV32XTHEADBB-NEXT: .LBB11_6: 974; RV32XTHEADBB-NEXT: srl a1, a1, a4 975; RV32XTHEADBB-NEXT: srai a5, a5, 31 976; RV32XTHEADBB-NEXT: and a1, a5, a1 977; RV32XTHEADBB-NEXT: or a1, a3, a1 978; RV32XTHEADBB-NEXT: or a0, a2, a0 979; RV32XTHEADBB-NEXT: ret 980; 981; RV64XTHEADBB-LABEL: rotl_64_mask_and_127_and_63: 982; RV64XTHEADBB: # %bb.0: 983; RV64XTHEADBB-NEXT: sll a2, a0, a1 984; RV64XTHEADBB-NEXT: negw a1, a1 985; RV64XTHEADBB-NEXT: srl a0, a0, a1 986; RV64XTHEADBB-NEXT: or a0, a2, a0 987; RV64XTHEADBB-NEXT: ret 988 %a = and i64 %y, 127 989 %b = shl i64 %x, %a 990 %c = sub i64 0, %y 991 %d = and i64 %c, 63 992 %e = lshr i64 %x, %d 993 %f = or i64 %b, %e 994 ret i64 %f 995} 996 997define i64 @rotl_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind { 998; RV32I-LABEL: rotl_64_mask_or_128_or_64: 999; RV32I: # %bb.0: 1000; RV32I-NEXT: li a0, 0 1001; RV32I-NEXT: li a1, 0 1002; RV32I-NEXT: ret 1003; 1004; RV64I-LABEL: rotl_64_mask_or_128_or_64: 1005; RV64I: # %bb.0: 1006; RV64I-NEXT: li a0, 0 1007; RV64I-NEXT: ret 1008; 1009; RV32ZBB-LABEL: rotl_64_mask_or_128_or_64: 1010; RV32ZBB: # %bb.0: 1011; RV32ZBB-NEXT: li a0, 0 1012; RV32ZBB-NEXT: li a1, 0 1013; RV32ZBB-NEXT: ret 1014; 1015; RV64ZBB-LABEL: rotl_64_mask_or_128_or_64: 1016; RV64ZBB: # %bb.0: 1017; RV64ZBB-NEXT: rol a0, a0, a1 1018; RV64ZBB-NEXT: ret 1019; 1020; RV32XTHEADBB-LABEL: rotl_64_mask_or_128_or_64: 1021; RV32XTHEADBB: # %bb.0: 1022; RV32XTHEADBB-NEXT: li a0, 0 1023; RV32XTHEADBB-NEXT: li a1, 0 1024; RV32XTHEADBB-NEXT: ret 1025; 1026; RV64XTHEADBB-LABEL: rotl_64_mask_or_128_or_64: 1027; RV64XTHEADBB: # %bb.0: 1028; RV64XTHEADBB-NEXT: sll a2, a0, a1 1029; RV64XTHEADBB-NEXT: negw a1, a1 1030; RV64XTHEADBB-NEXT: srl a0, a0, a1 1031; RV64XTHEADBB-NEXT: or a0, a2, a0 1032; RV64XTHEADBB-NEXT: ret 1033 %a = or i64 %y, 128 1034 %b = shl i64 %x, %a 1035 %c = sub i64 0, %y 1036 %d = or i64 %c, 64 1037 %e = lshr i64 %x, %d 1038 %f = or i64 %b, %e 1039 ret i64 %f 1040} 1041 1042define i64 @rotr_64_mask(i64 %x, i64 %y) nounwind { 1043; RV32I-LABEL: rotr_64_mask: 1044; RV32I: # %bb.0: 1045; RV32I-NEXT: addi a5, a2, -32 1046; RV32I-NEXT: srl a4, a1, a2 1047; RV32I-NEXT: bltz a5, .LBB13_2 1048; RV32I-NEXT: # %bb.1: 1049; RV32I-NEXT: mv a3, a4 1050; RV32I-NEXT: j .LBB13_3 1051; RV32I-NEXT: .LBB13_2: 1052; RV32I-NEXT: srl a3, a0, a2 1053; RV32I-NEXT: not a6, a2 1054; RV32I-NEXT: slli a7, a1, 1 1055; RV32I-NEXT: sll a6, a7, a6 1056; RV32I-NEXT: or a3, a3, a6 1057; RV32I-NEXT: .LBB13_3: 1058; RV32I-NEXT: srai t0, a5, 31 1059; RV32I-NEXT: neg a5, a2 1060; RV32I-NEXT: andi a7, a5, 63 1061; RV32I-NEXT: addi a6, a7, -32 1062; RV32I-NEXT: and a2, t0, a4 1063; RV32I-NEXT: bltz a6, .LBB13_5 1064; RV32I-NEXT: # %bb.4: 1065; RV32I-NEXT: sll a1, a0, a7 1066; RV32I-NEXT: j .LBB13_6 1067; RV32I-NEXT: .LBB13_5: 1068; RV32I-NEXT: sll a1, a1, a5 1069; RV32I-NEXT: not a4, a7 1070; RV32I-NEXT: srli a7, a0, 1 1071; RV32I-NEXT: srl a4, a7, a4 1072; RV32I-NEXT: or a1, a1, a4 1073; RV32I-NEXT: .LBB13_6: 1074; RV32I-NEXT: sll a0, a0, a5 1075; RV32I-NEXT: srai a4, a6, 31 1076; RV32I-NEXT: and a0, a4, a0 1077; RV32I-NEXT: or a0, a3, a0 1078; RV32I-NEXT: or a1, a2, a1 1079; RV32I-NEXT: ret 1080; 1081; RV64I-LABEL: rotr_64_mask: 1082; RV64I: # %bb.0: 1083; RV64I-NEXT: negw a2, a1 1084; RV64I-NEXT: srl a1, a0, a1 1085; RV64I-NEXT: sll a0, a0, a2 1086; RV64I-NEXT: or a0, a1, a0 1087; RV64I-NEXT: ret 1088; 1089; RV32ZBB-LABEL: rotr_64_mask: 1090; RV32ZBB: # %bb.0: 1091; RV32ZBB-NEXT: addi a5, a2, -32 1092; RV32ZBB-NEXT: srl a4, a1, a2 1093; RV32ZBB-NEXT: bltz a5, .LBB13_2 1094; RV32ZBB-NEXT: # %bb.1: 1095; RV32ZBB-NEXT: mv a3, a4 1096; RV32ZBB-NEXT: j .LBB13_3 1097; RV32ZBB-NEXT: .LBB13_2: 1098; RV32ZBB-NEXT: srl a3, a0, a2 1099; RV32ZBB-NEXT: not a6, a2 1100; RV32ZBB-NEXT: slli a7, a1, 1 1101; RV32ZBB-NEXT: sll a6, a7, a6 1102; RV32ZBB-NEXT: or a3, a3, a6 1103; RV32ZBB-NEXT: .LBB13_3: 1104; RV32ZBB-NEXT: srai t0, a5, 31 1105; RV32ZBB-NEXT: neg a5, a2 1106; RV32ZBB-NEXT: andi a7, a5, 63 1107; RV32ZBB-NEXT: addi a6, a7, -32 1108; RV32ZBB-NEXT: and a2, t0, a4 1109; RV32ZBB-NEXT: bltz a6, .LBB13_5 1110; RV32ZBB-NEXT: # %bb.4: 1111; RV32ZBB-NEXT: sll a1, a0, a7 1112; RV32ZBB-NEXT: j .LBB13_6 1113; RV32ZBB-NEXT: .LBB13_5: 1114; RV32ZBB-NEXT: sll a1, a1, a5 1115; RV32ZBB-NEXT: not a4, a7 1116; RV32ZBB-NEXT: srli a7, a0, 1 1117; RV32ZBB-NEXT: srl a4, a7, a4 1118; RV32ZBB-NEXT: or a1, a1, a4 1119; RV32ZBB-NEXT: .LBB13_6: 1120; RV32ZBB-NEXT: sll a0, a0, a5 1121; RV32ZBB-NEXT: srai a4, a6, 31 1122; RV32ZBB-NEXT: and a0, a4, a0 1123; RV32ZBB-NEXT: or a0, a3, a0 1124; RV32ZBB-NEXT: or a1, a2, a1 1125; RV32ZBB-NEXT: ret 1126; 1127; RV64ZBB-LABEL: rotr_64_mask: 1128; RV64ZBB: # %bb.0: 1129; RV64ZBB-NEXT: ror a0, a0, a1 1130; RV64ZBB-NEXT: ret 1131; 1132; RV32XTHEADBB-LABEL: rotr_64_mask: 1133; RV32XTHEADBB: # %bb.0: 1134; RV32XTHEADBB-NEXT: addi a5, a2, -32 1135; RV32XTHEADBB-NEXT: srl a4, a1, a2 1136; RV32XTHEADBB-NEXT: bltz a5, .LBB13_2 1137; RV32XTHEADBB-NEXT: # %bb.1: 1138; RV32XTHEADBB-NEXT: mv a3, a4 1139; RV32XTHEADBB-NEXT: j .LBB13_3 1140; RV32XTHEADBB-NEXT: .LBB13_2: 1141; RV32XTHEADBB-NEXT: srl a3, a0, a2 1142; RV32XTHEADBB-NEXT: not a6, a2 1143; RV32XTHEADBB-NEXT: slli a7, a1, 1 1144; RV32XTHEADBB-NEXT: sll a6, a7, a6 1145; RV32XTHEADBB-NEXT: or a3, a3, a6 1146; RV32XTHEADBB-NEXT: .LBB13_3: 1147; RV32XTHEADBB-NEXT: srai t0, a5, 31 1148; RV32XTHEADBB-NEXT: neg a5, a2 1149; RV32XTHEADBB-NEXT: andi a7, a5, 63 1150; RV32XTHEADBB-NEXT: addi a6, a7, -32 1151; RV32XTHEADBB-NEXT: and a2, t0, a4 1152; RV32XTHEADBB-NEXT: bltz a6, .LBB13_5 1153; RV32XTHEADBB-NEXT: # %bb.4: 1154; RV32XTHEADBB-NEXT: sll a1, a0, a7 1155; RV32XTHEADBB-NEXT: j .LBB13_6 1156; RV32XTHEADBB-NEXT: .LBB13_5: 1157; RV32XTHEADBB-NEXT: sll a1, a1, a5 1158; RV32XTHEADBB-NEXT: not a4, a7 1159; RV32XTHEADBB-NEXT: srli a7, a0, 1 1160; RV32XTHEADBB-NEXT: srl a4, a7, a4 1161; RV32XTHEADBB-NEXT: or a1, a1, a4 1162; RV32XTHEADBB-NEXT: .LBB13_6: 1163; RV32XTHEADBB-NEXT: sll a0, a0, a5 1164; RV32XTHEADBB-NEXT: srai a4, a6, 31 1165; RV32XTHEADBB-NEXT: and a0, a4, a0 1166; RV32XTHEADBB-NEXT: or a0, a3, a0 1167; RV32XTHEADBB-NEXT: or a1, a2, a1 1168; RV32XTHEADBB-NEXT: ret 1169; 1170; RV64XTHEADBB-LABEL: rotr_64_mask: 1171; RV64XTHEADBB: # %bb.0: 1172; RV64XTHEADBB-NEXT: srl a2, a0, a1 1173; RV64XTHEADBB-NEXT: negw a1, a1 1174; RV64XTHEADBB-NEXT: sll a0, a0, a1 1175; RV64XTHEADBB-NEXT: or a0, a2, a0 1176; RV64XTHEADBB-NEXT: ret 1177 %z = sub i64 0, %y 1178 %and = and i64 %z, 63 1179 %b = lshr i64 %x, %y 1180 %c = shl i64 %x, %and 1181 %d = or i64 %b, %c 1182 ret i64 %d 1183} 1184 1185define i64 @rotr_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind { 1186; RV32I-LABEL: rotr_64_mask_and_127_and_63: 1187; RV32I: # %bb.0: 1188; RV32I-NEXT: andi a3, a2, 127 1189; RV32I-NEXT: addi a4, a3, -32 1190; RV32I-NEXT: bltz a4, .LBB14_2 1191; RV32I-NEXT: # %bb.1: 1192; RV32I-NEXT: srl a3, a1, a3 1193; RV32I-NEXT: j .LBB14_3 1194; RV32I-NEXT: .LBB14_2: 1195; RV32I-NEXT: srl a5, a0, a2 1196; RV32I-NEXT: slli a6, a1, 1 1197; RV32I-NEXT: not a3, a3 1198; RV32I-NEXT: sll a3, a6, a3 1199; RV32I-NEXT: or a3, a5, a3 1200; RV32I-NEXT: .LBB14_3: 1201; RV32I-NEXT: srl a7, a1, a2 1202; RV32I-NEXT: srai t0, a4, 31 1203; RV32I-NEXT: neg a4, a2 1204; RV32I-NEXT: andi a6, a4, 63 1205; RV32I-NEXT: addi a5, a6, -32 1206; RV32I-NEXT: and a2, t0, a7 1207; RV32I-NEXT: bltz a5, .LBB14_5 1208; RV32I-NEXT: # %bb.4: 1209; RV32I-NEXT: sll a1, a0, a6 1210; RV32I-NEXT: j .LBB14_6 1211; RV32I-NEXT: .LBB14_5: 1212; RV32I-NEXT: sll a1, a1, a4 1213; RV32I-NEXT: not a6, a6 1214; RV32I-NEXT: srli a7, a0, 1 1215; RV32I-NEXT: srl a6, a7, a6 1216; RV32I-NEXT: or a1, a1, a6 1217; RV32I-NEXT: .LBB14_6: 1218; RV32I-NEXT: sll a0, a0, a4 1219; RV32I-NEXT: srai a5, a5, 31 1220; RV32I-NEXT: and a0, a5, a0 1221; RV32I-NEXT: or a0, a3, a0 1222; RV32I-NEXT: or a1, a2, a1 1223; RV32I-NEXT: ret 1224; 1225; RV64I-LABEL: rotr_64_mask_and_127_and_63: 1226; RV64I: # %bb.0: 1227; RV64I-NEXT: srl a2, a0, a1 1228; RV64I-NEXT: negw a1, a1 1229; RV64I-NEXT: sll a0, a0, a1 1230; RV64I-NEXT: or a0, a2, a0 1231; RV64I-NEXT: ret 1232; 1233; RV32ZBB-LABEL: rotr_64_mask_and_127_and_63: 1234; RV32ZBB: # %bb.0: 1235; RV32ZBB-NEXT: andi a3, a2, 127 1236; RV32ZBB-NEXT: addi a4, a3, -32 1237; RV32ZBB-NEXT: bltz a4, .LBB14_2 1238; RV32ZBB-NEXT: # %bb.1: 1239; RV32ZBB-NEXT: srl a3, a1, a3 1240; RV32ZBB-NEXT: j .LBB14_3 1241; RV32ZBB-NEXT: .LBB14_2: 1242; RV32ZBB-NEXT: srl a5, a0, a2 1243; RV32ZBB-NEXT: slli a6, a1, 1 1244; RV32ZBB-NEXT: not a3, a3 1245; RV32ZBB-NEXT: sll a3, a6, a3 1246; RV32ZBB-NEXT: or a3, a5, a3 1247; RV32ZBB-NEXT: .LBB14_3: 1248; RV32ZBB-NEXT: srl a7, a1, a2 1249; RV32ZBB-NEXT: srai t0, a4, 31 1250; RV32ZBB-NEXT: neg a4, a2 1251; RV32ZBB-NEXT: andi a6, a4, 63 1252; RV32ZBB-NEXT: addi a5, a6, -32 1253; RV32ZBB-NEXT: and a2, t0, a7 1254; RV32ZBB-NEXT: bltz a5, .LBB14_5 1255; RV32ZBB-NEXT: # %bb.4: 1256; RV32ZBB-NEXT: sll a1, a0, a6 1257; RV32ZBB-NEXT: j .LBB14_6 1258; RV32ZBB-NEXT: .LBB14_5: 1259; RV32ZBB-NEXT: sll a1, a1, a4 1260; RV32ZBB-NEXT: not a6, a6 1261; RV32ZBB-NEXT: srli a7, a0, 1 1262; RV32ZBB-NEXT: srl a6, a7, a6 1263; RV32ZBB-NEXT: or a1, a1, a6 1264; RV32ZBB-NEXT: .LBB14_6: 1265; RV32ZBB-NEXT: sll a0, a0, a4 1266; RV32ZBB-NEXT: srai a5, a5, 31 1267; RV32ZBB-NEXT: and a0, a5, a0 1268; RV32ZBB-NEXT: or a0, a3, a0 1269; RV32ZBB-NEXT: or a1, a2, a1 1270; RV32ZBB-NEXT: ret 1271; 1272; RV64ZBB-LABEL: rotr_64_mask_and_127_and_63: 1273; RV64ZBB: # %bb.0: 1274; RV64ZBB-NEXT: ror a0, a0, a1 1275; RV64ZBB-NEXT: ret 1276; 1277; RV32XTHEADBB-LABEL: rotr_64_mask_and_127_and_63: 1278; RV32XTHEADBB: # %bb.0: 1279; RV32XTHEADBB-NEXT: andi a3, a2, 127 1280; RV32XTHEADBB-NEXT: addi a4, a3, -32 1281; RV32XTHEADBB-NEXT: bltz a4, .LBB14_2 1282; RV32XTHEADBB-NEXT: # %bb.1: 1283; RV32XTHEADBB-NEXT: srl a3, a1, a3 1284; RV32XTHEADBB-NEXT: j .LBB14_3 1285; RV32XTHEADBB-NEXT: .LBB14_2: 1286; RV32XTHEADBB-NEXT: srl a5, a0, a2 1287; RV32XTHEADBB-NEXT: slli a6, a1, 1 1288; RV32XTHEADBB-NEXT: not a3, a3 1289; RV32XTHEADBB-NEXT: sll a3, a6, a3 1290; RV32XTHEADBB-NEXT: or a3, a5, a3 1291; RV32XTHEADBB-NEXT: .LBB14_3: 1292; RV32XTHEADBB-NEXT: srl a7, a1, a2 1293; RV32XTHEADBB-NEXT: srai t0, a4, 31 1294; RV32XTHEADBB-NEXT: neg a4, a2 1295; RV32XTHEADBB-NEXT: andi a6, a4, 63 1296; RV32XTHEADBB-NEXT: addi a5, a6, -32 1297; RV32XTHEADBB-NEXT: and a2, t0, a7 1298; RV32XTHEADBB-NEXT: bltz a5, .LBB14_5 1299; RV32XTHEADBB-NEXT: # %bb.4: 1300; RV32XTHEADBB-NEXT: sll a1, a0, a6 1301; RV32XTHEADBB-NEXT: j .LBB14_6 1302; RV32XTHEADBB-NEXT: .LBB14_5: 1303; RV32XTHEADBB-NEXT: sll a1, a1, a4 1304; RV32XTHEADBB-NEXT: not a6, a6 1305; RV32XTHEADBB-NEXT: srli a7, a0, 1 1306; RV32XTHEADBB-NEXT: srl a6, a7, a6 1307; RV32XTHEADBB-NEXT: or a1, a1, a6 1308; RV32XTHEADBB-NEXT: .LBB14_6: 1309; RV32XTHEADBB-NEXT: sll a0, a0, a4 1310; RV32XTHEADBB-NEXT: srai a5, a5, 31 1311; RV32XTHEADBB-NEXT: and a0, a5, a0 1312; RV32XTHEADBB-NEXT: or a0, a3, a0 1313; RV32XTHEADBB-NEXT: or a1, a2, a1 1314; RV32XTHEADBB-NEXT: ret 1315; 1316; RV64XTHEADBB-LABEL: rotr_64_mask_and_127_and_63: 1317; RV64XTHEADBB: # %bb.0: 1318; RV64XTHEADBB-NEXT: srl a2, a0, a1 1319; RV64XTHEADBB-NEXT: negw a1, a1 1320; RV64XTHEADBB-NEXT: sll a0, a0, a1 1321; RV64XTHEADBB-NEXT: or a0, a2, a0 1322; RV64XTHEADBB-NEXT: ret 1323 %a = and i64 %y, 127 1324 %b = lshr i64 %x, %a 1325 %c = sub i64 0, %y 1326 %d = and i64 %c, 63 1327 %e = shl i64 %x, %d 1328 %f = or i64 %b, %e 1329 ret i64 %f 1330} 1331 1332define i64 @rotr_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind { 1333; RV32I-LABEL: rotr_64_mask_or_128_or_64: 1334; RV32I: # %bb.0: 1335; RV32I-NEXT: li a0, 0 1336; RV32I-NEXT: li a1, 0 1337; RV32I-NEXT: ret 1338; 1339; RV64I-LABEL: rotr_64_mask_or_128_or_64: 1340; RV64I: # %bb.0: 1341; RV64I-NEXT: li a0, 0 1342; RV64I-NEXT: ret 1343; 1344; RV32ZBB-LABEL: rotr_64_mask_or_128_or_64: 1345; RV32ZBB: # %bb.0: 1346; RV32ZBB-NEXT: li a0, 0 1347; RV32ZBB-NEXT: li a1, 0 1348; RV32ZBB-NEXT: ret 1349; 1350; RV64ZBB-LABEL: rotr_64_mask_or_128_or_64: 1351; RV64ZBB: # %bb.0: 1352; RV64ZBB-NEXT: ror a0, a0, a1 1353; RV64ZBB-NEXT: ret 1354; 1355; RV32XTHEADBB-LABEL: rotr_64_mask_or_128_or_64: 1356; RV32XTHEADBB: # %bb.0: 1357; RV32XTHEADBB-NEXT: li a0, 0 1358; RV32XTHEADBB-NEXT: li a1, 0 1359; RV32XTHEADBB-NEXT: ret 1360; 1361; RV64XTHEADBB-LABEL: rotr_64_mask_or_128_or_64: 1362; RV64XTHEADBB: # %bb.0: 1363; RV64XTHEADBB-NEXT: srl a2, a0, a1 1364; RV64XTHEADBB-NEXT: negw a1, a1 1365; RV64XTHEADBB-NEXT: sll a0, a0, a1 1366; RV64XTHEADBB-NEXT: or a0, a2, a0 1367; RV64XTHEADBB-NEXT: ret 1368 %a = or i64 %y, 128 1369 %b = lshr i64 %x, %a 1370 %c = sub i64 0, %y 1371 %d = or i64 %c, 64 1372 %e = shl i64 %x, %d 1373 %f = or i64 %b, %e 1374 ret i64 %f 1375} 1376 1377; Test that we're able to remove a mask on the rotate amount that has more than 1378; one use. 1379define signext i32 @rotl_32_mask_shared(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind { 1380; RV32I-LABEL: rotl_32_mask_shared: 1381; RV32I: # %bb.0: 1382; RV32I-NEXT: sll a3, a0, a2 1383; RV32I-NEXT: neg a4, a2 1384; RV32I-NEXT: srl a0, a0, a4 1385; RV32I-NEXT: or a0, a3, a0 1386; RV32I-NEXT: sll a1, a1, a2 1387; RV32I-NEXT: add a0, a0, a1 1388; RV32I-NEXT: ret 1389; 1390; RV64I-LABEL: rotl_32_mask_shared: 1391; RV64I: # %bb.0: 1392; RV64I-NEXT: sllw a3, a0, a2 1393; RV64I-NEXT: negw a4, a2 1394; RV64I-NEXT: srlw a0, a0, a4 1395; RV64I-NEXT: or a0, a3, a0 1396; RV64I-NEXT: sllw a1, a1, a2 1397; RV64I-NEXT: addw a0, a0, a1 1398; RV64I-NEXT: ret 1399; 1400; RV32ZBB-LABEL: rotl_32_mask_shared: 1401; RV32ZBB: # %bb.0: 1402; RV32ZBB-NEXT: rol a0, a0, a2 1403; RV32ZBB-NEXT: sll a1, a1, a2 1404; RV32ZBB-NEXT: add a0, a0, a1 1405; RV32ZBB-NEXT: ret 1406; 1407; RV64ZBB-LABEL: rotl_32_mask_shared: 1408; RV64ZBB: # %bb.0: 1409; RV64ZBB-NEXT: rolw a0, a0, a2 1410; RV64ZBB-NEXT: sllw a1, a1, a2 1411; RV64ZBB-NEXT: addw a0, a0, a1 1412; RV64ZBB-NEXT: ret 1413; 1414; RV32XTHEADBB-LABEL: rotl_32_mask_shared: 1415; RV32XTHEADBB: # %bb.0: 1416; RV32XTHEADBB-NEXT: sll a3, a0, a2 1417; RV32XTHEADBB-NEXT: neg a4, a2 1418; RV32XTHEADBB-NEXT: srl a0, a0, a4 1419; RV32XTHEADBB-NEXT: or a0, a3, a0 1420; RV32XTHEADBB-NEXT: sll a1, a1, a2 1421; RV32XTHEADBB-NEXT: add a0, a0, a1 1422; RV32XTHEADBB-NEXT: ret 1423; 1424; RV64XTHEADBB-LABEL: rotl_32_mask_shared: 1425; RV64XTHEADBB: # %bb.0: 1426; RV64XTHEADBB-NEXT: sllw a3, a0, a2 1427; RV64XTHEADBB-NEXT: negw a4, a2 1428; RV64XTHEADBB-NEXT: srlw a0, a0, a4 1429; RV64XTHEADBB-NEXT: or a0, a3, a0 1430; RV64XTHEADBB-NEXT: sllw a1, a1, a2 1431; RV64XTHEADBB-NEXT: addw a0, a0, a1 1432; RV64XTHEADBB-NEXT: ret 1433 %maskedamt = and i32 %amt, 31 1434 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %maskedamt) 1435 %2 = shl i32 %b, %maskedamt 1436 %3 = add i32 %1, %2 1437 ret i32 %3 1438} 1439declare i32 @llvm.fshl.i32(i32, i32, i32) 1440 1441define signext i64 @rotl_64_mask_shared(i64 signext %a, i64 signext %b, i64 signext %amt) nounwind { 1442; RV32I-LABEL: rotl_64_mask_shared: 1443; RV32I: # %bb.0: 1444; RV32I-NEXT: slli a5, a4, 26 1445; RV32I-NEXT: srli t0, a5, 31 1446; RV32I-NEXT: mv a6, a0 1447; RV32I-NEXT: bnez t0, .LBB17_2 1448; RV32I-NEXT: # %bb.1: 1449; RV32I-NEXT: mv a6, a1 1450; RV32I-NEXT: .LBB17_2: 1451; RV32I-NEXT: andi a5, a4, 63 1452; RV32I-NEXT: sll a7, a6, a4 1453; RV32I-NEXT: bnez t0, .LBB17_4 1454; RV32I-NEXT: # %bb.3: 1455; RV32I-NEXT: mv a1, a0 1456; RV32I-NEXT: .LBB17_4: 1457; RV32I-NEXT: srli a0, a1, 1 1458; RV32I-NEXT: not t0, a4 1459; RV32I-NEXT: sll t1, a1, a4 1460; RV32I-NEXT: srli a1, a6, 1 1461; RV32I-NEXT: srl a6, a0, t0 1462; RV32I-NEXT: srl t0, a1, t0 1463; RV32I-NEXT: addi a0, a5, -32 1464; RV32I-NEXT: or a1, a7, a6 1465; RV32I-NEXT: or a6, t1, t0 1466; RV32I-NEXT: bltz a0, .LBB17_6 1467; RV32I-NEXT: # %bb.5: 1468; RV32I-NEXT: sll a3, a2, a5 1469; RV32I-NEXT: j .LBB17_7 1470; RV32I-NEXT: .LBB17_6: 1471; RV32I-NEXT: sll a3, a3, a4 1472; RV32I-NEXT: srli a7, a2, 1 1473; RV32I-NEXT: not a5, a5 1474; RV32I-NEXT: srl a5, a7, a5 1475; RV32I-NEXT: or a3, a3, a5 1476; RV32I-NEXT: .LBB17_7: 1477; RV32I-NEXT: sll a2, a2, a4 1478; RV32I-NEXT: srai a0, a0, 31 1479; RV32I-NEXT: and a0, a0, a2 1480; RV32I-NEXT: add a0, a6, a0 1481; RV32I-NEXT: sltu a2, a0, a6 1482; RV32I-NEXT: add a1, a1, a3 1483; RV32I-NEXT: add a1, a1, a2 1484; RV32I-NEXT: ret 1485; 1486; RV64I-LABEL: rotl_64_mask_shared: 1487; RV64I: # %bb.0: 1488; RV64I-NEXT: sll a3, a0, a2 1489; RV64I-NEXT: negw a4, a2 1490; RV64I-NEXT: srl a0, a0, a4 1491; RV64I-NEXT: or a0, a3, a0 1492; RV64I-NEXT: sll a1, a1, a2 1493; RV64I-NEXT: add a0, a0, a1 1494; RV64I-NEXT: ret 1495; 1496; RV32ZBB-LABEL: rotl_64_mask_shared: 1497; RV32ZBB: # %bb.0: 1498; RV32ZBB-NEXT: slli a5, a4, 26 1499; RV32ZBB-NEXT: srli t0, a5, 31 1500; RV32ZBB-NEXT: mv a6, a0 1501; RV32ZBB-NEXT: bnez t0, .LBB17_2 1502; RV32ZBB-NEXT: # %bb.1: 1503; RV32ZBB-NEXT: mv a6, a1 1504; RV32ZBB-NEXT: .LBB17_2: 1505; RV32ZBB-NEXT: andi a5, a4, 63 1506; RV32ZBB-NEXT: sll a7, a6, a4 1507; RV32ZBB-NEXT: bnez t0, .LBB17_4 1508; RV32ZBB-NEXT: # %bb.3: 1509; RV32ZBB-NEXT: mv a1, a0 1510; RV32ZBB-NEXT: .LBB17_4: 1511; RV32ZBB-NEXT: srli a0, a1, 1 1512; RV32ZBB-NEXT: not t0, a4 1513; RV32ZBB-NEXT: sll t1, a1, a4 1514; RV32ZBB-NEXT: srli a1, a6, 1 1515; RV32ZBB-NEXT: srl a6, a0, t0 1516; RV32ZBB-NEXT: srl t0, a1, t0 1517; RV32ZBB-NEXT: addi a0, a5, -32 1518; RV32ZBB-NEXT: or a1, a7, a6 1519; RV32ZBB-NEXT: or a6, t1, t0 1520; RV32ZBB-NEXT: bltz a0, .LBB17_6 1521; RV32ZBB-NEXT: # %bb.5: 1522; RV32ZBB-NEXT: sll a3, a2, a5 1523; RV32ZBB-NEXT: j .LBB17_7 1524; RV32ZBB-NEXT: .LBB17_6: 1525; RV32ZBB-NEXT: sll a3, a3, a4 1526; RV32ZBB-NEXT: srli a7, a2, 1 1527; RV32ZBB-NEXT: not a5, a5 1528; RV32ZBB-NEXT: srl a5, a7, a5 1529; RV32ZBB-NEXT: or a3, a3, a5 1530; RV32ZBB-NEXT: .LBB17_7: 1531; RV32ZBB-NEXT: sll a2, a2, a4 1532; RV32ZBB-NEXT: srai a0, a0, 31 1533; RV32ZBB-NEXT: and a0, a0, a2 1534; RV32ZBB-NEXT: add a0, a6, a0 1535; RV32ZBB-NEXT: sltu a2, a0, a6 1536; RV32ZBB-NEXT: add a1, a1, a3 1537; RV32ZBB-NEXT: add a1, a1, a2 1538; RV32ZBB-NEXT: ret 1539; 1540; RV64ZBB-LABEL: rotl_64_mask_shared: 1541; RV64ZBB: # %bb.0: 1542; RV64ZBB-NEXT: rol a0, a0, a2 1543; RV64ZBB-NEXT: sll a1, a1, a2 1544; RV64ZBB-NEXT: add a0, a0, a1 1545; RV64ZBB-NEXT: ret 1546; 1547; RV32XTHEADBB-LABEL: rotl_64_mask_shared: 1548; RV32XTHEADBB: # %bb.0: 1549; RV32XTHEADBB-NEXT: th.extu t0, a4, 5, 5 1550; RV32XTHEADBB-NEXT: mv a6, a0 1551; RV32XTHEADBB-NEXT: bnez t0, .LBB17_2 1552; RV32XTHEADBB-NEXT: # %bb.1: 1553; RV32XTHEADBB-NEXT: mv a6, a1 1554; RV32XTHEADBB-NEXT: .LBB17_2: 1555; RV32XTHEADBB-NEXT: andi a5, a4, 63 1556; RV32XTHEADBB-NEXT: sll a7, a6, a4 1557; RV32XTHEADBB-NEXT: bnez t0, .LBB17_4 1558; RV32XTHEADBB-NEXT: # %bb.3: 1559; RV32XTHEADBB-NEXT: mv a1, a0 1560; RV32XTHEADBB-NEXT: .LBB17_4: 1561; RV32XTHEADBB-NEXT: srli a0, a1, 1 1562; RV32XTHEADBB-NEXT: not t0, a4 1563; RV32XTHEADBB-NEXT: sll t1, a1, a4 1564; RV32XTHEADBB-NEXT: srli a1, a6, 1 1565; RV32XTHEADBB-NEXT: srl a6, a0, t0 1566; RV32XTHEADBB-NEXT: srl t0, a1, t0 1567; RV32XTHEADBB-NEXT: addi a0, a5, -32 1568; RV32XTHEADBB-NEXT: or a1, a7, a6 1569; RV32XTHEADBB-NEXT: or a6, t1, t0 1570; RV32XTHEADBB-NEXT: bltz a0, .LBB17_6 1571; RV32XTHEADBB-NEXT: # %bb.5: 1572; RV32XTHEADBB-NEXT: sll a3, a2, a5 1573; RV32XTHEADBB-NEXT: j .LBB17_7 1574; RV32XTHEADBB-NEXT: .LBB17_6: 1575; RV32XTHEADBB-NEXT: sll a3, a3, a4 1576; RV32XTHEADBB-NEXT: srli a7, a2, 1 1577; RV32XTHEADBB-NEXT: not a5, a5 1578; RV32XTHEADBB-NEXT: srl a5, a7, a5 1579; RV32XTHEADBB-NEXT: or a3, a3, a5 1580; RV32XTHEADBB-NEXT: .LBB17_7: 1581; RV32XTHEADBB-NEXT: sll a2, a2, a4 1582; RV32XTHEADBB-NEXT: srai a0, a0, 31 1583; RV32XTHEADBB-NEXT: and a0, a0, a2 1584; RV32XTHEADBB-NEXT: add a0, a6, a0 1585; RV32XTHEADBB-NEXT: sltu a2, a0, a6 1586; RV32XTHEADBB-NEXT: add a1, a1, a3 1587; RV32XTHEADBB-NEXT: add a1, a1, a2 1588; RV32XTHEADBB-NEXT: ret 1589; 1590; RV64XTHEADBB-LABEL: rotl_64_mask_shared: 1591; RV64XTHEADBB: # %bb.0: 1592; RV64XTHEADBB-NEXT: sll a3, a0, a2 1593; RV64XTHEADBB-NEXT: negw a4, a2 1594; RV64XTHEADBB-NEXT: srl a0, a0, a4 1595; RV64XTHEADBB-NEXT: or a0, a3, a0 1596; RV64XTHEADBB-NEXT: sll a1, a1, a2 1597; RV64XTHEADBB-NEXT: add a0, a0, a1 1598; RV64XTHEADBB-NEXT: ret 1599 %maskedamt = and i64 %amt, 63 1600 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %maskedamt) 1601 %2 = shl i64 %b, %maskedamt 1602 %3 = add i64 %1, %2 1603 ret i64 %3 1604} 1605declare i64 @llvm.fshl.i64(i64, i64, i64) 1606 1607define signext i32 @rotr_32_mask_shared(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind { 1608; RV32I-LABEL: rotr_32_mask_shared: 1609; RV32I: # %bb.0: 1610; RV32I-NEXT: srl a3, a0, a2 1611; RV32I-NEXT: neg a4, a2 1612; RV32I-NEXT: sll a0, a0, a4 1613; RV32I-NEXT: or a0, a3, a0 1614; RV32I-NEXT: sll a1, a1, a2 1615; RV32I-NEXT: add a0, a0, a1 1616; RV32I-NEXT: ret 1617; 1618; RV64I-LABEL: rotr_32_mask_shared: 1619; RV64I: # %bb.0: 1620; RV64I-NEXT: srlw a3, a0, a2 1621; RV64I-NEXT: negw a4, a2 1622; RV64I-NEXT: sllw a0, a0, a4 1623; RV64I-NEXT: or a0, a3, a0 1624; RV64I-NEXT: sllw a1, a1, a2 1625; RV64I-NEXT: addw a0, a0, a1 1626; RV64I-NEXT: ret 1627; 1628; RV32ZBB-LABEL: rotr_32_mask_shared: 1629; RV32ZBB: # %bb.0: 1630; RV32ZBB-NEXT: ror a0, a0, a2 1631; RV32ZBB-NEXT: sll a1, a1, a2 1632; RV32ZBB-NEXT: add a0, a0, a1 1633; RV32ZBB-NEXT: ret 1634; 1635; RV64ZBB-LABEL: rotr_32_mask_shared: 1636; RV64ZBB: # %bb.0: 1637; RV64ZBB-NEXT: rorw a0, a0, a2 1638; RV64ZBB-NEXT: sllw a1, a1, a2 1639; RV64ZBB-NEXT: addw a0, a0, a1 1640; RV64ZBB-NEXT: ret 1641; 1642; RV32XTHEADBB-LABEL: rotr_32_mask_shared: 1643; RV32XTHEADBB: # %bb.0: 1644; RV32XTHEADBB-NEXT: srl a3, a0, a2 1645; RV32XTHEADBB-NEXT: neg a4, a2 1646; RV32XTHEADBB-NEXT: sll a0, a0, a4 1647; RV32XTHEADBB-NEXT: or a0, a3, a0 1648; RV32XTHEADBB-NEXT: sll a1, a1, a2 1649; RV32XTHEADBB-NEXT: add a0, a0, a1 1650; RV32XTHEADBB-NEXT: ret 1651; 1652; RV64XTHEADBB-LABEL: rotr_32_mask_shared: 1653; RV64XTHEADBB: # %bb.0: 1654; RV64XTHEADBB-NEXT: srlw a3, a0, a2 1655; RV64XTHEADBB-NEXT: negw a4, a2 1656; RV64XTHEADBB-NEXT: sllw a0, a0, a4 1657; RV64XTHEADBB-NEXT: or a0, a3, a0 1658; RV64XTHEADBB-NEXT: sllw a1, a1, a2 1659; RV64XTHEADBB-NEXT: addw a0, a0, a1 1660; RV64XTHEADBB-NEXT: ret 1661 %maskedamt = and i32 %amt, 31 1662 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %maskedamt) 1663 %2 = shl i32 %b, %maskedamt 1664 %3 = add i32 %1, %2 1665 ret i32 %3 1666} 1667declare i32 @llvm.fshr.i32(i32, i32, i32) 1668 1669define signext i64 @rotr_64_mask_shared(i64 signext %a, i64 signext %b, i64 signext %amt) nounwind { 1670; RV32I-LABEL: rotr_64_mask_shared: 1671; RV32I: # %bb.0: 1672; RV32I-NEXT: andi t0, a4, 32 1673; RV32I-NEXT: mv a6, a1 1674; RV32I-NEXT: beqz t0, .LBB19_2 1675; RV32I-NEXT: # %bb.1: 1676; RV32I-NEXT: mv a6, a0 1677; RV32I-NEXT: .LBB19_2: 1678; RV32I-NEXT: andi a5, a4, 63 1679; RV32I-NEXT: srl a7, a6, a4 1680; RV32I-NEXT: beqz t0, .LBB19_4 1681; RV32I-NEXT: # %bb.3: 1682; RV32I-NEXT: mv a0, a1 1683; RV32I-NEXT: .LBB19_4: 1684; RV32I-NEXT: slli a1, a0, 1 1685; RV32I-NEXT: not t0, a4 1686; RV32I-NEXT: srl t1, a0, a4 1687; RV32I-NEXT: slli a6, a6, 1 1688; RV32I-NEXT: sll a1, a1, t0 1689; RV32I-NEXT: sll a6, a6, t0 1690; RV32I-NEXT: addi a0, a5, -32 1691; RV32I-NEXT: or a1, a1, a7 1692; RV32I-NEXT: or a6, a6, t1 1693; RV32I-NEXT: bltz a0, .LBB19_6 1694; RV32I-NEXT: # %bb.5: 1695; RV32I-NEXT: sll a3, a2, a5 1696; RV32I-NEXT: j .LBB19_7 1697; RV32I-NEXT: .LBB19_6: 1698; RV32I-NEXT: sll a3, a3, a4 1699; RV32I-NEXT: srli a7, a2, 1 1700; RV32I-NEXT: not a5, a5 1701; RV32I-NEXT: srl a5, a7, a5 1702; RV32I-NEXT: or a3, a3, a5 1703; RV32I-NEXT: .LBB19_7: 1704; RV32I-NEXT: sll a2, a2, a4 1705; RV32I-NEXT: srai a0, a0, 31 1706; RV32I-NEXT: and a0, a0, a2 1707; RV32I-NEXT: add a0, a6, a0 1708; RV32I-NEXT: sltu a2, a0, a6 1709; RV32I-NEXT: add a1, a1, a3 1710; RV32I-NEXT: add a1, a1, a2 1711; RV32I-NEXT: ret 1712; 1713; RV64I-LABEL: rotr_64_mask_shared: 1714; RV64I: # %bb.0: 1715; RV64I-NEXT: srl a3, a0, a2 1716; RV64I-NEXT: negw a4, a2 1717; RV64I-NEXT: sll a0, a0, a4 1718; RV64I-NEXT: or a0, a3, a0 1719; RV64I-NEXT: sll a1, a1, a2 1720; RV64I-NEXT: add a0, a0, a1 1721; RV64I-NEXT: ret 1722; 1723; RV32ZBB-LABEL: rotr_64_mask_shared: 1724; RV32ZBB: # %bb.0: 1725; RV32ZBB-NEXT: andi t0, a4, 32 1726; RV32ZBB-NEXT: mv a6, a1 1727; RV32ZBB-NEXT: beqz t0, .LBB19_2 1728; RV32ZBB-NEXT: # %bb.1: 1729; RV32ZBB-NEXT: mv a6, a0 1730; RV32ZBB-NEXT: .LBB19_2: 1731; RV32ZBB-NEXT: andi a5, a4, 63 1732; RV32ZBB-NEXT: srl a7, a6, a4 1733; RV32ZBB-NEXT: beqz t0, .LBB19_4 1734; RV32ZBB-NEXT: # %bb.3: 1735; RV32ZBB-NEXT: mv a0, a1 1736; RV32ZBB-NEXT: .LBB19_4: 1737; RV32ZBB-NEXT: slli a1, a0, 1 1738; RV32ZBB-NEXT: not t0, a4 1739; RV32ZBB-NEXT: srl t1, a0, a4 1740; RV32ZBB-NEXT: slli a6, a6, 1 1741; RV32ZBB-NEXT: sll a1, a1, t0 1742; RV32ZBB-NEXT: sll a6, a6, t0 1743; RV32ZBB-NEXT: addi a0, a5, -32 1744; RV32ZBB-NEXT: or a1, a1, a7 1745; RV32ZBB-NEXT: or a6, a6, t1 1746; RV32ZBB-NEXT: bltz a0, .LBB19_6 1747; RV32ZBB-NEXT: # %bb.5: 1748; RV32ZBB-NEXT: sll a3, a2, a5 1749; RV32ZBB-NEXT: j .LBB19_7 1750; RV32ZBB-NEXT: .LBB19_6: 1751; RV32ZBB-NEXT: sll a3, a3, a4 1752; RV32ZBB-NEXT: srli a7, a2, 1 1753; RV32ZBB-NEXT: not a5, a5 1754; RV32ZBB-NEXT: srl a5, a7, a5 1755; RV32ZBB-NEXT: or a3, a3, a5 1756; RV32ZBB-NEXT: .LBB19_7: 1757; RV32ZBB-NEXT: sll a2, a2, a4 1758; RV32ZBB-NEXT: srai a0, a0, 31 1759; RV32ZBB-NEXT: and a0, a0, a2 1760; RV32ZBB-NEXT: add a0, a6, a0 1761; RV32ZBB-NEXT: sltu a2, a0, a6 1762; RV32ZBB-NEXT: add a1, a1, a3 1763; RV32ZBB-NEXT: add a1, a1, a2 1764; RV32ZBB-NEXT: ret 1765; 1766; RV64ZBB-LABEL: rotr_64_mask_shared: 1767; RV64ZBB: # %bb.0: 1768; RV64ZBB-NEXT: ror a0, a0, a2 1769; RV64ZBB-NEXT: sll a1, a1, a2 1770; RV64ZBB-NEXT: add a0, a0, a1 1771; RV64ZBB-NEXT: ret 1772; 1773; RV32XTHEADBB-LABEL: rotr_64_mask_shared: 1774; RV32XTHEADBB: # %bb.0: 1775; RV32XTHEADBB-NEXT: andi t0, a4, 32 1776; RV32XTHEADBB-NEXT: mv a6, a1 1777; RV32XTHEADBB-NEXT: beqz t0, .LBB19_2 1778; RV32XTHEADBB-NEXT: # %bb.1: 1779; RV32XTHEADBB-NEXT: mv a6, a0 1780; RV32XTHEADBB-NEXT: .LBB19_2: 1781; RV32XTHEADBB-NEXT: andi a5, a4, 63 1782; RV32XTHEADBB-NEXT: srl a7, a6, a4 1783; RV32XTHEADBB-NEXT: beqz t0, .LBB19_4 1784; RV32XTHEADBB-NEXT: # %bb.3: 1785; RV32XTHEADBB-NEXT: mv a0, a1 1786; RV32XTHEADBB-NEXT: .LBB19_4: 1787; RV32XTHEADBB-NEXT: slli a1, a0, 1 1788; RV32XTHEADBB-NEXT: not t0, a4 1789; RV32XTHEADBB-NEXT: srl t1, a0, a4 1790; RV32XTHEADBB-NEXT: slli a6, a6, 1 1791; RV32XTHEADBB-NEXT: sll a1, a1, t0 1792; RV32XTHEADBB-NEXT: sll a6, a6, t0 1793; RV32XTHEADBB-NEXT: addi a0, a5, -32 1794; RV32XTHEADBB-NEXT: or a1, a1, a7 1795; RV32XTHEADBB-NEXT: or a6, a6, t1 1796; RV32XTHEADBB-NEXT: bltz a0, .LBB19_6 1797; RV32XTHEADBB-NEXT: # %bb.5: 1798; RV32XTHEADBB-NEXT: sll a3, a2, a5 1799; RV32XTHEADBB-NEXT: j .LBB19_7 1800; RV32XTHEADBB-NEXT: .LBB19_6: 1801; RV32XTHEADBB-NEXT: sll a3, a3, a4 1802; RV32XTHEADBB-NEXT: srli a7, a2, 1 1803; RV32XTHEADBB-NEXT: not a5, a5 1804; RV32XTHEADBB-NEXT: srl a5, a7, a5 1805; RV32XTHEADBB-NEXT: or a3, a3, a5 1806; RV32XTHEADBB-NEXT: .LBB19_7: 1807; RV32XTHEADBB-NEXT: sll a2, a2, a4 1808; RV32XTHEADBB-NEXT: srai a0, a0, 31 1809; RV32XTHEADBB-NEXT: and a0, a0, a2 1810; RV32XTHEADBB-NEXT: add a0, a6, a0 1811; RV32XTHEADBB-NEXT: sltu a2, a0, a6 1812; RV32XTHEADBB-NEXT: add a1, a1, a3 1813; RV32XTHEADBB-NEXT: add a1, a1, a2 1814; RV32XTHEADBB-NEXT: ret 1815; 1816; RV64XTHEADBB-LABEL: rotr_64_mask_shared: 1817; RV64XTHEADBB: # %bb.0: 1818; RV64XTHEADBB-NEXT: srl a3, a0, a2 1819; RV64XTHEADBB-NEXT: negw a4, a2 1820; RV64XTHEADBB-NEXT: sll a0, a0, a4 1821; RV64XTHEADBB-NEXT: or a0, a3, a0 1822; RV64XTHEADBB-NEXT: sll a1, a1, a2 1823; RV64XTHEADBB-NEXT: add a0, a0, a1 1824; RV64XTHEADBB-NEXT: ret 1825 %maskedamt = and i64 %amt, 63 1826 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %maskedamt) 1827 %2 = shl i64 %b, %maskedamt 1828 %3 = add i64 %1, %2 1829 ret i64 %3 1830} 1831declare i64 @llvm.fshr.i64(i64, i64, i64) 1832 1833define signext i32 @rotl_32_mask_multiple(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind { 1834; RV32I-LABEL: rotl_32_mask_multiple: 1835; RV32I: # %bb.0: 1836; RV32I-NEXT: sll a3, a0, a2 1837; RV32I-NEXT: neg a4, a2 1838; RV32I-NEXT: sll a2, a1, a2 1839; RV32I-NEXT: srl a0, a0, a4 1840; RV32I-NEXT: srl a1, a1, a4 1841; RV32I-NEXT: or a0, a3, a0 1842; RV32I-NEXT: or a1, a2, a1 1843; RV32I-NEXT: add a0, a0, a1 1844; RV32I-NEXT: ret 1845; 1846; RV64I-LABEL: rotl_32_mask_multiple: 1847; RV64I: # %bb.0: 1848; RV64I-NEXT: sllw a3, a0, a2 1849; RV64I-NEXT: negw a4, a2 1850; RV64I-NEXT: sllw a2, a1, a2 1851; RV64I-NEXT: srlw a0, a0, a4 1852; RV64I-NEXT: srlw a1, a1, a4 1853; RV64I-NEXT: or a0, a3, a0 1854; RV64I-NEXT: or a1, a2, a1 1855; RV64I-NEXT: addw a0, a0, a1 1856; RV64I-NEXT: ret 1857; 1858; RV32ZBB-LABEL: rotl_32_mask_multiple: 1859; RV32ZBB: # %bb.0: 1860; RV32ZBB-NEXT: rol a0, a0, a2 1861; RV32ZBB-NEXT: rol a1, a1, a2 1862; RV32ZBB-NEXT: add a0, a0, a1 1863; RV32ZBB-NEXT: ret 1864; 1865; RV64ZBB-LABEL: rotl_32_mask_multiple: 1866; RV64ZBB: # %bb.0: 1867; RV64ZBB-NEXT: rolw a0, a0, a2 1868; RV64ZBB-NEXT: rolw a1, a1, a2 1869; RV64ZBB-NEXT: addw a0, a0, a1 1870; RV64ZBB-NEXT: ret 1871; 1872; RV32XTHEADBB-LABEL: rotl_32_mask_multiple: 1873; RV32XTHEADBB: # %bb.0: 1874; RV32XTHEADBB-NEXT: sll a3, a0, a2 1875; RV32XTHEADBB-NEXT: neg a4, a2 1876; RV32XTHEADBB-NEXT: sll a2, a1, a2 1877; RV32XTHEADBB-NEXT: srl a0, a0, a4 1878; RV32XTHEADBB-NEXT: srl a1, a1, a4 1879; RV32XTHEADBB-NEXT: or a0, a3, a0 1880; RV32XTHEADBB-NEXT: or a1, a2, a1 1881; RV32XTHEADBB-NEXT: add a0, a0, a1 1882; RV32XTHEADBB-NEXT: ret 1883; 1884; RV64XTHEADBB-LABEL: rotl_32_mask_multiple: 1885; RV64XTHEADBB: # %bb.0: 1886; RV64XTHEADBB-NEXT: sllw a3, a0, a2 1887; RV64XTHEADBB-NEXT: negw a4, a2 1888; RV64XTHEADBB-NEXT: sllw a2, a1, a2 1889; RV64XTHEADBB-NEXT: srlw a0, a0, a4 1890; RV64XTHEADBB-NEXT: srlw a1, a1, a4 1891; RV64XTHEADBB-NEXT: or a0, a3, a0 1892; RV64XTHEADBB-NEXT: or a1, a2, a1 1893; RV64XTHEADBB-NEXT: addw a0, a0, a1 1894; RV64XTHEADBB-NEXT: ret 1895 %maskedamt = and i32 %amt, 31 1896 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %maskedamt) 1897 %2 = tail call i32 @llvm.fshl.i32(i32 %b, i32 %b, i32 %maskedamt) 1898 %3 = add i32 %1, %2 1899 ret i32 %3 1900} 1901 1902define i64 @rotl_64_mask_multiple(i64 %a, i64 %b, i64 %amt) nounwind { 1903; RV32I-LABEL: rotl_64_mask_multiple: 1904; RV32I: # %bb.0: 1905; RV32I-NEXT: slli a5, a4, 26 1906; RV32I-NEXT: srli a5, a5, 31 1907; RV32I-NEXT: mv a6, a1 1908; RV32I-NEXT: bnez a5, .LBB21_2 1909; RV32I-NEXT: # %bb.1: 1910; RV32I-NEXT: mv a6, a0 1911; RV32I-NEXT: .LBB21_2: 1912; RV32I-NEXT: bnez a5, .LBB21_4 1913; RV32I-NEXT: # %bb.3: 1914; RV32I-NEXT: mv a0, a1 1915; RV32I-NEXT: .LBB21_4: 1916; RV32I-NEXT: sll a7, a6, a4 1917; RV32I-NEXT: srli t1, a0, 1 1918; RV32I-NEXT: not a1, a4 1919; RV32I-NEXT: sll t0, a0, a4 1920; RV32I-NEXT: srli a0, a6, 1 1921; RV32I-NEXT: srl a6, t1, a1 1922; RV32I-NEXT: srl t1, a0, a1 1923; RV32I-NEXT: mv a0, a3 1924; RV32I-NEXT: bnez a5, .LBB21_6 1925; RV32I-NEXT: # %bb.5: 1926; RV32I-NEXT: mv a0, a2 1927; RV32I-NEXT: .LBB21_6: 1928; RV32I-NEXT: or a6, a7, a6 1929; RV32I-NEXT: or a7, t0, t1 1930; RV32I-NEXT: sll t0, a0, a4 1931; RV32I-NEXT: bnez a5, .LBB21_8 1932; RV32I-NEXT: # %bb.7: 1933; RV32I-NEXT: mv a2, a3 1934; RV32I-NEXT: .LBB21_8: 1935; RV32I-NEXT: srli a3, a2, 1 1936; RV32I-NEXT: sll a2, a2, a4 1937; RV32I-NEXT: srli a0, a0, 1 1938; RV32I-NEXT: srl a3, a3, a1 1939; RV32I-NEXT: srl a0, a0, a1 1940; RV32I-NEXT: or a1, t0, a3 1941; RV32I-NEXT: or a0, a2, a0 1942; RV32I-NEXT: add a7, a7, a0 1943; RV32I-NEXT: add a0, a6, a1 1944; RV32I-NEXT: sltu a1, a0, a6 1945; RV32I-NEXT: add a1, a7, a1 1946; RV32I-NEXT: ret 1947; 1948; RV64I-LABEL: rotl_64_mask_multiple: 1949; RV64I: # %bb.0: 1950; RV64I-NEXT: sll a3, a0, a2 1951; RV64I-NEXT: negw a4, a2 1952; RV64I-NEXT: sll a2, a1, a2 1953; RV64I-NEXT: srl a0, a0, a4 1954; RV64I-NEXT: srl a1, a1, a4 1955; RV64I-NEXT: or a0, a3, a0 1956; RV64I-NEXT: or a1, a2, a1 1957; RV64I-NEXT: add a0, a0, a1 1958; RV64I-NEXT: ret 1959; 1960; RV32ZBB-LABEL: rotl_64_mask_multiple: 1961; RV32ZBB: # %bb.0: 1962; RV32ZBB-NEXT: slli a5, a4, 26 1963; RV32ZBB-NEXT: srli a5, a5, 31 1964; RV32ZBB-NEXT: mv a6, a1 1965; RV32ZBB-NEXT: bnez a5, .LBB21_2 1966; RV32ZBB-NEXT: # %bb.1: 1967; RV32ZBB-NEXT: mv a6, a0 1968; RV32ZBB-NEXT: .LBB21_2: 1969; RV32ZBB-NEXT: bnez a5, .LBB21_4 1970; RV32ZBB-NEXT: # %bb.3: 1971; RV32ZBB-NEXT: mv a0, a1 1972; RV32ZBB-NEXT: .LBB21_4: 1973; RV32ZBB-NEXT: sll a7, a6, a4 1974; RV32ZBB-NEXT: srli t1, a0, 1 1975; RV32ZBB-NEXT: not a1, a4 1976; RV32ZBB-NEXT: sll t0, a0, a4 1977; RV32ZBB-NEXT: srli a0, a6, 1 1978; RV32ZBB-NEXT: srl a6, t1, a1 1979; RV32ZBB-NEXT: srl t1, a0, a1 1980; RV32ZBB-NEXT: mv a0, a3 1981; RV32ZBB-NEXT: bnez a5, .LBB21_6 1982; RV32ZBB-NEXT: # %bb.5: 1983; RV32ZBB-NEXT: mv a0, a2 1984; RV32ZBB-NEXT: .LBB21_6: 1985; RV32ZBB-NEXT: or a6, a7, a6 1986; RV32ZBB-NEXT: or a7, t0, t1 1987; RV32ZBB-NEXT: sll t0, a0, a4 1988; RV32ZBB-NEXT: bnez a5, .LBB21_8 1989; RV32ZBB-NEXT: # %bb.7: 1990; RV32ZBB-NEXT: mv a2, a3 1991; RV32ZBB-NEXT: .LBB21_8: 1992; RV32ZBB-NEXT: srli a3, a2, 1 1993; RV32ZBB-NEXT: sll a2, a2, a4 1994; RV32ZBB-NEXT: srli a0, a0, 1 1995; RV32ZBB-NEXT: srl a3, a3, a1 1996; RV32ZBB-NEXT: srl a0, a0, a1 1997; RV32ZBB-NEXT: or a1, t0, a3 1998; RV32ZBB-NEXT: or a0, a2, a0 1999; RV32ZBB-NEXT: add a7, a7, a0 2000; RV32ZBB-NEXT: add a0, a6, a1 2001; RV32ZBB-NEXT: sltu a1, a0, a6 2002; RV32ZBB-NEXT: add a1, a7, a1 2003; RV32ZBB-NEXT: ret 2004; 2005; RV64ZBB-LABEL: rotl_64_mask_multiple: 2006; RV64ZBB: # %bb.0: 2007; RV64ZBB-NEXT: rol a0, a0, a2 2008; RV64ZBB-NEXT: rol a1, a1, a2 2009; RV64ZBB-NEXT: add a0, a0, a1 2010; RV64ZBB-NEXT: ret 2011; 2012; RV32XTHEADBB-LABEL: rotl_64_mask_multiple: 2013; RV32XTHEADBB: # %bb.0: 2014; RV32XTHEADBB-NEXT: th.extu a5, a4, 5, 5 2015; RV32XTHEADBB-NEXT: mv a6, a1 2016; RV32XTHEADBB-NEXT: bnez a5, .LBB21_2 2017; RV32XTHEADBB-NEXT: # %bb.1: 2018; RV32XTHEADBB-NEXT: mv a6, a0 2019; RV32XTHEADBB-NEXT: .LBB21_2: 2020; RV32XTHEADBB-NEXT: bnez a5, .LBB21_4 2021; RV32XTHEADBB-NEXT: # %bb.3: 2022; RV32XTHEADBB-NEXT: mv a0, a1 2023; RV32XTHEADBB-NEXT: .LBB21_4: 2024; RV32XTHEADBB-NEXT: sll a7, a6, a4 2025; RV32XTHEADBB-NEXT: srli t1, a0, 1 2026; RV32XTHEADBB-NEXT: not a1, a4 2027; RV32XTHEADBB-NEXT: sll t0, a0, a4 2028; RV32XTHEADBB-NEXT: srli a0, a6, 1 2029; RV32XTHEADBB-NEXT: srl a6, t1, a1 2030; RV32XTHEADBB-NEXT: srl t1, a0, a1 2031; RV32XTHEADBB-NEXT: mv a0, a3 2032; RV32XTHEADBB-NEXT: bnez a5, .LBB21_6 2033; RV32XTHEADBB-NEXT: # %bb.5: 2034; RV32XTHEADBB-NEXT: mv a0, a2 2035; RV32XTHEADBB-NEXT: .LBB21_6: 2036; RV32XTHEADBB-NEXT: or a6, a7, a6 2037; RV32XTHEADBB-NEXT: or a7, t0, t1 2038; RV32XTHEADBB-NEXT: sll t0, a0, a4 2039; RV32XTHEADBB-NEXT: bnez a5, .LBB21_8 2040; RV32XTHEADBB-NEXT: # %bb.7: 2041; RV32XTHEADBB-NEXT: mv a2, a3 2042; RV32XTHEADBB-NEXT: .LBB21_8: 2043; RV32XTHEADBB-NEXT: srli a3, a2, 1 2044; RV32XTHEADBB-NEXT: sll a2, a2, a4 2045; RV32XTHEADBB-NEXT: srli a0, a0, 1 2046; RV32XTHEADBB-NEXT: srl a3, a3, a1 2047; RV32XTHEADBB-NEXT: srl a0, a0, a1 2048; RV32XTHEADBB-NEXT: or a1, t0, a3 2049; RV32XTHEADBB-NEXT: or a0, a2, a0 2050; RV32XTHEADBB-NEXT: add a7, a7, a0 2051; RV32XTHEADBB-NEXT: add a0, a6, a1 2052; RV32XTHEADBB-NEXT: sltu a1, a0, a6 2053; RV32XTHEADBB-NEXT: add a1, a7, a1 2054; RV32XTHEADBB-NEXT: ret 2055; 2056; RV64XTHEADBB-LABEL: rotl_64_mask_multiple: 2057; RV64XTHEADBB: # %bb.0: 2058; RV64XTHEADBB-NEXT: sll a3, a0, a2 2059; RV64XTHEADBB-NEXT: negw a4, a2 2060; RV64XTHEADBB-NEXT: sll a2, a1, a2 2061; RV64XTHEADBB-NEXT: srl a0, a0, a4 2062; RV64XTHEADBB-NEXT: srl a1, a1, a4 2063; RV64XTHEADBB-NEXT: or a0, a3, a0 2064; RV64XTHEADBB-NEXT: or a1, a2, a1 2065; RV64XTHEADBB-NEXT: add a0, a0, a1 2066; RV64XTHEADBB-NEXT: ret 2067 %maskedamt = and i64 %amt, 63 2068 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %maskedamt) 2069 %2 = tail call i64 @llvm.fshl.i64(i64 %b, i64 %b, i64 %maskedamt) 2070 %3 = add i64 %1, %2 2071 ret i64 %3 2072} 2073 2074define signext i32 @rotr_32_mask_multiple(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind { 2075; RV32I-LABEL: rotr_32_mask_multiple: 2076; RV32I: # %bb.0: 2077; RV32I-NEXT: srl a3, a0, a2 2078; RV32I-NEXT: neg a4, a2 2079; RV32I-NEXT: srl a2, a1, a2 2080; RV32I-NEXT: sll a0, a0, a4 2081; RV32I-NEXT: sll a1, a1, a4 2082; RV32I-NEXT: or a0, a3, a0 2083; RV32I-NEXT: or a1, a2, a1 2084; RV32I-NEXT: add a0, a0, a1 2085; RV32I-NEXT: ret 2086; 2087; RV64I-LABEL: rotr_32_mask_multiple: 2088; RV64I: # %bb.0: 2089; RV64I-NEXT: srlw a3, a0, a2 2090; RV64I-NEXT: negw a4, a2 2091; RV64I-NEXT: srlw a2, a1, a2 2092; RV64I-NEXT: sllw a0, a0, a4 2093; RV64I-NEXT: sllw a1, a1, a4 2094; RV64I-NEXT: or a0, a3, a0 2095; RV64I-NEXT: or a1, a2, a1 2096; RV64I-NEXT: addw a0, a0, a1 2097; RV64I-NEXT: ret 2098; 2099; RV32ZBB-LABEL: rotr_32_mask_multiple: 2100; RV32ZBB: # %bb.0: 2101; RV32ZBB-NEXT: ror a0, a0, a2 2102; RV32ZBB-NEXT: ror a1, a1, a2 2103; RV32ZBB-NEXT: add a0, a0, a1 2104; RV32ZBB-NEXT: ret 2105; 2106; RV64ZBB-LABEL: rotr_32_mask_multiple: 2107; RV64ZBB: # %bb.0: 2108; RV64ZBB-NEXT: rorw a0, a0, a2 2109; RV64ZBB-NEXT: rorw a1, a1, a2 2110; RV64ZBB-NEXT: addw a0, a0, a1 2111; RV64ZBB-NEXT: ret 2112; 2113; RV32XTHEADBB-LABEL: rotr_32_mask_multiple: 2114; RV32XTHEADBB: # %bb.0: 2115; RV32XTHEADBB-NEXT: srl a3, a0, a2 2116; RV32XTHEADBB-NEXT: neg a4, a2 2117; RV32XTHEADBB-NEXT: srl a2, a1, a2 2118; RV32XTHEADBB-NEXT: sll a0, a0, a4 2119; RV32XTHEADBB-NEXT: sll a1, a1, a4 2120; RV32XTHEADBB-NEXT: or a0, a3, a0 2121; RV32XTHEADBB-NEXT: or a1, a2, a1 2122; RV32XTHEADBB-NEXT: add a0, a0, a1 2123; RV32XTHEADBB-NEXT: ret 2124; 2125; RV64XTHEADBB-LABEL: rotr_32_mask_multiple: 2126; RV64XTHEADBB: # %bb.0: 2127; RV64XTHEADBB-NEXT: srlw a3, a0, a2 2128; RV64XTHEADBB-NEXT: negw a4, a2 2129; RV64XTHEADBB-NEXT: srlw a2, a1, a2 2130; RV64XTHEADBB-NEXT: sllw a0, a0, a4 2131; RV64XTHEADBB-NEXT: sllw a1, a1, a4 2132; RV64XTHEADBB-NEXT: or a0, a3, a0 2133; RV64XTHEADBB-NEXT: or a1, a2, a1 2134; RV64XTHEADBB-NEXT: addw a0, a0, a1 2135; RV64XTHEADBB-NEXT: ret 2136 %maskedamt = and i32 %amt, 31 2137 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %maskedamt) 2138 %2 = tail call i32 @llvm.fshr.i32(i32 %b, i32 %b, i32 %maskedamt) 2139 %3 = add i32 %1, %2 2140 ret i32 %3 2141} 2142 2143define i64 @rotr_64_mask_multiple(i64 %a, i64 %b, i64 %amt) nounwind { 2144; RV32I-LABEL: rotr_64_mask_multiple: 2145; RV32I: # %bb.0: 2146; RV32I-NEXT: andi a5, a4, 32 2147; RV32I-NEXT: mv a6, a0 2148; RV32I-NEXT: beqz a5, .LBB23_2 2149; RV32I-NEXT: # %bb.1: 2150; RV32I-NEXT: mv a6, a1 2151; RV32I-NEXT: .LBB23_2: 2152; RV32I-NEXT: beqz a5, .LBB23_4 2153; RV32I-NEXT: # %bb.3: 2154; RV32I-NEXT: mv a1, a0 2155; RV32I-NEXT: .LBB23_4: 2156; RV32I-NEXT: srl a7, a6, a4 2157; RV32I-NEXT: slli t1, a1, 1 2158; RV32I-NEXT: not a0, a4 2159; RV32I-NEXT: srl t0, a1, a4 2160; RV32I-NEXT: slli a6, a6, 1 2161; RV32I-NEXT: sll a1, t1, a0 2162; RV32I-NEXT: sll t1, a6, a0 2163; RV32I-NEXT: mv a6, a2 2164; RV32I-NEXT: beqz a5, .LBB23_6 2165; RV32I-NEXT: # %bb.5: 2166; RV32I-NEXT: mv a6, a3 2167; RV32I-NEXT: .LBB23_6: 2168; RV32I-NEXT: or a1, a1, a7 2169; RV32I-NEXT: or a7, t1, t0 2170; RV32I-NEXT: srl t0, a6, a4 2171; RV32I-NEXT: beqz a5, .LBB23_8 2172; RV32I-NEXT: # %bb.7: 2173; RV32I-NEXT: mv a3, a2 2174; RV32I-NEXT: .LBB23_8: 2175; RV32I-NEXT: slli a2, a3, 1 2176; RV32I-NEXT: srl a3, a3, a4 2177; RV32I-NEXT: slli a6, a6, 1 2178; RV32I-NEXT: sll a2, a2, a0 2179; RV32I-NEXT: sll a0, a6, a0 2180; RV32I-NEXT: or a2, a2, t0 2181; RV32I-NEXT: or a0, a0, a3 2182; RV32I-NEXT: add a7, a7, a0 2183; RV32I-NEXT: add a0, a1, a2 2184; RV32I-NEXT: sltu a1, a0, a1 2185; RV32I-NEXT: add a1, a7, a1 2186; RV32I-NEXT: ret 2187; 2188; RV64I-LABEL: rotr_64_mask_multiple: 2189; RV64I: # %bb.0: 2190; RV64I-NEXT: srl a3, a0, a2 2191; RV64I-NEXT: negw a4, a2 2192; RV64I-NEXT: srl a2, a1, a2 2193; RV64I-NEXT: sll a0, a0, a4 2194; RV64I-NEXT: sll a1, a1, a4 2195; RV64I-NEXT: or a0, a3, a0 2196; RV64I-NEXT: or a1, a2, a1 2197; RV64I-NEXT: add a0, a0, a1 2198; RV64I-NEXT: ret 2199; 2200; RV32ZBB-LABEL: rotr_64_mask_multiple: 2201; RV32ZBB: # %bb.0: 2202; RV32ZBB-NEXT: andi a5, a4, 32 2203; RV32ZBB-NEXT: mv a6, a0 2204; RV32ZBB-NEXT: beqz a5, .LBB23_2 2205; RV32ZBB-NEXT: # %bb.1: 2206; RV32ZBB-NEXT: mv a6, a1 2207; RV32ZBB-NEXT: .LBB23_2: 2208; RV32ZBB-NEXT: beqz a5, .LBB23_4 2209; RV32ZBB-NEXT: # %bb.3: 2210; RV32ZBB-NEXT: mv a1, a0 2211; RV32ZBB-NEXT: .LBB23_4: 2212; RV32ZBB-NEXT: srl a7, a6, a4 2213; RV32ZBB-NEXT: slli t1, a1, 1 2214; RV32ZBB-NEXT: not a0, a4 2215; RV32ZBB-NEXT: srl t0, a1, a4 2216; RV32ZBB-NEXT: slli a6, a6, 1 2217; RV32ZBB-NEXT: sll a1, t1, a0 2218; RV32ZBB-NEXT: sll t1, a6, a0 2219; RV32ZBB-NEXT: mv a6, a2 2220; RV32ZBB-NEXT: beqz a5, .LBB23_6 2221; RV32ZBB-NEXT: # %bb.5: 2222; RV32ZBB-NEXT: mv a6, a3 2223; RV32ZBB-NEXT: .LBB23_6: 2224; RV32ZBB-NEXT: or a1, a1, a7 2225; RV32ZBB-NEXT: or a7, t1, t0 2226; RV32ZBB-NEXT: srl t0, a6, a4 2227; RV32ZBB-NEXT: beqz a5, .LBB23_8 2228; RV32ZBB-NEXT: # %bb.7: 2229; RV32ZBB-NEXT: mv a3, a2 2230; RV32ZBB-NEXT: .LBB23_8: 2231; RV32ZBB-NEXT: slli a2, a3, 1 2232; RV32ZBB-NEXT: srl a3, a3, a4 2233; RV32ZBB-NEXT: slli a6, a6, 1 2234; RV32ZBB-NEXT: sll a2, a2, a0 2235; RV32ZBB-NEXT: sll a0, a6, a0 2236; RV32ZBB-NEXT: or a2, a2, t0 2237; RV32ZBB-NEXT: or a0, a0, a3 2238; RV32ZBB-NEXT: add a7, a7, a0 2239; RV32ZBB-NEXT: add a0, a1, a2 2240; RV32ZBB-NEXT: sltu a1, a0, a1 2241; RV32ZBB-NEXT: add a1, a7, a1 2242; RV32ZBB-NEXT: ret 2243; 2244; RV64ZBB-LABEL: rotr_64_mask_multiple: 2245; RV64ZBB: # %bb.0: 2246; RV64ZBB-NEXT: ror a0, a0, a2 2247; RV64ZBB-NEXT: ror a1, a1, a2 2248; RV64ZBB-NEXT: add a0, a0, a1 2249; RV64ZBB-NEXT: ret 2250; 2251; RV32XTHEADBB-LABEL: rotr_64_mask_multiple: 2252; RV32XTHEADBB: # %bb.0: 2253; RV32XTHEADBB-NEXT: andi a5, a4, 32 2254; RV32XTHEADBB-NEXT: mv a6, a0 2255; RV32XTHEADBB-NEXT: beqz a5, .LBB23_2 2256; RV32XTHEADBB-NEXT: # %bb.1: 2257; RV32XTHEADBB-NEXT: mv a6, a1 2258; RV32XTHEADBB-NEXT: .LBB23_2: 2259; RV32XTHEADBB-NEXT: beqz a5, .LBB23_4 2260; RV32XTHEADBB-NEXT: # %bb.3: 2261; RV32XTHEADBB-NEXT: mv a1, a0 2262; RV32XTHEADBB-NEXT: .LBB23_4: 2263; RV32XTHEADBB-NEXT: srl a7, a6, a4 2264; RV32XTHEADBB-NEXT: slli t1, a1, 1 2265; RV32XTHEADBB-NEXT: not a0, a4 2266; RV32XTHEADBB-NEXT: srl t0, a1, a4 2267; RV32XTHEADBB-NEXT: slli a6, a6, 1 2268; RV32XTHEADBB-NEXT: sll a1, t1, a0 2269; RV32XTHEADBB-NEXT: sll t1, a6, a0 2270; RV32XTHEADBB-NEXT: mv a6, a2 2271; RV32XTHEADBB-NEXT: beqz a5, .LBB23_6 2272; RV32XTHEADBB-NEXT: # %bb.5: 2273; RV32XTHEADBB-NEXT: mv a6, a3 2274; RV32XTHEADBB-NEXT: .LBB23_6: 2275; RV32XTHEADBB-NEXT: or a1, a1, a7 2276; RV32XTHEADBB-NEXT: or a7, t1, t0 2277; RV32XTHEADBB-NEXT: srl t0, a6, a4 2278; RV32XTHEADBB-NEXT: beqz a5, .LBB23_8 2279; RV32XTHEADBB-NEXT: # %bb.7: 2280; RV32XTHEADBB-NEXT: mv a3, a2 2281; RV32XTHEADBB-NEXT: .LBB23_8: 2282; RV32XTHEADBB-NEXT: slli a2, a3, 1 2283; RV32XTHEADBB-NEXT: srl a3, a3, a4 2284; RV32XTHEADBB-NEXT: slli a6, a6, 1 2285; RV32XTHEADBB-NEXT: sll a2, a2, a0 2286; RV32XTHEADBB-NEXT: sll a0, a6, a0 2287; RV32XTHEADBB-NEXT: or a2, a2, t0 2288; RV32XTHEADBB-NEXT: or a0, a0, a3 2289; RV32XTHEADBB-NEXT: add a7, a7, a0 2290; RV32XTHEADBB-NEXT: add a0, a1, a2 2291; RV32XTHEADBB-NEXT: sltu a1, a0, a1 2292; RV32XTHEADBB-NEXT: add a1, a7, a1 2293; RV32XTHEADBB-NEXT: ret 2294; 2295; RV64XTHEADBB-LABEL: rotr_64_mask_multiple: 2296; RV64XTHEADBB: # %bb.0: 2297; RV64XTHEADBB-NEXT: srl a3, a0, a2 2298; RV64XTHEADBB-NEXT: negw a4, a2 2299; RV64XTHEADBB-NEXT: srl a2, a1, a2 2300; RV64XTHEADBB-NEXT: sll a0, a0, a4 2301; RV64XTHEADBB-NEXT: sll a1, a1, a4 2302; RV64XTHEADBB-NEXT: or a0, a3, a0 2303; RV64XTHEADBB-NEXT: or a1, a2, a1 2304; RV64XTHEADBB-NEXT: add a0, a0, a1 2305; RV64XTHEADBB-NEXT: ret 2306 %maskedamt = and i64 %amt, 63 2307 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %maskedamt) 2308 %2 = tail call i64 @llvm.fshr.i64(i64 %b, i64 %b, i64 %maskedamt) 2309 %3 = add i64 %1, %2 2310 ret i64 %3 2311} 2312 2313define i64 @rotl_64_zext(i64 %x, i32 %y) nounwind { 2314; RV32I-LABEL: rotl_64_zext: 2315; RV32I: # %bb.0: 2316; RV32I-NEXT: neg a4, a2 2317; RV32I-NEXT: addi a6, a2, -32 2318; RV32I-NEXT: sll a5, a0, a2 2319; RV32I-NEXT: bltz a6, .LBB24_2 2320; RV32I-NEXT: # %bb.1: 2321; RV32I-NEXT: mv a3, a5 2322; RV32I-NEXT: j .LBB24_3 2323; RV32I-NEXT: .LBB24_2: 2324; RV32I-NEXT: sll a3, a1, a2 2325; RV32I-NEXT: not a7, a2 2326; RV32I-NEXT: srli t0, a0, 1 2327; RV32I-NEXT: srl a7, t0, a7 2328; RV32I-NEXT: or a3, a3, a7 2329; RV32I-NEXT: .LBB24_3: 2330; RV32I-NEXT: srai a6, a6, 31 2331; RV32I-NEXT: li a7, 32 2332; RV32I-NEXT: and a5, a6, a5 2333; RV32I-NEXT: sub a6, a7, a2 2334; RV32I-NEXT: srl a7, a1, a4 2335; RV32I-NEXT: bltz a6, .LBB24_5 2336; RV32I-NEXT: # %bb.4: 2337; RV32I-NEXT: mv a0, a7 2338; RV32I-NEXT: j .LBB24_6 2339; RV32I-NEXT: .LBB24_5: 2340; RV32I-NEXT: li t0, 64 2341; RV32I-NEXT: srl a0, a0, a4 2342; RV32I-NEXT: sub a2, t0, a2 2343; RV32I-NEXT: not a2, a2 2344; RV32I-NEXT: slli a1, a1, 1 2345; RV32I-NEXT: sll a1, a1, a2 2346; RV32I-NEXT: or a0, a0, a1 2347; RV32I-NEXT: .LBB24_6: 2348; RV32I-NEXT: srai a1, a6, 31 2349; RV32I-NEXT: and a1, a1, a7 2350; RV32I-NEXT: or a1, a3, a1 2351; RV32I-NEXT: or a0, a5, a0 2352; RV32I-NEXT: ret 2353; 2354; RV64I-LABEL: rotl_64_zext: 2355; RV64I: # %bb.0: 2356; RV64I-NEXT: negw a2, a1 2357; RV64I-NEXT: sll a1, a0, a1 2358; RV64I-NEXT: srl a0, a0, a2 2359; RV64I-NEXT: or a0, a1, a0 2360; RV64I-NEXT: ret 2361; 2362; RV32ZBB-LABEL: rotl_64_zext: 2363; RV32ZBB: # %bb.0: 2364; RV32ZBB-NEXT: neg a4, a2 2365; RV32ZBB-NEXT: addi a6, a2, -32 2366; RV32ZBB-NEXT: sll a5, a0, a2 2367; RV32ZBB-NEXT: bltz a6, .LBB24_2 2368; RV32ZBB-NEXT: # %bb.1: 2369; RV32ZBB-NEXT: mv a3, a5 2370; RV32ZBB-NEXT: j .LBB24_3 2371; RV32ZBB-NEXT: .LBB24_2: 2372; RV32ZBB-NEXT: sll a3, a1, a2 2373; RV32ZBB-NEXT: not a7, a2 2374; RV32ZBB-NEXT: srli t0, a0, 1 2375; RV32ZBB-NEXT: srl a7, t0, a7 2376; RV32ZBB-NEXT: or a3, a3, a7 2377; RV32ZBB-NEXT: .LBB24_3: 2378; RV32ZBB-NEXT: srai a6, a6, 31 2379; RV32ZBB-NEXT: li a7, 32 2380; RV32ZBB-NEXT: and a5, a6, a5 2381; RV32ZBB-NEXT: sub a6, a7, a2 2382; RV32ZBB-NEXT: srl a7, a1, a4 2383; RV32ZBB-NEXT: bltz a6, .LBB24_5 2384; RV32ZBB-NEXT: # %bb.4: 2385; RV32ZBB-NEXT: mv a0, a7 2386; RV32ZBB-NEXT: j .LBB24_6 2387; RV32ZBB-NEXT: .LBB24_5: 2388; RV32ZBB-NEXT: li t0, 64 2389; RV32ZBB-NEXT: srl a0, a0, a4 2390; RV32ZBB-NEXT: sub a2, t0, a2 2391; RV32ZBB-NEXT: not a2, a2 2392; RV32ZBB-NEXT: slli a1, a1, 1 2393; RV32ZBB-NEXT: sll a1, a1, a2 2394; RV32ZBB-NEXT: or a0, a0, a1 2395; RV32ZBB-NEXT: .LBB24_6: 2396; RV32ZBB-NEXT: srai a1, a6, 31 2397; RV32ZBB-NEXT: and a1, a1, a7 2398; RV32ZBB-NEXT: or a1, a3, a1 2399; RV32ZBB-NEXT: or a0, a5, a0 2400; RV32ZBB-NEXT: ret 2401; 2402; RV64ZBB-LABEL: rotl_64_zext: 2403; RV64ZBB: # %bb.0: 2404; RV64ZBB-NEXT: rol a0, a0, a1 2405; RV64ZBB-NEXT: ret 2406; 2407; RV32XTHEADBB-LABEL: rotl_64_zext: 2408; RV32XTHEADBB: # %bb.0: 2409; RV32XTHEADBB-NEXT: neg a4, a2 2410; RV32XTHEADBB-NEXT: addi a6, a2, -32 2411; RV32XTHEADBB-NEXT: sll a5, a0, a2 2412; RV32XTHEADBB-NEXT: bltz a6, .LBB24_2 2413; RV32XTHEADBB-NEXT: # %bb.1: 2414; RV32XTHEADBB-NEXT: mv a3, a5 2415; RV32XTHEADBB-NEXT: j .LBB24_3 2416; RV32XTHEADBB-NEXT: .LBB24_2: 2417; RV32XTHEADBB-NEXT: sll a3, a1, a2 2418; RV32XTHEADBB-NEXT: not a7, a2 2419; RV32XTHEADBB-NEXT: srli t0, a0, 1 2420; RV32XTHEADBB-NEXT: srl a7, t0, a7 2421; RV32XTHEADBB-NEXT: or a3, a3, a7 2422; RV32XTHEADBB-NEXT: .LBB24_3: 2423; RV32XTHEADBB-NEXT: srai a6, a6, 31 2424; RV32XTHEADBB-NEXT: li a7, 32 2425; RV32XTHEADBB-NEXT: and a5, a6, a5 2426; RV32XTHEADBB-NEXT: sub a6, a7, a2 2427; RV32XTHEADBB-NEXT: srl a7, a1, a4 2428; RV32XTHEADBB-NEXT: bltz a6, .LBB24_5 2429; RV32XTHEADBB-NEXT: # %bb.4: 2430; RV32XTHEADBB-NEXT: mv a0, a7 2431; RV32XTHEADBB-NEXT: j .LBB24_6 2432; RV32XTHEADBB-NEXT: .LBB24_5: 2433; RV32XTHEADBB-NEXT: li t0, 64 2434; RV32XTHEADBB-NEXT: srl a0, a0, a4 2435; RV32XTHEADBB-NEXT: sub a2, t0, a2 2436; RV32XTHEADBB-NEXT: not a2, a2 2437; RV32XTHEADBB-NEXT: slli a1, a1, 1 2438; RV32XTHEADBB-NEXT: sll a1, a1, a2 2439; RV32XTHEADBB-NEXT: or a0, a0, a1 2440; RV32XTHEADBB-NEXT: .LBB24_6: 2441; RV32XTHEADBB-NEXT: srai a1, a6, 31 2442; RV32XTHEADBB-NEXT: and a1, a1, a7 2443; RV32XTHEADBB-NEXT: or a1, a3, a1 2444; RV32XTHEADBB-NEXT: or a0, a5, a0 2445; RV32XTHEADBB-NEXT: ret 2446; 2447; RV64XTHEADBB-LABEL: rotl_64_zext: 2448; RV64XTHEADBB: # %bb.0: 2449; RV64XTHEADBB-NEXT: sll a2, a0, a1 2450; RV64XTHEADBB-NEXT: negw a1, a1 2451; RV64XTHEADBB-NEXT: srl a0, a0, a1 2452; RV64XTHEADBB-NEXT: or a0, a2, a0 2453; RV64XTHEADBB-NEXT: ret 2454 %z = sub i32 64, %y 2455 %zext = zext i32 %z to i64 2456 %zexty = zext i32 %y to i64 2457 %b = shl i64 %x, %zexty 2458 %c = lshr i64 %x, %zext 2459 %d = or i64 %b, %c 2460 ret i64 %d 2461} 2462 2463define i64 @rotr_64_zext(i64 %x, i32 %y) nounwind { 2464; RV32I-LABEL: rotr_64_zext: 2465; RV32I: # %bb.0: 2466; RV32I-NEXT: neg a4, a2 2467; RV32I-NEXT: addi a6, a2, -32 2468; RV32I-NEXT: srl a5, a1, a2 2469; RV32I-NEXT: bltz a6, .LBB25_2 2470; RV32I-NEXT: # %bb.1: 2471; RV32I-NEXT: mv a3, a5 2472; RV32I-NEXT: j .LBB25_3 2473; RV32I-NEXT: .LBB25_2: 2474; RV32I-NEXT: srl a3, a0, a2 2475; RV32I-NEXT: not a7, a2 2476; RV32I-NEXT: slli t0, a1, 1 2477; RV32I-NEXT: sll a7, t0, a7 2478; RV32I-NEXT: or a3, a3, a7 2479; RV32I-NEXT: .LBB25_3: 2480; RV32I-NEXT: srai a6, a6, 31 2481; RV32I-NEXT: li a7, 32 2482; RV32I-NEXT: and a5, a6, a5 2483; RV32I-NEXT: sub a6, a7, a2 2484; RV32I-NEXT: sll a7, a0, a4 2485; RV32I-NEXT: bltz a6, .LBB25_5 2486; RV32I-NEXT: # %bb.4: 2487; RV32I-NEXT: mv a1, a7 2488; RV32I-NEXT: j .LBB25_6 2489; RV32I-NEXT: .LBB25_5: 2490; RV32I-NEXT: li t0, 64 2491; RV32I-NEXT: sll a1, a1, a4 2492; RV32I-NEXT: sub a2, t0, a2 2493; RV32I-NEXT: not a2, a2 2494; RV32I-NEXT: srli a0, a0, 1 2495; RV32I-NEXT: srl a0, a0, a2 2496; RV32I-NEXT: or a1, a1, a0 2497; RV32I-NEXT: .LBB25_6: 2498; RV32I-NEXT: srai a0, a6, 31 2499; RV32I-NEXT: and a0, a0, a7 2500; RV32I-NEXT: or a0, a3, a0 2501; RV32I-NEXT: or a1, a5, a1 2502; RV32I-NEXT: ret 2503; 2504; RV64I-LABEL: rotr_64_zext: 2505; RV64I: # %bb.0: 2506; RV64I-NEXT: negw a2, a1 2507; RV64I-NEXT: srl a1, a0, a1 2508; RV64I-NEXT: sll a0, a0, a2 2509; RV64I-NEXT: or a0, a1, a0 2510; RV64I-NEXT: ret 2511; 2512; RV32ZBB-LABEL: rotr_64_zext: 2513; RV32ZBB: # %bb.0: 2514; RV32ZBB-NEXT: neg a4, a2 2515; RV32ZBB-NEXT: addi a6, a2, -32 2516; RV32ZBB-NEXT: srl a5, a1, a2 2517; RV32ZBB-NEXT: bltz a6, .LBB25_2 2518; RV32ZBB-NEXT: # %bb.1: 2519; RV32ZBB-NEXT: mv a3, a5 2520; RV32ZBB-NEXT: j .LBB25_3 2521; RV32ZBB-NEXT: .LBB25_2: 2522; RV32ZBB-NEXT: srl a3, a0, a2 2523; RV32ZBB-NEXT: not a7, a2 2524; RV32ZBB-NEXT: slli t0, a1, 1 2525; RV32ZBB-NEXT: sll a7, t0, a7 2526; RV32ZBB-NEXT: or a3, a3, a7 2527; RV32ZBB-NEXT: .LBB25_3: 2528; RV32ZBB-NEXT: srai a6, a6, 31 2529; RV32ZBB-NEXT: li a7, 32 2530; RV32ZBB-NEXT: and a5, a6, a5 2531; RV32ZBB-NEXT: sub a6, a7, a2 2532; RV32ZBB-NEXT: sll a7, a0, a4 2533; RV32ZBB-NEXT: bltz a6, .LBB25_5 2534; RV32ZBB-NEXT: # %bb.4: 2535; RV32ZBB-NEXT: mv a1, a7 2536; RV32ZBB-NEXT: j .LBB25_6 2537; RV32ZBB-NEXT: .LBB25_5: 2538; RV32ZBB-NEXT: li t0, 64 2539; RV32ZBB-NEXT: sll a1, a1, a4 2540; RV32ZBB-NEXT: sub a2, t0, a2 2541; RV32ZBB-NEXT: not a2, a2 2542; RV32ZBB-NEXT: srli a0, a0, 1 2543; RV32ZBB-NEXT: srl a0, a0, a2 2544; RV32ZBB-NEXT: or a1, a1, a0 2545; RV32ZBB-NEXT: .LBB25_6: 2546; RV32ZBB-NEXT: srai a0, a6, 31 2547; RV32ZBB-NEXT: and a0, a0, a7 2548; RV32ZBB-NEXT: or a0, a3, a0 2549; RV32ZBB-NEXT: or a1, a5, a1 2550; RV32ZBB-NEXT: ret 2551; 2552; RV64ZBB-LABEL: rotr_64_zext: 2553; RV64ZBB: # %bb.0: 2554; RV64ZBB-NEXT: ror a0, a0, a1 2555; RV64ZBB-NEXT: ret 2556; 2557; RV32XTHEADBB-LABEL: rotr_64_zext: 2558; RV32XTHEADBB: # %bb.0: 2559; RV32XTHEADBB-NEXT: neg a4, a2 2560; RV32XTHEADBB-NEXT: addi a6, a2, -32 2561; RV32XTHEADBB-NEXT: srl a5, a1, a2 2562; RV32XTHEADBB-NEXT: bltz a6, .LBB25_2 2563; RV32XTHEADBB-NEXT: # %bb.1: 2564; RV32XTHEADBB-NEXT: mv a3, a5 2565; RV32XTHEADBB-NEXT: j .LBB25_3 2566; RV32XTHEADBB-NEXT: .LBB25_2: 2567; RV32XTHEADBB-NEXT: srl a3, a0, a2 2568; RV32XTHEADBB-NEXT: not a7, a2 2569; RV32XTHEADBB-NEXT: slli t0, a1, 1 2570; RV32XTHEADBB-NEXT: sll a7, t0, a7 2571; RV32XTHEADBB-NEXT: or a3, a3, a7 2572; RV32XTHEADBB-NEXT: .LBB25_3: 2573; RV32XTHEADBB-NEXT: srai a6, a6, 31 2574; RV32XTHEADBB-NEXT: li a7, 32 2575; RV32XTHEADBB-NEXT: and a5, a6, a5 2576; RV32XTHEADBB-NEXT: sub a6, a7, a2 2577; RV32XTHEADBB-NEXT: sll a7, a0, a4 2578; RV32XTHEADBB-NEXT: bltz a6, .LBB25_5 2579; RV32XTHEADBB-NEXT: # %bb.4: 2580; RV32XTHEADBB-NEXT: mv a1, a7 2581; RV32XTHEADBB-NEXT: j .LBB25_6 2582; RV32XTHEADBB-NEXT: .LBB25_5: 2583; RV32XTHEADBB-NEXT: li t0, 64 2584; RV32XTHEADBB-NEXT: sll a1, a1, a4 2585; RV32XTHEADBB-NEXT: sub a2, t0, a2 2586; RV32XTHEADBB-NEXT: not a2, a2 2587; RV32XTHEADBB-NEXT: srli a0, a0, 1 2588; RV32XTHEADBB-NEXT: srl a0, a0, a2 2589; RV32XTHEADBB-NEXT: or a1, a1, a0 2590; RV32XTHEADBB-NEXT: .LBB25_6: 2591; RV32XTHEADBB-NEXT: srai a0, a6, 31 2592; RV32XTHEADBB-NEXT: and a0, a0, a7 2593; RV32XTHEADBB-NEXT: or a0, a3, a0 2594; RV32XTHEADBB-NEXT: or a1, a5, a1 2595; RV32XTHEADBB-NEXT: ret 2596; 2597; RV64XTHEADBB-LABEL: rotr_64_zext: 2598; RV64XTHEADBB: # %bb.0: 2599; RV64XTHEADBB-NEXT: srl a2, a0, a1 2600; RV64XTHEADBB-NEXT: negw a1, a1 2601; RV64XTHEADBB-NEXT: sll a0, a0, a1 2602; RV64XTHEADBB-NEXT: or a0, a2, a0 2603; RV64XTHEADBB-NEXT: ret 2604 %z = sub i32 64, %y 2605 %zext = zext i32 %z to i64 2606 %zexty = zext i32 %y to i64 2607 %b = lshr i64 %x, %zexty 2608 %c = shl i64 %x, %zext 2609 %d = or i64 %b, %c 2610 ret i64 %d 2611} 2612