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=riscv32 -mattr=+experimental-b -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV32IB 6; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbb -verify-machineinstrs < %s \ 7; RUN: | FileCheck %s -check-prefix=RV32IBB 8; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbp -verify-machineinstrs < %s \ 9; RUN: | FileCheck %s -check-prefix=RV32IBP 10 11define i32 @andn_i32(i32 %a, i32 %b) nounwind { 12; RV32I-LABEL: andn_i32: 13; RV32I: # %bb.0: 14; RV32I-NEXT: not a1, a1 15; RV32I-NEXT: and a0, a1, a0 16; RV32I-NEXT: ret 17; 18; RV32IB-LABEL: andn_i32: 19; RV32IB: # %bb.0: 20; RV32IB-NEXT: andn a0, a0, a1 21; RV32IB-NEXT: ret 22; 23; RV32IBB-LABEL: andn_i32: 24; RV32IBB: # %bb.0: 25; RV32IBB-NEXT: andn a0, a0, a1 26; RV32IBB-NEXT: ret 27; 28; RV32IBP-LABEL: andn_i32: 29; RV32IBP: # %bb.0: 30; RV32IBP-NEXT: andn a0, a0, a1 31; RV32IBP-NEXT: ret 32 %neg = xor i32 %b, -1 33 %and = and i32 %neg, %a 34 ret i32 %and 35} 36 37define i64 @andn_i64(i64 %a, i64 %b) nounwind { 38; RV32I-LABEL: andn_i64: 39; RV32I: # %bb.0: 40; RV32I-NEXT: not a3, a3 41; RV32I-NEXT: not a2, a2 42; RV32I-NEXT: and a0, a2, a0 43; RV32I-NEXT: and a1, a3, a1 44; RV32I-NEXT: ret 45; 46; RV32IB-LABEL: andn_i64: 47; RV32IB: # %bb.0: 48; RV32IB-NEXT: andn a0, a0, a2 49; RV32IB-NEXT: andn a1, a1, a3 50; RV32IB-NEXT: ret 51; 52; RV32IBB-LABEL: andn_i64: 53; RV32IBB: # %bb.0: 54; RV32IBB-NEXT: andn a0, a0, a2 55; RV32IBB-NEXT: andn a1, a1, a3 56; RV32IBB-NEXT: ret 57; 58; RV32IBP-LABEL: andn_i64: 59; RV32IBP: # %bb.0: 60; RV32IBP-NEXT: andn a0, a0, a2 61; RV32IBP-NEXT: andn a1, a1, a3 62; RV32IBP-NEXT: ret 63 %neg = xor i64 %b, -1 64 %and = and i64 %neg, %a 65 ret i64 %and 66} 67 68define i32 @orn_i32(i32 %a, i32 %b) nounwind { 69; RV32I-LABEL: orn_i32: 70; RV32I: # %bb.0: 71; RV32I-NEXT: not a1, a1 72; RV32I-NEXT: or a0, a1, a0 73; RV32I-NEXT: ret 74; 75; RV32IB-LABEL: orn_i32: 76; RV32IB: # %bb.0: 77; RV32IB-NEXT: orn a0, a0, a1 78; RV32IB-NEXT: ret 79; 80; RV32IBB-LABEL: orn_i32: 81; RV32IBB: # %bb.0: 82; RV32IBB-NEXT: orn a0, a0, a1 83; RV32IBB-NEXT: ret 84; 85; RV32IBP-LABEL: orn_i32: 86; RV32IBP: # %bb.0: 87; RV32IBP-NEXT: orn a0, a0, a1 88; RV32IBP-NEXT: ret 89 %neg = xor i32 %b, -1 90 %or = or i32 %neg, %a 91 ret i32 %or 92} 93 94define i64 @orn_i64(i64 %a, i64 %b) nounwind { 95; RV32I-LABEL: orn_i64: 96; RV32I: # %bb.0: 97; RV32I-NEXT: not a3, a3 98; RV32I-NEXT: not a2, a2 99; RV32I-NEXT: or a0, a2, a0 100; RV32I-NEXT: or a1, a3, a1 101; RV32I-NEXT: ret 102; 103; RV32IB-LABEL: orn_i64: 104; RV32IB: # %bb.0: 105; RV32IB-NEXT: orn a0, a0, a2 106; RV32IB-NEXT: orn a1, a1, a3 107; RV32IB-NEXT: ret 108; 109; RV32IBB-LABEL: orn_i64: 110; RV32IBB: # %bb.0: 111; RV32IBB-NEXT: orn a0, a0, a2 112; RV32IBB-NEXT: orn a1, a1, a3 113; RV32IBB-NEXT: ret 114; 115; RV32IBP-LABEL: orn_i64: 116; RV32IBP: # %bb.0: 117; RV32IBP-NEXT: orn a0, a0, a2 118; RV32IBP-NEXT: orn a1, a1, a3 119; RV32IBP-NEXT: ret 120 %neg = xor i64 %b, -1 121 %or = or i64 %neg, %a 122 ret i64 %or 123} 124 125define i32 @xnor_i32(i32 %a, i32 %b) nounwind { 126; RV32I-LABEL: xnor_i32: 127; RV32I: # %bb.0: 128; RV32I-NEXT: xor a0, a0, a1 129; RV32I-NEXT: not a0, a0 130; RV32I-NEXT: ret 131; 132; RV32IB-LABEL: xnor_i32: 133; RV32IB: # %bb.0: 134; RV32IB-NEXT: xnor a0, a0, a1 135; RV32IB-NEXT: ret 136; 137; RV32IBB-LABEL: xnor_i32: 138; RV32IBB: # %bb.0: 139; RV32IBB-NEXT: xnor a0, a0, a1 140; RV32IBB-NEXT: ret 141; 142; RV32IBP-LABEL: xnor_i32: 143; RV32IBP: # %bb.0: 144; RV32IBP-NEXT: xnor a0, a0, a1 145; RV32IBP-NEXT: ret 146 %neg = xor i32 %a, -1 147 %xor = xor i32 %neg, %b 148 ret i32 %xor 149} 150 151define i64 @xnor_i64(i64 %a, i64 %b) nounwind { 152; RV32I-LABEL: xnor_i64: 153; RV32I: # %bb.0: 154; RV32I-NEXT: xor a1, a1, a3 155; RV32I-NEXT: xor a0, a0, a2 156; RV32I-NEXT: not a0, a0 157; RV32I-NEXT: not a1, a1 158; RV32I-NEXT: ret 159; 160; RV32IB-LABEL: xnor_i64: 161; RV32IB: # %bb.0: 162; RV32IB-NEXT: xnor a0, a0, a2 163; RV32IB-NEXT: xnor a1, a1, a3 164; RV32IB-NEXT: ret 165; 166; RV32IBB-LABEL: xnor_i64: 167; RV32IBB: # %bb.0: 168; RV32IBB-NEXT: xnor a0, a0, a2 169; RV32IBB-NEXT: xnor a1, a1, a3 170; RV32IBB-NEXT: ret 171; 172; RV32IBP-LABEL: xnor_i64: 173; RV32IBP: # %bb.0: 174; RV32IBP-NEXT: xnor a0, a0, a2 175; RV32IBP-NEXT: xnor a1, a1, a3 176; RV32IBP-NEXT: ret 177 %neg = xor i64 %a, -1 178 %xor = xor i64 %neg, %b 179 ret i64 %xor 180} 181 182declare i32 @llvm.fshl.i32(i32, i32, i32) 183 184define i32 @rol_i32(i32 %a, i32 %b) nounwind { 185; RV32I-LABEL: rol_i32: 186; RV32I: # %bb.0: 187; RV32I-NEXT: sll a2, a0, a1 188; RV32I-NEXT: neg a1, a1 189; RV32I-NEXT: srl a0, a0, a1 190; RV32I-NEXT: or a0, a2, a0 191; RV32I-NEXT: ret 192; 193; RV32IB-LABEL: rol_i32: 194; RV32IB: # %bb.0: 195; RV32IB-NEXT: rol a0, a0, a1 196; RV32IB-NEXT: ret 197; 198; RV32IBB-LABEL: rol_i32: 199; RV32IBB: # %bb.0: 200; RV32IBB-NEXT: rol a0, a0, a1 201; RV32IBB-NEXT: ret 202; 203; RV32IBP-LABEL: rol_i32: 204; RV32IBP: # %bb.0: 205; RV32IBP-NEXT: rol a0, a0, a1 206; RV32IBP-NEXT: ret 207 %or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b) 208 ret i32 %or 209} 210 211; As we are not matching directly i64 code patterns on RV32 some i64 patterns 212; don't have yet any matching bit manipulation instructions on RV32. 213; This test is presented here in case future expansions of the experimental-b 214; extension introduce instructions suitable for this pattern. 215 216declare i64 @llvm.fshl.i64(i64, i64, i64) 217 218define i64 @rol_i64(i64 %a, i64 %b) nounwind { 219; RV32I-LABEL: rol_i64: 220; RV32I: # %bb.0: 221; RV32I-NEXT: andi a3, a2, 63 222; RV32I-NEXT: addi t1, a3, -32 223; RV32I-NEXT: addi a6, zero, 31 224; RV32I-NEXT: bltz t1, .LBB7_2 225; RV32I-NEXT: # %bb.1: 226; RV32I-NEXT: sll a7, a0, t1 227; RV32I-NEXT: j .LBB7_3 228; RV32I-NEXT: .LBB7_2: 229; RV32I-NEXT: sll a4, a1, a2 230; RV32I-NEXT: sub a3, a6, a3 231; RV32I-NEXT: srli a5, a0, 1 232; RV32I-NEXT: srl a3, a5, a3 233; RV32I-NEXT: or a7, a4, a3 234; RV32I-NEXT: .LBB7_3: 235; RV32I-NEXT: neg a4, a2 236; RV32I-NEXT: andi a5, a4, 63 237; RV32I-NEXT: addi a3, a5, -32 238; RV32I-NEXT: bltz a3, .LBB7_7 239; RV32I-NEXT: # %bb.4: 240; RV32I-NEXT: mv t0, zero 241; RV32I-NEXT: bgez a3, .LBB7_8 242; RV32I-NEXT: .LBB7_5: 243; RV32I-NEXT: srl a3, a0, a4 244; RV32I-NEXT: sub a4, a6, a5 245; RV32I-NEXT: slli a1, a1, 1 246; RV32I-NEXT: sll a1, a1, a4 247; RV32I-NEXT: or a4, a3, a1 248; RV32I-NEXT: or a1, a7, t0 249; RV32I-NEXT: bgez t1, .LBB7_9 250; RV32I-NEXT: .LBB7_6: 251; RV32I-NEXT: sll a0, a0, a2 252; RV32I-NEXT: or a0, a0, a4 253; RV32I-NEXT: ret 254; RV32I-NEXT: .LBB7_7: 255; RV32I-NEXT: srl t0, a1, a4 256; RV32I-NEXT: bltz a3, .LBB7_5 257; RV32I-NEXT: .LBB7_8: 258; RV32I-NEXT: srl a4, a1, a3 259; RV32I-NEXT: or a1, a7, t0 260; RV32I-NEXT: bltz t1, .LBB7_6 261; RV32I-NEXT: .LBB7_9: 262; RV32I-NEXT: or a0, zero, a4 263; RV32I-NEXT: ret 264; 265; RV32IB-LABEL: rol_i64: 266; RV32IB: # %bb.0: 267; RV32IB-NEXT: andi a3, a2, 63 268; RV32IB-NEXT: addi t1, a3, -32 269; RV32IB-NEXT: addi a6, zero, 31 270; RV32IB-NEXT: bltz t1, .LBB7_2 271; RV32IB-NEXT: # %bb.1: 272; RV32IB-NEXT: sll a7, a0, t1 273; RV32IB-NEXT: j .LBB7_3 274; RV32IB-NEXT: .LBB7_2: 275; RV32IB-NEXT: sll a4, a1, a2 276; RV32IB-NEXT: sub a3, a6, a3 277; RV32IB-NEXT: srli a5, a0, 1 278; RV32IB-NEXT: srl a3, a5, a3 279; RV32IB-NEXT: or a7, a4, a3 280; RV32IB-NEXT: .LBB7_3: 281; RV32IB-NEXT: neg a4, a2 282; RV32IB-NEXT: andi a5, a4, 63 283; RV32IB-NEXT: addi a3, a5, -32 284; RV32IB-NEXT: bltz a3, .LBB7_7 285; RV32IB-NEXT: # %bb.4: 286; RV32IB-NEXT: mv t0, zero 287; RV32IB-NEXT: bgez a3, .LBB7_8 288; RV32IB-NEXT: .LBB7_5: 289; RV32IB-NEXT: srl a3, a0, a4 290; RV32IB-NEXT: sub a4, a6, a5 291; RV32IB-NEXT: slli a1, a1, 1 292; RV32IB-NEXT: sll a1, a1, a4 293; RV32IB-NEXT: or a4, a3, a1 294; RV32IB-NEXT: or a1, a7, t0 295; RV32IB-NEXT: bgez t1, .LBB7_9 296; RV32IB-NEXT: .LBB7_6: 297; RV32IB-NEXT: sll a0, a0, a2 298; RV32IB-NEXT: or a0, a0, a4 299; RV32IB-NEXT: ret 300; RV32IB-NEXT: .LBB7_7: 301; RV32IB-NEXT: srl t0, a1, a4 302; RV32IB-NEXT: bltz a3, .LBB7_5 303; RV32IB-NEXT: .LBB7_8: 304; RV32IB-NEXT: srl a4, a1, a3 305; RV32IB-NEXT: or a1, a7, t0 306; RV32IB-NEXT: bltz t1, .LBB7_6 307; RV32IB-NEXT: .LBB7_9: 308; RV32IB-NEXT: or a0, zero, a4 309; RV32IB-NEXT: ret 310; 311; RV32IBB-LABEL: rol_i64: 312; RV32IBB: # %bb.0: 313; RV32IBB-NEXT: andi a3, a2, 63 314; RV32IBB-NEXT: addi t1, a3, -32 315; RV32IBB-NEXT: addi a6, zero, 31 316; RV32IBB-NEXT: bltz t1, .LBB7_2 317; RV32IBB-NEXT: # %bb.1: 318; RV32IBB-NEXT: sll a7, a0, t1 319; RV32IBB-NEXT: j .LBB7_3 320; RV32IBB-NEXT: .LBB7_2: 321; RV32IBB-NEXT: sll a4, a1, a2 322; RV32IBB-NEXT: sub a3, a6, a3 323; RV32IBB-NEXT: srli a5, a0, 1 324; RV32IBB-NEXT: srl a3, a5, a3 325; RV32IBB-NEXT: or a7, a4, a3 326; RV32IBB-NEXT: .LBB7_3: 327; RV32IBB-NEXT: neg a4, a2 328; RV32IBB-NEXT: andi a5, a4, 63 329; RV32IBB-NEXT: addi a3, a5, -32 330; RV32IBB-NEXT: bltz a3, .LBB7_7 331; RV32IBB-NEXT: # %bb.4: 332; RV32IBB-NEXT: mv t0, zero 333; RV32IBB-NEXT: bgez a3, .LBB7_8 334; RV32IBB-NEXT: .LBB7_5: 335; RV32IBB-NEXT: srl a3, a0, a4 336; RV32IBB-NEXT: sub a4, a6, a5 337; RV32IBB-NEXT: slli a1, a1, 1 338; RV32IBB-NEXT: sll a1, a1, a4 339; RV32IBB-NEXT: or a4, a3, a1 340; RV32IBB-NEXT: or a1, a7, t0 341; RV32IBB-NEXT: bgez t1, .LBB7_9 342; RV32IBB-NEXT: .LBB7_6: 343; RV32IBB-NEXT: sll a0, a0, a2 344; RV32IBB-NEXT: or a0, a0, a4 345; RV32IBB-NEXT: ret 346; RV32IBB-NEXT: .LBB7_7: 347; RV32IBB-NEXT: srl t0, a1, a4 348; RV32IBB-NEXT: bltz a3, .LBB7_5 349; RV32IBB-NEXT: .LBB7_8: 350; RV32IBB-NEXT: srl a4, a1, a3 351; RV32IBB-NEXT: or a1, a7, t0 352; RV32IBB-NEXT: bltz t1, .LBB7_6 353; RV32IBB-NEXT: .LBB7_9: 354; RV32IBB-NEXT: or a0, zero, a4 355; RV32IBB-NEXT: ret 356; 357; RV32IBP-LABEL: rol_i64: 358; RV32IBP: # %bb.0: 359; RV32IBP-NEXT: andi a3, a2, 63 360; RV32IBP-NEXT: addi t1, a3, -32 361; RV32IBP-NEXT: addi a6, zero, 31 362; RV32IBP-NEXT: bltz t1, .LBB7_2 363; RV32IBP-NEXT: # %bb.1: 364; RV32IBP-NEXT: sll a7, a0, t1 365; RV32IBP-NEXT: j .LBB7_3 366; RV32IBP-NEXT: .LBB7_2: 367; RV32IBP-NEXT: sll a4, a1, a2 368; RV32IBP-NEXT: sub a3, a6, a3 369; RV32IBP-NEXT: srli a5, a0, 1 370; RV32IBP-NEXT: srl a3, a5, a3 371; RV32IBP-NEXT: or a7, a4, a3 372; RV32IBP-NEXT: .LBB7_3: 373; RV32IBP-NEXT: neg a4, a2 374; RV32IBP-NEXT: andi a5, a4, 63 375; RV32IBP-NEXT: addi a3, a5, -32 376; RV32IBP-NEXT: bltz a3, .LBB7_7 377; RV32IBP-NEXT: # %bb.4: 378; RV32IBP-NEXT: mv t0, zero 379; RV32IBP-NEXT: bgez a3, .LBB7_8 380; RV32IBP-NEXT: .LBB7_5: 381; RV32IBP-NEXT: srl a3, a0, a4 382; RV32IBP-NEXT: sub a4, a6, a5 383; RV32IBP-NEXT: slli a1, a1, 1 384; RV32IBP-NEXT: sll a1, a1, a4 385; RV32IBP-NEXT: or a4, a3, a1 386; RV32IBP-NEXT: or a1, a7, t0 387; RV32IBP-NEXT: bgez t1, .LBB7_9 388; RV32IBP-NEXT: .LBB7_6: 389; RV32IBP-NEXT: sll a0, a0, a2 390; RV32IBP-NEXT: or a0, a0, a4 391; RV32IBP-NEXT: ret 392; RV32IBP-NEXT: .LBB7_7: 393; RV32IBP-NEXT: srl t0, a1, a4 394; RV32IBP-NEXT: bltz a3, .LBB7_5 395; RV32IBP-NEXT: .LBB7_8: 396; RV32IBP-NEXT: srl a4, a1, a3 397; RV32IBP-NEXT: or a1, a7, t0 398; RV32IBP-NEXT: bltz t1, .LBB7_6 399; RV32IBP-NEXT: .LBB7_9: 400; RV32IBP-NEXT: or a0, zero, a4 401; RV32IBP-NEXT: ret 402 %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b) 403 ret i64 %or 404} 405 406declare i32 @llvm.fshr.i32(i32, i32, i32) 407 408define i32 @ror_i32(i32 %a, i32 %b) nounwind { 409; RV32I-LABEL: ror_i32: 410; RV32I: # %bb.0: 411; RV32I-NEXT: srl a2, a0, a1 412; RV32I-NEXT: neg a1, a1 413; RV32I-NEXT: sll a0, a0, a1 414; RV32I-NEXT: or a0, a2, a0 415; RV32I-NEXT: ret 416; 417; RV32IB-LABEL: ror_i32: 418; RV32IB: # %bb.0: 419; RV32IB-NEXT: ror a0, a0, a1 420; RV32IB-NEXT: ret 421; 422; RV32IBB-LABEL: ror_i32: 423; RV32IBB: # %bb.0: 424; RV32IBB-NEXT: ror a0, a0, a1 425; RV32IBB-NEXT: ret 426; 427; RV32IBP-LABEL: ror_i32: 428; RV32IBP: # %bb.0: 429; RV32IBP-NEXT: ror a0, a0, a1 430; RV32IBP-NEXT: ret 431 %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b) 432 ret i32 %or 433} 434 435; As we are not matching directly i64 code patterns on RV32 some i64 patterns 436; don't have yet any matching bit manipulation instructions on RV32. 437; This test is presented here in case future expansions of the experimental-b 438; extension introduce instructions suitable for this pattern. 439 440declare i64 @llvm.fshr.i64(i64, i64, i64) 441 442define i64 @ror_i64(i64 %a, i64 %b) nounwind { 443; RV32I-LABEL: ror_i64: 444; RV32I: # %bb.0: 445; RV32I-NEXT: andi a3, a2, 63 446; RV32I-NEXT: addi t1, a3, -32 447; RV32I-NEXT: addi a6, zero, 31 448; RV32I-NEXT: bltz t1, .LBB9_2 449; RV32I-NEXT: # %bb.1: 450; RV32I-NEXT: srl a7, a1, t1 451; RV32I-NEXT: j .LBB9_3 452; RV32I-NEXT: .LBB9_2: 453; RV32I-NEXT: srl a4, a0, a2 454; RV32I-NEXT: sub a3, a6, a3 455; RV32I-NEXT: slli a5, a1, 1 456; RV32I-NEXT: sll a3, a5, a3 457; RV32I-NEXT: or a7, a4, a3 458; RV32I-NEXT: .LBB9_3: 459; RV32I-NEXT: neg a4, a2 460; RV32I-NEXT: andi a5, a4, 63 461; RV32I-NEXT: addi a3, a5, -32 462; RV32I-NEXT: bltz a3, .LBB9_7 463; RV32I-NEXT: # %bb.4: 464; RV32I-NEXT: mv t0, zero 465; RV32I-NEXT: bgez a3, .LBB9_8 466; RV32I-NEXT: .LBB9_5: 467; RV32I-NEXT: sll a3, a1, a4 468; RV32I-NEXT: sub a4, a6, a5 469; RV32I-NEXT: srli a0, a0, 1 470; RV32I-NEXT: srl a0, a0, a4 471; RV32I-NEXT: or a4, a3, a0 472; RV32I-NEXT: or a0, a7, t0 473; RV32I-NEXT: bgez t1, .LBB9_9 474; RV32I-NEXT: .LBB9_6: 475; RV32I-NEXT: srl a1, a1, a2 476; RV32I-NEXT: or a1, a1, a4 477; RV32I-NEXT: ret 478; RV32I-NEXT: .LBB9_7: 479; RV32I-NEXT: sll t0, a0, a4 480; RV32I-NEXT: bltz a3, .LBB9_5 481; RV32I-NEXT: .LBB9_8: 482; RV32I-NEXT: sll a4, a0, a3 483; RV32I-NEXT: or a0, a7, t0 484; RV32I-NEXT: bltz t1, .LBB9_6 485; RV32I-NEXT: .LBB9_9: 486; RV32I-NEXT: or a1, zero, a4 487; RV32I-NEXT: ret 488; 489; RV32IB-LABEL: ror_i64: 490; RV32IB: # %bb.0: 491; RV32IB-NEXT: andi a3, a2, 63 492; RV32IB-NEXT: addi t1, a3, -32 493; RV32IB-NEXT: addi a6, zero, 31 494; RV32IB-NEXT: bltz t1, .LBB9_2 495; RV32IB-NEXT: # %bb.1: 496; RV32IB-NEXT: srl a7, a1, t1 497; RV32IB-NEXT: j .LBB9_3 498; RV32IB-NEXT: .LBB9_2: 499; RV32IB-NEXT: srl a4, a0, a2 500; RV32IB-NEXT: sub a3, a6, a3 501; RV32IB-NEXT: slli a5, a1, 1 502; RV32IB-NEXT: sll a3, a5, a3 503; RV32IB-NEXT: or a7, a4, a3 504; RV32IB-NEXT: .LBB9_3: 505; RV32IB-NEXT: neg a4, a2 506; RV32IB-NEXT: andi a5, a4, 63 507; RV32IB-NEXT: addi a3, a5, -32 508; RV32IB-NEXT: bltz a3, .LBB9_7 509; RV32IB-NEXT: # %bb.4: 510; RV32IB-NEXT: mv t0, zero 511; RV32IB-NEXT: bgez a3, .LBB9_8 512; RV32IB-NEXT: .LBB9_5: 513; RV32IB-NEXT: sll a3, a1, a4 514; RV32IB-NEXT: sub a4, a6, a5 515; RV32IB-NEXT: srli a0, a0, 1 516; RV32IB-NEXT: srl a0, a0, a4 517; RV32IB-NEXT: or a4, a3, a0 518; RV32IB-NEXT: or a0, a7, t0 519; RV32IB-NEXT: bgez t1, .LBB9_9 520; RV32IB-NEXT: .LBB9_6: 521; RV32IB-NEXT: srl a1, a1, a2 522; RV32IB-NEXT: or a1, a1, a4 523; RV32IB-NEXT: ret 524; RV32IB-NEXT: .LBB9_7: 525; RV32IB-NEXT: sll t0, a0, a4 526; RV32IB-NEXT: bltz a3, .LBB9_5 527; RV32IB-NEXT: .LBB9_8: 528; RV32IB-NEXT: sll a4, a0, a3 529; RV32IB-NEXT: or a0, a7, t0 530; RV32IB-NEXT: bltz t1, .LBB9_6 531; RV32IB-NEXT: .LBB9_9: 532; RV32IB-NEXT: or a1, zero, a4 533; RV32IB-NEXT: ret 534; 535; RV32IBB-LABEL: ror_i64: 536; RV32IBB: # %bb.0: 537; RV32IBB-NEXT: andi a3, a2, 63 538; RV32IBB-NEXT: addi t1, a3, -32 539; RV32IBB-NEXT: addi a6, zero, 31 540; RV32IBB-NEXT: bltz t1, .LBB9_2 541; RV32IBB-NEXT: # %bb.1: 542; RV32IBB-NEXT: srl a7, a1, t1 543; RV32IBB-NEXT: j .LBB9_3 544; RV32IBB-NEXT: .LBB9_2: 545; RV32IBB-NEXT: srl a4, a0, a2 546; RV32IBB-NEXT: sub a3, a6, a3 547; RV32IBB-NEXT: slli a5, a1, 1 548; RV32IBB-NEXT: sll a3, a5, a3 549; RV32IBB-NEXT: or a7, a4, a3 550; RV32IBB-NEXT: .LBB9_3: 551; RV32IBB-NEXT: neg a4, a2 552; RV32IBB-NEXT: andi a5, a4, 63 553; RV32IBB-NEXT: addi a3, a5, -32 554; RV32IBB-NEXT: bltz a3, .LBB9_7 555; RV32IBB-NEXT: # %bb.4: 556; RV32IBB-NEXT: mv t0, zero 557; RV32IBB-NEXT: bgez a3, .LBB9_8 558; RV32IBB-NEXT: .LBB9_5: 559; RV32IBB-NEXT: sll a3, a1, a4 560; RV32IBB-NEXT: sub a4, a6, a5 561; RV32IBB-NEXT: srli a0, a0, 1 562; RV32IBB-NEXT: srl a0, a0, a4 563; RV32IBB-NEXT: or a4, a3, a0 564; RV32IBB-NEXT: or a0, a7, t0 565; RV32IBB-NEXT: bgez t1, .LBB9_9 566; RV32IBB-NEXT: .LBB9_6: 567; RV32IBB-NEXT: srl a1, a1, a2 568; RV32IBB-NEXT: or a1, a1, a4 569; RV32IBB-NEXT: ret 570; RV32IBB-NEXT: .LBB9_7: 571; RV32IBB-NEXT: sll t0, a0, a4 572; RV32IBB-NEXT: bltz a3, .LBB9_5 573; RV32IBB-NEXT: .LBB9_8: 574; RV32IBB-NEXT: sll a4, a0, a3 575; RV32IBB-NEXT: or a0, a7, t0 576; RV32IBB-NEXT: bltz t1, .LBB9_6 577; RV32IBB-NEXT: .LBB9_9: 578; RV32IBB-NEXT: or a1, zero, a4 579; RV32IBB-NEXT: ret 580; 581; RV32IBP-LABEL: ror_i64: 582; RV32IBP: # %bb.0: 583; RV32IBP-NEXT: andi a3, a2, 63 584; RV32IBP-NEXT: addi t1, a3, -32 585; RV32IBP-NEXT: addi a6, zero, 31 586; RV32IBP-NEXT: bltz t1, .LBB9_2 587; RV32IBP-NEXT: # %bb.1: 588; RV32IBP-NEXT: srl a7, a1, t1 589; RV32IBP-NEXT: j .LBB9_3 590; RV32IBP-NEXT: .LBB9_2: 591; RV32IBP-NEXT: srl a4, a0, a2 592; RV32IBP-NEXT: sub a3, a6, a3 593; RV32IBP-NEXT: slli a5, a1, 1 594; RV32IBP-NEXT: sll a3, a5, a3 595; RV32IBP-NEXT: or a7, a4, a3 596; RV32IBP-NEXT: .LBB9_3: 597; RV32IBP-NEXT: neg a4, a2 598; RV32IBP-NEXT: andi a5, a4, 63 599; RV32IBP-NEXT: addi a3, a5, -32 600; RV32IBP-NEXT: bltz a3, .LBB9_7 601; RV32IBP-NEXT: # %bb.4: 602; RV32IBP-NEXT: mv t0, zero 603; RV32IBP-NEXT: bgez a3, .LBB9_8 604; RV32IBP-NEXT: .LBB9_5: 605; RV32IBP-NEXT: sll a3, a1, a4 606; RV32IBP-NEXT: sub a4, a6, a5 607; RV32IBP-NEXT: srli a0, a0, 1 608; RV32IBP-NEXT: srl a0, a0, a4 609; RV32IBP-NEXT: or a4, a3, a0 610; RV32IBP-NEXT: or a0, a7, t0 611; RV32IBP-NEXT: bgez t1, .LBB9_9 612; RV32IBP-NEXT: .LBB9_6: 613; RV32IBP-NEXT: srl a1, a1, a2 614; RV32IBP-NEXT: or a1, a1, a4 615; RV32IBP-NEXT: ret 616; RV32IBP-NEXT: .LBB9_7: 617; RV32IBP-NEXT: sll t0, a0, a4 618; RV32IBP-NEXT: bltz a3, .LBB9_5 619; RV32IBP-NEXT: .LBB9_8: 620; RV32IBP-NEXT: sll a4, a0, a3 621; RV32IBP-NEXT: or a0, a7, t0 622; RV32IBP-NEXT: bltz t1, .LBB9_6 623; RV32IBP-NEXT: .LBB9_9: 624; RV32IBP-NEXT: or a1, zero, a4 625; RV32IBP-NEXT: ret 626 %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b) 627 ret i64 %or 628} 629 630define i32 @rori_i32_fshl(i32 %a) nounwind { 631; RV32I-LABEL: rori_i32_fshl: 632; RV32I: # %bb.0: 633; RV32I-NEXT: srli a1, a0, 1 634; RV32I-NEXT: slli a0, a0, 31 635; RV32I-NEXT: or a0, a0, a1 636; RV32I-NEXT: ret 637; 638; RV32IB-LABEL: rori_i32_fshl: 639; RV32IB: # %bb.0: 640; RV32IB-NEXT: rori a0, a0, 1 641; RV32IB-NEXT: ret 642; 643; RV32IBB-LABEL: rori_i32_fshl: 644; RV32IBB: # %bb.0: 645; RV32IBB-NEXT: rori a0, a0, 1 646; RV32IBB-NEXT: ret 647; 648; RV32IBP-LABEL: rori_i32_fshl: 649; RV32IBP: # %bb.0: 650; RV32IBP-NEXT: rori a0, a0, 1 651; RV32IBP-NEXT: ret 652 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31) 653 ret i32 %1 654} 655 656define i32 @rori_i32_fshr(i32 %a) nounwind { 657; RV32I-LABEL: rori_i32_fshr: 658; RV32I: # %bb.0: 659; RV32I-NEXT: slli a1, a0, 1 660; RV32I-NEXT: srli a0, a0, 31 661; RV32I-NEXT: or a0, a0, a1 662; RV32I-NEXT: ret 663; 664; RV32IB-LABEL: rori_i32_fshr: 665; RV32IB: # %bb.0: 666; RV32IB-NEXT: rori a0, a0, 31 667; RV32IB-NEXT: ret 668; 669; RV32IBB-LABEL: rori_i32_fshr: 670; RV32IBB: # %bb.0: 671; RV32IBB-NEXT: rori a0, a0, 31 672; RV32IBB-NEXT: ret 673; 674; RV32IBP-LABEL: rori_i32_fshr: 675; RV32IBP: # %bb.0: 676; RV32IBP-NEXT: rori a0, a0, 31 677; RV32IBP-NEXT: ret 678 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31) 679 ret i32 %1 680} 681 682define i64 @rori_i64(i64 %a) nounwind { 683; RV32I-LABEL: rori_i64: 684; RV32I: # %bb.0: 685; RV32I-NEXT: slli a2, a1, 31 686; RV32I-NEXT: srli a3, a0, 1 687; RV32I-NEXT: or a2, a3, a2 688; RV32I-NEXT: srli a1, a1, 1 689; RV32I-NEXT: slli a0, a0, 31 690; RV32I-NEXT: or a1, a0, a1 691; RV32I-NEXT: mv a0, a2 692; RV32I-NEXT: ret 693; 694; RV32IB-LABEL: rori_i64: 695; RV32IB: # %bb.0: 696; RV32IB-NEXT: fsri a2, a0, a1, 1 697; RV32IB-NEXT: fsri a1, a1, a0, 1 698; RV32IB-NEXT: mv a0, a2 699; RV32IB-NEXT: ret 700; 701; RV32IBB-LABEL: rori_i64: 702; RV32IBB: # %bb.0: 703; RV32IBB-NEXT: slli a2, a1, 31 704; RV32IBB-NEXT: srli a3, a0, 1 705; RV32IBB-NEXT: or a2, a3, a2 706; RV32IBB-NEXT: srli a1, a1, 1 707; RV32IBB-NEXT: slli a0, a0, 31 708; RV32IBB-NEXT: or a1, a0, a1 709; RV32IBB-NEXT: mv a0, a2 710; RV32IBB-NEXT: ret 711; 712; RV32IBP-LABEL: rori_i64: 713; RV32IBP: # %bb.0: 714; RV32IBP-NEXT: slli a2, a1, 31 715; RV32IBP-NEXT: srli a3, a0, 1 716; RV32IBP-NEXT: or a2, a3, a2 717; RV32IBP-NEXT: srli a1, a1, 1 718; RV32IBP-NEXT: slli a0, a0, 31 719; RV32IBP-NEXT: or a1, a0, a1 720; RV32IBP-NEXT: mv a0, a2 721; RV32IBP-NEXT: ret 722 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63) 723 ret i64 %1 724} 725 726define i64 @rori_i64_fshr(i64 %a) nounwind { 727; RV32I-LABEL: rori_i64_fshr: 728; RV32I: # %bb.0: 729; RV32I-NEXT: slli a2, a0, 1 730; RV32I-NEXT: srli a3, a1, 31 731; RV32I-NEXT: or a2, a3, a2 732; RV32I-NEXT: srli a0, a0, 31 733; RV32I-NEXT: slli a1, a1, 1 734; RV32I-NEXT: or a1, a1, a0 735; RV32I-NEXT: mv a0, a2 736; RV32I-NEXT: ret 737; 738; RV32IB-LABEL: rori_i64_fshr: 739; RV32IB: # %bb.0: 740; RV32IB-NEXT: fsri a2, a1, a0, 31 741; RV32IB-NEXT: fsri a1, a0, a1, 31 742; RV32IB-NEXT: mv a0, a2 743; RV32IB-NEXT: ret 744; 745; RV32IBB-LABEL: rori_i64_fshr: 746; RV32IBB: # %bb.0: 747; RV32IBB-NEXT: slli a2, a0, 1 748; RV32IBB-NEXT: srli a3, a1, 31 749; RV32IBB-NEXT: or a2, a3, a2 750; RV32IBB-NEXT: srli a0, a0, 31 751; RV32IBB-NEXT: slli a1, a1, 1 752; RV32IBB-NEXT: or a1, a1, a0 753; RV32IBB-NEXT: mv a0, a2 754; RV32IBB-NEXT: ret 755; 756; RV32IBP-LABEL: rori_i64_fshr: 757; RV32IBP: # %bb.0: 758; RV32IBP-NEXT: slli a2, a0, 1 759; RV32IBP-NEXT: srli a3, a1, 31 760; RV32IBP-NEXT: or a2, a3, a2 761; RV32IBP-NEXT: srli a0, a0, 31 762; RV32IBP-NEXT: slli a1, a1, 1 763; RV32IBP-NEXT: or a1, a1, a0 764; RV32IBP-NEXT: mv a0, a2 765; RV32IBP-NEXT: ret 766 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63) 767 ret i64 %1 768} 769 770define i32 @pack_i32(i32 %a, i32 %b) nounwind { 771; RV32I-LABEL: pack_i32: 772; RV32I: # %bb.0: 773; RV32I-NEXT: lui a2, 16 774; RV32I-NEXT: addi a2, a2, -1 775; RV32I-NEXT: and a0, a0, a2 776; RV32I-NEXT: slli a1, a1, 16 777; RV32I-NEXT: or a0, a1, a0 778; RV32I-NEXT: ret 779; 780; RV32IB-LABEL: pack_i32: 781; RV32IB: # %bb.0: 782; RV32IB-NEXT: pack a0, a0, a1 783; RV32IB-NEXT: ret 784; 785; RV32IBB-LABEL: pack_i32: 786; RV32IBB: # %bb.0: 787; RV32IBB-NEXT: pack a0, a0, a1 788; RV32IBB-NEXT: ret 789; 790; RV32IBP-LABEL: pack_i32: 791; RV32IBP: # %bb.0: 792; RV32IBP-NEXT: pack a0, a0, a1 793; RV32IBP-NEXT: ret 794 %shl = and i32 %a, 65535 795 %shl1 = shl i32 %b, 16 796 %or = or i32 %shl1, %shl 797 ret i32 %or 798} 799 800; As we are not matching directly i64 code patterns on RV32 some i64 patterns 801; don't have yet any matching bit manipulation instructions on RV32. 802; This test is presented here in case future expansions of the experimental-b 803; extension introduce instructions suitable for this pattern. 804 805define i64 @pack_i64(i64 %a, i64 %b) nounwind { 806; RV32I-LABEL: pack_i64: 807; RV32I: # %bb.0: 808; RV32I-NEXT: mv a1, a2 809; RV32I-NEXT: ret 810; 811; RV32IB-LABEL: pack_i64: 812; RV32IB: # %bb.0: 813; RV32IB-NEXT: mv a1, a2 814; RV32IB-NEXT: ret 815; 816; RV32IBB-LABEL: pack_i64: 817; RV32IBB: # %bb.0: 818; RV32IBB-NEXT: mv a1, a2 819; RV32IBB-NEXT: ret 820; 821; RV32IBP-LABEL: pack_i64: 822; RV32IBP: # %bb.0: 823; RV32IBP-NEXT: mv a1, a2 824; RV32IBP-NEXT: ret 825 %shl = and i64 %a, 4294967295 826 %shl1 = shl i64 %b, 32 827 %or = or i64 %shl1, %shl 828 ret i64 %or 829} 830 831define i32 @packu_i32(i32 %a, i32 %b) nounwind { 832; RV32I-LABEL: packu_i32: 833; RV32I: # %bb.0: 834; RV32I-NEXT: srli a0, a0, 16 835; RV32I-NEXT: lui a2, 1048560 836; RV32I-NEXT: and a1, a1, a2 837; RV32I-NEXT: or a0, a1, a0 838; RV32I-NEXT: ret 839; 840; RV32IB-LABEL: packu_i32: 841; RV32IB: # %bb.0: 842; RV32IB-NEXT: packu a0, a0, a1 843; RV32IB-NEXT: ret 844; 845; RV32IBB-LABEL: packu_i32: 846; RV32IBB: # %bb.0: 847; RV32IBB-NEXT: packu a0, a0, a1 848; RV32IBB-NEXT: ret 849; 850; RV32IBP-LABEL: packu_i32: 851; RV32IBP: # %bb.0: 852; RV32IBP-NEXT: packu a0, a0, a1 853; RV32IBP-NEXT: ret 854 %shr = lshr i32 %a, 16 855 %shr1 = and i32 %b, -65536 856 %or = or i32 %shr1, %shr 857 ret i32 %or 858} 859 860; As we are not matching directly i64 code patterns on RV32 some i64 patterns 861; don't have yet any matching bit manipulation instructions on RV32. 862; This test is presented here in case future expansions of the experimental-b 863; extension introduce instructions suitable for this pattern. 864 865define i64 @packu_i64(i64 %a, i64 %b) nounwind { 866; RV32I-LABEL: packu_i64: 867; RV32I: # %bb.0: 868; RV32I-NEXT: mv a0, a1 869; RV32I-NEXT: mv a1, a3 870; RV32I-NEXT: ret 871; 872; RV32IB-LABEL: packu_i64: 873; RV32IB: # %bb.0: 874; RV32IB-NEXT: mv a0, a1 875; RV32IB-NEXT: mv a1, a3 876; RV32IB-NEXT: ret 877; 878; RV32IBB-LABEL: packu_i64: 879; RV32IBB: # %bb.0: 880; RV32IBB-NEXT: mv a0, a1 881; RV32IBB-NEXT: mv a1, a3 882; RV32IBB-NEXT: ret 883; 884; RV32IBP-LABEL: packu_i64: 885; RV32IBP: # %bb.0: 886; RV32IBP-NEXT: mv a0, a1 887; RV32IBP-NEXT: mv a1, a3 888; RV32IBP-NEXT: ret 889 %shr = lshr i64 %a, 32 890 %shr1 = and i64 %b, -4294967296 891 %or = or i64 %shr1, %shr 892 ret i64 %or 893} 894 895define i32 @packh_i32(i32 %a, i32 %b) nounwind { 896; RV32I-LABEL: packh_i32: 897; RV32I: # %bb.0: 898; RV32I-NEXT: andi a0, a0, 255 899; RV32I-NEXT: slli a1, a1, 8 900; RV32I-NEXT: lui a2, 16 901; RV32I-NEXT: addi a2, a2, -256 902; RV32I-NEXT: and a1, a1, a2 903; RV32I-NEXT: or a0, a1, a0 904; RV32I-NEXT: ret 905; 906; RV32IB-LABEL: packh_i32: 907; RV32IB: # %bb.0: 908; RV32IB-NEXT: packh a0, a0, a1 909; RV32IB-NEXT: ret 910; 911; RV32IBB-LABEL: packh_i32: 912; RV32IBB: # %bb.0: 913; RV32IBB-NEXT: packh a0, a0, a1 914; RV32IBB-NEXT: ret 915; 916; RV32IBP-LABEL: packh_i32: 917; RV32IBP: # %bb.0: 918; RV32IBP-NEXT: packh a0, a0, a1 919; RV32IBP-NEXT: ret 920 %and = and i32 %a, 255 921 %and1 = shl i32 %b, 8 922 %shl = and i32 %and1, 65280 923 %or = or i32 %shl, %and 924 ret i32 %or 925} 926 927define i64 @packh_i64(i64 %a, i64 %b) nounwind { 928; RV32I-LABEL: packh_i64: 929; RV32I: # %bb.0: 930; RV32I-NEXT: andi a0, a0, 255 931; RV32I-NEXT: slli a1, a2, 8 932; RV32I-NEXT: lui a2, 16 933; RV32I-NEXT: addi a2, a2, -256 934; RV32I-NEXT: and a1, a1, a2 935; RV32I-NEXT: or a0, a1, a0 936; RV32I-NEXT: mv a1, zero 937; RV32I-NEXT: ret 938; 939; RV32IB-LABEL: packh_i64: 940; RV32IB: # %bb.0: 941; RV32IB-NEXT: packh a0, a0, a2 942; RV32IB-NEXT: mv a1, zero 943; RV32IB-NEXT: ret 944; 945; RV32IBB-LABEL: packh_i64: 946; RV32IBB: # %bb.0: 947; RV32IBB-NEXT: packh a0, a0, a2 948; RV32IBB-NEXT: mv a1, zero 949; RV32IBB-NEXT: ret 950; 951; RV32IBP-LABEL: packh_i64: 952; RV32IBP: # %bb.0: 953; RV32IBP-NEXT: packh a0, a0, a2 954; RV32IBP-NEXT: mv a1, zero 955; RV32IBP-NEXT: ret 956 %and = and i64 %a, 255 957 %and1 = shl i64 %b, 8 958 %shl = and i64 %and1, 65280 959 %or = or i64 %shl, %and 960 ret i64 %or 961} 962 963define i32 @zexth_i32(i32 %a) nounwind { 964; RV32I-LABEL: zexth_i32: 965; RV32I: # %bb.0: 966; RV32I-NEXT: lui a1, 16 967; RV32I-NEXT: addi a1, a1, -1 968; RV32I-NEXT: and a0, a0, a1 969; RV32I-NEXT: ret 970; 971; RV32IB-LABEL: zexth_i32: 972; RV32IB: # %bb.0: 973; RV32IB-NEXT: zext.h a0, a0 974; RV32IB-NEXT: ret 975; 976; RV32IBB-LABEL: zexth_i32: 977; RV32IBB: # %bb.0: 978; RV32IBB-NEXT: zext.h a0, a0 979; RV32IBB-NEXT: ret 980; 981; RV32IBP-LABEL: zexth_i32: 982; RV32IBP: # %bb.0: 983; RV32IBP-NEXT: pack a0, a0, zero 984; RV32IBP-NEXT: ret 985 %and = and i32 %a, 65535 986 ret i32 %and 987} 988 989define i64 @zexth_i64(i64 %a) nounwind { 990; RV32I-LABEL: zexth_i64: 991; RV32I: # %bb.0: 992; RV32I-NEXT: lui a1, 16 993; RV32I-NEXT: addi a1, a1, -1 994; RV32I-NEXT: and a0, a0, a1 995; RV32I-NEXT: mv a1, zero 996; RV32I-NEXT: ret 997; 998; RV32IB-LABEL: zexth_i64: 999; RV32IB: # %bb.0: 1000; RV32IB-NEXT: zext.h a0, a0 1001; RV32IB-NEXT: mv a1, zero 1002; RV32IB-NEXT: ret 1003; 1004; RV32IBB-LABEL: zexth_i64: 1005; RV32IBB: # %bb.0: 1006; RV32IBB-NEXT: zext.h a0, a0 1007; RV32IBB-NEXT: mv a1, zero 1008; RV32IBB-NEXT: ret 1009; 1010; RV32IBP-LABEL: zexth_i64: 1011; RV32IBP: # %bb.0: 1012; RV32IBP-NEXT: pack a0, a0, zero 1013; RV32IBP-NEXT: mv a1, zero 1014; RV32IBP-NEXT: ret 1015 %and = and i64 %a, 65535 1016 ret i64 %and 1017} 1018