1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV64I 4; RUN: llc -mtriple=riscv64 -mattr=+experimental-b -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64IB 6; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbb -verify-machineinstrs < %s \ 7; RUN: | FileCheck %s -check-prefix=RV64IBB 8; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbp -verify-machineinstrs < %s \ 9; RUN: | FileCheck %s -check-prefix=RV64IBP 10 11define signext i32 @andn_i32(i32 signext %a, i32 signext %b) nounwind { 12; RV64I-LABEL: andn_i32: 13; RV64I: # %bb.0: 14; RV64I-NEXT: not a1, a1 15; RV64I-NEXT: and a0, a1, a0 16; RV64I-NEXT: ret 17; 18; RV64IB-LABEL: andn_i32: 19; RV64IB: # %bb.0: 20; RV64IB-NEXT: andn a0, a0, a1 21; RV64IB-NEXT: ret 22; 23; RV64IBB-LABEL: andn_i32: 24; RV64IBB: # %bb.0: 25; RV64IBB-NEXT: andn a0, a0, a1 26; RV64IBB-NEXT: ret 27; 28; RV64IBP-LABEL: andn_i32: 29; RV64IBP: # %bb.0: 30; RV64IBP-NEXT: andn a0, a0, a1 31; RV64IBP-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; RV64I-LABEL: andn_i64: 39; RV64I: # %bb.0: 40; RV64I-NEXT: not a1, a1 41; RV64I-NEXT: and a0, a1, a0 42; RV64I-NEXT: ret 43; 44; RV64IB-LABEL: andn_i64: 45; RV64IB: # %bb.0: 46; RV64IB-NEXT: andn a0, a0, a1 47; RV64IB-NEXT: ret 48; 49; RV64IBB-LABEL: andn_i64: 50; RV64IBB: # %bb.0: 51; RV64IBB-NEXT: andn a0, a0, a1 52; RV64IBB-NEXT: ret 53; 54; RV64IBP-LABEL: andn_i64: 55; RV64IBP: # %bb.0: 56; RV64IBP-NEXT: andn a0, a0, a1 57; RV64IBP-NEXT: ret 58 %neg = xor i64 %b, -1 59 %and = and i64 %neg, %a 60 ret i64 %and 61} 62 63define signext i32 @orn_i32(i32 signext %a, i32 signext %b) nounwind { 64; RV64I-LABEL: orn_i32: 65; RV64I: # %bb.0: 66; RV64I-NEXT: not a1, a1 67; RV64I-NEXT: or a0, a1, a0 68; RV64I-NEXT: ret 69; 70; RV64IB-LABEL: orn_i32: 71; RV64IB: # %bb.0: 72; RV64IB-NEXT: orn a0, a0, a1 73; RV64IB-NEXT: ret 74; 75; RV64IBB-LABEL: orn_i32: 76; RV64IBB: # %bb.0: 77; RV64IBB-NEXT: orn a0, a0, a1 78; RV64IBB-NEXT: ret 79; 80; RV64IBP-LABEL: orn_i32: 81; RV64IBP: # %bb.0: 82; RV64IBP-NEXT: orn a0, a0, a1 83; RV64IBP-NEXT: ret 84 %neg = xor i32 %b, -1 85 %or = or i32 %neg, %a 86 ret i32 %or 87} 88 89define i64 @orn_i64(i64 %a, i64 %b) nounwind { 90; RV64I-LABEL: orn_i64: 91; RV64I: # %bb.0: 92; RV64I-NEXT: not a1, a1 93; RV64I-NEXT: or a0, a1, a0 94; RV64I-NEXT: ret 95; 96; RV64IB-LABEL: orn_i64: 97; RV64IB: # %bb.0: 98; RV64IB-NEXT: orn a0, a0, a1 99; RV64IB-NEXT: ret 100; 101; RV64IBB-LABEL: orn_i64: 102; RV64IBB: # %bb.0: 103; RV64IBB-NEXT: orn a0, a0, a1 104; RV64IBB-NEXT: ret 105; 106; RV64IBP-LABEL: orn_i64: 107; RV64IBP: # %bb.0: 108; RV64IBP-NEXT: orn a0, a0, a1 109; RV64IBP-NEXT: ret 110 %neg = xor i64 %b, -1 111 %or = or i64 %neg, %a 112 ret i64 %or 113} 114 115define signext i32 @xnor_i32(i32 signext %a, i32 signext %b) nounwind { 116; RV64I-LABEL: xnor_i32: 117; RV64I: # %bb.0: 118; RV64I-NEXT: xor a0, a0, a1 119; RV64I-NEXT: not a0, a0 120; RV64I-NEXT: ret 121; 122; RV64IB-LABEL: xnor_i32: 123; RV64IB: # %bb.0: 124; RV64IB-NEXT: xnor a0, a0, a1 125; RV64IB-NEXT: ret 126; 127; RV64IBB-LABEL: xnor_i32: 128; RV64IBB: # %bb.0: 129; RV64IBB-NEXT: xnor a0, a0, a1 130; RV64IBB-NEXT: ret 131; 132; RV64IBP-LABEL: xnor_i32: 133; RV64IBP: # %bb.0: 134; RV64IBP-NEXT: xnor a0, a0, a1 135; RV64IBP-NEXT: ret 136 %neg = xor i32 %a, -1 137 %xor = xor i32 %neg, %b 138 ret i32 %xor 139} 140 141define i64 @xnor_i64(i64 %a, i64 %b) nounwind { 142; RV64I-LABEL: xnor_i64: 143; RV64I: # %bb.0: 144; RV64I-NEXT: xor a0, a0, a1 145; RV64I-NEXT: not a0, a0 146; RV64I-NEXT: ret 147; 148; RV64IB-LABEL: xnor_i64: 149; RV64IB: # %bb.0: 150; RV64IB-NEXT: xnor a0, a0, a1 151; RV64IB-NEXT: ret 152; 153; RV64IBB-LABEL: xnor_i64: 154; RV64IBB: # %bb.0: 155; RV64IBB-NEXT: xnor a0, a0, a1 156; RV64IBB-NEXT: ret 157; 158; RV64IBP-LABEL: xnor_i64: 159; RV64IBP: # %bb.0: 160; RV64IBP-NEXT: xnor a0, a0, a1 161; RV64IBP-NEXT: ret 162 %neg = xor i64 %a, -1 163 %xor = xor i64 %neg, %b 164 ret i64 %xor 165} 166 167declare i32 @llvm.fshl.i32(i32, i32, i32) 168 169define signext i32 @rol_i32(i32 signext %a, i32 signext %b) nounwind { 170; RV64I-LABEL: rol_i32: 171; RV64I: # %bb.0: 172; RV64I-NEXT: sllw a2, a0, a1 173; RV64I-NEXT: neg a1, a1 174; RV64I-NEXT: srlw a0, a0, a1 175; RV64I-NEXT: or a0, a2, a0 176; RV64I-NEXT: ret 177; 178; RV64IB-LABEL: rol_i32: 179; RV64IB: # %bb.0: 180; RV64IB-NEXT: rolw a0, a0, a1 181; RV64IB-NEXT: ret 182; 183; RV64IBB-LABEL: rol_i32: 184; RV64IBB: # %bb.0: 185; RV64IBB-NEXT: rolw a0, a0, a1 186; RV64IBB-NEXT: ret 187; 188; RV64IBP-LABEL: rol_i32: 189; RV64IBP: # %bb.0: 190; RV64IBP-NEXT: rolw a0, a0, a1 191; RV64IBP-NEXT: ret 192 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b) 193 ret i32 %1 194} 195 196; Similar to rol_i32, but doesn't sign extend the result. 197define void @rol_i32_nosext(i32 signext %a, i32 signext %b, i32* %x) nounwind { 198; RV64I-LABEL: rol_i32_nosext: 199; RV64I: # %bb.0: 200; RV64I-NEXT: sllw a3, a0, a1 201; RV64I-NEXT: neg a1, a1 202; RV64I-NEXT: srlw a0, a0, a1 203; RV64I-NEXT: or a0, a3, a0 204; RV64I-NEXT: sw a0, 0(a2) 205; RV64I-NEXT: ret 206; 207; RV64IB-LABEL: rol_i32_nosext: 208; RV64IB: # %bb.0: 209; RV64IB-NEXT: rolw a0, a0, a1 210; RV64IB-NEXT: sw a0, 0(a2) 211; RV64IB-NEXT: ret 212; 213; RV64IBB-LABEL: rol_i32_nosext: 214; RV64IBB: # %bb.0: 215; RV64IBB-NEXT: rolw a0, a0, a1 216; RV64IBB-NEXT: sw a0, 0(a2) 217; RV64IBB-NEXT: ret 218; 219; RV64IBP-LABEL: rol_i32_nosext: 220; RV64IBP: # %bb.0: 221; RV64IBP-NEXT: rolw a0, a0, a1 222; RV64IBP-NEXT: sw a0, 0(a2) 223; RV64IBP-NEXT: ret 224 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b) 225 store i32 %1, i32* %x 226 ret void 227} 228 229declare i64 @llvm.fshl.i64(i64, i64, i64) 230 231define i64 @rol_i64(i64 %a, i64 %b) nounwind { 232; RV64I-LABEL: rol_i64: 233; RV64I: # %bb.0: 234; RV64I-NEXT: sll a2, a0, a1 235; RV64I-NEXT: neg a1, a1 236; RV64I-NEXT: srl a0, a0, a1 237; RV64I-NEXT: or a0, a2, a0 238; RV64I-NEXT: ret 239; 240; RV64IB-LABEL: rol_i64: 241; RV64IB: # %bb.0: 242; RV64IB-NEXT: rol a0, a0, a1 243; RV64IB-NEXT: ret 244; 245; RV64IBB-LABEL: rol_i64: 246; RV64IBB: # %bb.0: 247; RV64IBB-NEXT: rol a0, a0, a1 248; RV64IBB-NEXT: ret 249; 250; RV64IBP-LABEL: rol_i64: 251; RV64IBP: # %bb.0: 252; RV64IBP-NEXT: rol a0, a0, a1 253; RV64IBP-NEXT: ret 254 %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b) 255 ret i64 %or 256} 257 258declare i32 @llvm.fshr.i32(i32, i32, i32) 259 260define signext i32 @ror_i32(i32 signext %a, i32 signext %b) nounwind { 261; RV64I-LABEL: ror_i32: 262; RV64I: # %bb.0: 263; RV64I-NEXT: srlw a2, a0, a1 264; RV64I-NEXT: neg a1, a1 265; RV64I-NEXT: sllw a0, a0, a1 266; RV64I-NEXT: or a0, a2, a0 267; RV64I-NEXT: ret 268; 269; RV64IB-LABEL: ror_i32: 270; RV64IB: # %bb.0: 271; RV64IB-NEXT: rorw a0, a0, a1 272; RV64IB-NEXT: ret 273; 274; RV64IBB-LABEL: ror_i32: 275; RV64IBB: # %bb.0: 276; RV64IBB-NEXT: rorw a0, a0, a1 277; RV64IBB-NEXT: ret 278; 279; RV64IBP-LABEL: ror_i32: 280; RV64IBP: # %bb.0: 281; RV64IBP-NEXT: rorw a0, a0, a1 282; RV64IBP-NEXT: ret 283 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b) 284 ret i32 %1 285} 286 287; Similar to ror_i32, but doesn't sign extend the result. 288define void @ror_i32_nosext(i32 signext %a, i32 signext %b, i32* %x) nounwind { 289; RV64I-LABEL: ror_i32_nosext: 290; RV64I: # %bb.0: 291; RV64I-NEXT: srlw a3, a0, a1 292; RV64I-NEXT: neg a1, a1 293; RV64I-NEXT: sllw a0, a0, a1 294; RV64I-NEXT: or a0, a3, a0 295; RV64I-NEXT: sw a0, 0(a2) 296; RV64I-NEXT: ret 297; 298; RV64IB-LABEL: ror_i32_nosext: 299; RV64IB: # %bb.0: 300; RV64IB-NEXT: rorw a0, a0, a1 301; RV64IB-NEXT: sw a0, 0(a2) 302; RV64IB-NEXT: ret 303; 304; RV64IBB-LABEL: ror_i32_nosext: 305; RV64IBB: # %bb.0: 306; RV64IBB-NEXT: rorw a0, a0, a1 307; RV64IBB-NEXT: sw a0, 0(a2) 308; RV64IBB-NEXT: ret 309; 310; RV64IBP-LABEL: ror_i32_nosext: 311; RV64IBP: # %bb.0: 312; RV64IBP-NEXT: rorw a0, a0, a1 313; RV64IBP-NEXT: sw a0, 0(a2) 314; RV64IBP-NEXT: ret 315 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b) 316 store i32 %1, i32* %x 317 ret void 318} 319 320declare i64 @llvm.fshr.i64(i64, i64, i64) 321 322define i64 @ror_i64(i64 %a, i64 %b) nounwind { 323; RV64I-LABEL: ror_i64: 324; RV64I: # %bb.0: 325; RV64I-NEXT: srl a2, a0, a1 326; RV64I-NEXT: neg a1, a1 327; RV64I-NEXT: sll a0, a0, a1 328; RV64I-NEXT: or a0, a2, a0 329; RV64I-NEXT: ret 330; 331; RV64IB-LABEL: ror_i64: 332; RV64IB: # %bb.0: 333; RV64IB-NEXT: ror a0, a0, a1 334; RV64IB-NEXT: ret 335; 336; RV64IBB-LABEL: ror_i64: 337; RV64IBB: # %bb.0: 338; RV64IBB-NEXT: ror a0, a0, a1 339; RV64IBB-NEXT: ret 340; 341; RV64IBP-LABEL: ror_i64: 342; RV64IBP: # %bb.0: 343; RV64IBP-NEXT: ror a0, a0, a1 344; RV64IBP-NEXT: ret 345 %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b) 346 ret i64 %or 347} 348 349define signext i32 @rori_i32_fshl(i32 signext %a) nounwind { 350; RV64I-LABEL: rori_i32_fshl: 351; RV64I: # %bb.0: 352; RV64I-NEXT: srliw a1, a0, 1 353; RV64I-NEXT: slli a0, a0, 31 354; RV64I-NEXT: or a0, a0, a1 355; RV64I-NEXT: sext.w a0, a0 356; RV64I-NEXT: ret 357; 358; RV64IB-LABEL: rori_i32_fshl: 359; RV64IB: # %bb.0: 360; RV64IB-NEXT: roriw a0, a0, 1 361; RV64IB-NEXT: ret 362; 363; RV64IBB-LABEL: rori_i32_fshl: 364; RV64IBB: # %bb.0: 365; RV64IBB-NEXT: roriw a0, a0, 1 366; RV64IBB-NEXT: ret 367; 368; RV64IBP-LABEL: rori_i32_fshl: 369; RV64IBP: # %bb.0: 370; RV64IBP-NEXT: roriw a0, a0, 1 371; RV64IBP-NEXT: ret 372 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31) 373 ret i32 %1 374} 375 376; Similar to rori_i32_fshl, but doesn't sign extend the result. 377define void @rori_i32_fshl_nosext(i32 signext %a, i32* %x) nounwind { 378; RV64I-LABEL: rori_i32_fshl_nosext: 379; RV64I: # %bb.0: 380; RV64I-NEXT: srliw a2, a0, 1 381; RV64I-NEXT: slli a0, a0, 31 382; RV64I-NEXT: or a0, a0, a2 383; RV64I-NEXT: sw a0, 0(a1) 384; RV64I-NEXT: ret 385; 386; RV64IB-LABEL: rori_i32_fshl_nosext: 387; RV64IB: # %bb.0: 388; RV64IB-NEXT: roriw a0, a0, 1 389; RV64IB-NEXT: sw a0, 0(a1) 390; RV64IB-NEXT: ret 391; 392; RV64IBB-LABEL: rori_i32_fshl_nosext: 393; RV64IBB: # %bb.0: 394; RV64IBB-NEXT: roriw a0, a0, 1 395; RV64IBB-NEXT: sw a0, 0(a1) 396; RV64IBB-NEXT: ret 397; 398; RV64IBP-LABEL: rori_i32_fshl_nosext: 399; RV64IBP: # %bb.0: 400; RV64IBP-NEXT: roriw a0, a0, 1 401; RV64IBP-NEXT: sw a0, 0(a1) 402; RV64IBP-NEXT: ret 403 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31) 404 store i32 %1, i32* %x 405 ret void 406} 407 408define signext i32 @rori_i32_fshr(i32 signext %a) nounwind { 409; RV64I-LABEL: rori_i32_fshr: 410; RV64I: # %bb.0: 411; RV64I-NEXT: slli a1, a0, 1 412; RV64I-NEXT: srliw a0, a0, 31 413; RV64I-NEXT: or a0, a0, a1 414; RV64I-NEXT: sext.w a0, a0 415; RV64I-NEXT: ret 416; 417; RV64IB-LABEL: rori_i32_fshr: 418; RV64IB: # %bb.0: 419; RV64IB-NEXT: roriw a0, a0, 31 420; RV64IB-NEXT: ret 421; 422; RV64IBB-LABEL: rori_i32_fshr: 423; RV64IBB: # %bb.0: 424; RV64IBB-NEXT: roriw a0, a0, 31 425; RV64IBB-NEXT: ret 426; 427; RV64IBP-LABEL: rori_i32_fshr: 428; RV64IBP: # %bb.0: 429; RV64IBP-NEXT: roriw a0, a0, 31 430; RV64IBP-NEXT: ret 431 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31) 432 ret i32 %1 433} 434 435; Similar to rori_i32_fshr, but doesn't sign extend the result. 436define void @rori_i32_fshr_nosext(i32 signext %a, i32* %x) nounwind { 437; RV64I-LABEL: rori_i32_fshr_nosext: 438; RV64I: # %bb.0: 439; RV64I-NEXT: slli a2, a0, 1 440; RV64I-NEXT: srliw a0, a0, 31 441; RV64I-NEXT: or a0, a0, a2 442; RV64I-NEXT: sw a0, 0(a1) 443; RV64I-NEXT: ret 444; 445; RV64IB-LABEL: rori_i32_fshr_nosext: 446; RV64IB: # %bb.0: 447; RV64IB-NEXT: roriw a0, a0, 31 448; RV64IB-NEXT: sw a0, 0(a1) 449; RV64IB-NEXT: ret 450; 451; RV64IBB-LABEL: rori_i32_fshr_nosext: 452; RV64IBB: # %bb.0: 453; RV64IBB-NEXT: roriw a0, a0, 31 454; RV64IBB-NEXT: sw a0, 0(a1) 455; RV64IBB-NEXT: ret 456; 457; RV64IBP-LABEL: rori_i32_fshr_nosext: 458; RV64IBP: # %bb.0: 459; RV64IBP-NEXT: roriw a0, a0, 31 460; RV64IBP-NEXT: sw a0, 0(a1) 461; RV64IBP-NEXT: ret 462 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31) 463 store i32 %1, i32* %x 464 ret void 465} 466 467; This test is similar to the type legalized version of the fshl/fshr tests, but 468; instead of having the same input to both shifts it has different inputs. Make 469; sure we don't match it as a roriw. 470define signext i32 @not_rori_i32(i32 signext %x, i32 signext %y) nounwind { 471; RV64I-LABEL: not_rori_i32: 472; RV64I: # %bb.0: 473; RV64I-NEXT: slli a0, a0, 31 474; RV64I-NEXT: srliw a1, a1, 1 475; RV64I-NEXT: or a0, a0, a1 476; RV64I-NEXT: sext.w a0, a0 477; RV64I-NEXT: ret 478; 479; RV64IB-LABEL: not_rori_i32: 480; RV64IB: # %bb.0: 481; RV64IB-NEXT: slli a0, a0, 31 482; RV64IB-NEXT: srliw a1, a1, 1 483; RV64IB-NEXT: or a0, a0, a1 484; RV64IB-NEXT: sext.w a0, a0 485; RV64IB-NEXT: ret 486; 487; RV64IBB-LABEL: not_rori_i32: 488; RV64IBB: # %bb.0: 489; RV64IBB-NEXT: slli a0, a0, 31 490; RV64IBB-NEXT: srliw a1, a1, 1 491; RV64IBB-NEXT: or a0, a0, a1 492; RV64IBB-NEXT: sext.w a0, a0 493; RV64IBB-NEXT: ret 494; 495; RV64IBP-LABEL: not_rori_i32: 496; RV64IBP: # %bb.0: 497; RV64IBP-NEXT: slli a0, a0, 31 498; RV64IBP-NEXT: srliw a1, a1, 1 499; RV64IBP-NEXT: or a0, a0, a1 500; RV64IBP-NEXT: sext.w a0, a0 501; RV64IBP-NEXT: ret 502 %a = shl i32 %x, 31 503 %b = lshr i32 %y, 1 504 %c = or i32 %a, %b 505 ret i32 %c 506} 507 508; This is similar to the type legalized roriw pattern, but the and mask is more 509; than 32 bits so the lshr doesn't shift zeroes into the lower 32 bits. Make 510; sure we don't match it to roriw. 511define i64 @roriw_bug(i64 %x) nounwind { 512; RV64I-LABEL: roriw_bug: 513; RV64I: # %bb.0: 514; RV64I-NEXT: slli a1, a0, 31 515; RV64I-NEXT: andi a0, a0, -2 516; RV64I-NEXT: srli a2, a0, 1 517; RV64I-NEXT: or a1, a1, a2 518; RV64I-NEXT: sext.w a1, a1 519; RV64I-NEXT: xor a0, a0, a1 520; RV64I-NEXT: ret 521; 522; RV64IB-LABEL: roriw_bug: 523; RV64IB: # %bb.0: 524; RV64IB-NEXT: slli a1, a0, 31 525; RV64IB-NEXT: andi a0, a0, -2 526; RV64IB-NEXT: srli a2, a0, 1 527; RV64IB-NEXT: or a1, a1, a2 528; RV64IB-NEXT: sext.w a1, a1 529; RV64IB-NEXT: xor a0, a0, a1 530; RV64IB-NEXT: ret 531; 532; RV64IBB-LABEL: roriw_bug: 533; RV64IBB: # %bb.0: 534; RV64IBB-NEXT: slli a1, a0, 31 535; RV64IBB-NEXT: andi a0, a0, -2 536; RV64IBB-NEXT: srli a2, a0, 1 537; RV64IBB-NEXT: or a1, a1, a2 538; RV64IBB-NEXT: sext.w a1, a1 539; RV64IBB-NEXT: xor a0, a0, a1 540; RV64IBB-NEXT: ret 541; 542; RV64IBP-LABEL: roriw_bug: 543; RV64IBP: # %bb.0: 544; RV64IBP-NEXT: slli a1, a0, 31 545; RV64IBP-NEXT: andi a0, a0, -2 546; RV64IBP-NEXT: srli a2, a0, 1 547; RV64IBP-NEXT: or a1, a1, a2 548; RV64IBP-NEXT: sext.w a1, a1 549; RV64IBP-NEXT: xor a0, a0, a1 550; RV64IBP-NEXT: ret 551 %a = shl i64 %x, 31 552 %b = and i64 %x, 18446744073709551614 553 %c = lshr i64 %b, 1 554 %d = or i64 %a, %c 555 %e = shl i64 %d, 32 556 %f = ashr i64 %e, 32 557 %g = xor i64 %b, %f ; to increase the use count on %b to disable SimplifyDemandedBits. 558 ret i64 %g 559} 560 561define i64 @rori_i64_fshl(i64 %a) nounwind { 562; RV64I-LABEL: rori_i64_fshl: 563; RV64I: # %bb.0: 564; RV64I-NEXT: srli a1, a0, 1 565; RV64I-NEXT: slli a0, a0, 63 566; RV64I-NEXT: or a0, a0, a1 567; RV64I-NEXT: ret 568; 569; RV64IB-LABEL: rori_i64_fshl: 570; RV64IB: # %bb.0: 571; RV64IB-NEXT: rori a0, a0, 1 572; RV64IB-NEXT: ret 573; 574; RV64IBB-LABEL: rori_i64_fshl: 575; RV64IBB: # %bb.0: 576; RV64IBB-NEXT: rori a0, a0, 1 577; RV64IBB-NEXT: ret 578; 579; RV64IBP-LABEL: rori_i64_fshl: 580; RV64IBP: # %bb.0: 581; RV64IBP-NEXT: rori a0, a0, 1 582; RV64IBP-NEXT: ret 583 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63) 584 ret i64 %1 585} 586 587define i64 @rori_i64_fshr(i64 %a) nounwind { 588; RV64I-LABEL: rori_i64_fshr: 589; RV64I: # %bb.0: 590; RV64I-NEXT: slli a1, a0, 1 591; RV64I-NEXT: srli a0, a0, 63 592; RV64I-NEXT: or a0, a0, a1 593; RV64I-NEXT: ret 594; 595; RV64IB-LABEL: rori_i64_fshr: 596; RV64IB: # %bb.0: 597; RV64IB-NEXT: rori a0, a0, 63 598; RV64IB-NEXT: ret 599; 600; RV64IBB-LABEL: rori_i64_fshr: 601; RV64IBB: # %bb.0: 602; RV64IBB-NEXT: rori a0, a0, 63 603; RV64IBB-NEXT: ret 604; 605; RV64IBP-LABEL: rori_i64_fshr: 606; RV64IBP: # %bb.0: 607; RV64IBP-NEXT: rori a0, a0, 63 608; RV64IBP-NEXT: ret 609 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63) 610 ret i64 %1 611} 612 613define signext i32 @pack_i32(i32 signext %a, i32 signext %b) nounwind { 614; RV64I-LABEL: pack_i32: 615; RV64I: # %bb.0: 616; RV64I-NEXT: lui a2, 16 617; RV64I-NEXT: addiw a2, a2, -1 618; RV64I-NEXT: and a0, a0, a2 619; RV64I-NEXT: slli a1, a1, 16 620; RV64I-NEXT: or a0, a1, a0 621; RV64I-NEXT: sext.w a0, a0 622; RV64I-NEXT: ret 623; 624; RV64IB-LABEL: pack_i32: 625; RV64IB: # %bb.0: 626; RV64IB-NEXT: packw a0, a0, a1 627; RV64IB-NEXT: ret 628; 629; RV64IBB-LABEL: pack_i32: 630; RV64IBB: # %bb.0: 631; RV64IBB-NEXT: packw a0, a0, a1 632; RV64IBB-NEXT: ret 633; 634; RV64IBP-LABEL: pack_i32: 635; RV64IBP: # %bb.0: 636; RV64IBP-NEXT: packw a0, a0, a1 637; RV64IBP-NEXT: ret 638 %shl = and i32 %a, 65535 639 %shl1 = shl i32 %b, 16 640 %or = or i32 %shl1, %shl 641 ret i32 %or 642} 643 644define i64 @pack_i64(i64 %a, i64 %b) nounwind { 645; RV64I-LABEL: pack_i64: 646; RV64I: # %bb.0: 647; RV64I-NEXT: slli a0, a0, 32 648; RV64I-NEXT: srli a0, a0, 32 649; RV64I-NEXT: slli a1, a1, 32 650; RV64I-NEXT: or a0, a1, a0 651; RV64I-NEXT: ret 652; 653; RV64IB-LABEL: pack_i64: 654; RV64IB: # %bb.0: 655; RV64IB-NEXT: pack a0, a0, a1 656; RV64IB-NEXT: ret 657; 658; RV64IBB-LABEL: pack_i64: 659; RV64IBB: # %bb.0: 660; RV64IBB-NEXT: pack a0, a0, a1 661; RV64IBB-NEXT: ret 662; 663; RV64IBP-LABEL: pack_i64: 664; RV64IBP: # %bb.0: 665; RV64IBP-NEXT: pack a0, a0, a1 666; RV64IBP-NEXT: ret 667 %shl = and i64 %a, 4294967295 668 %shl1 = shl i64 %b, 32 669 %or = or i64 %shl1, %shl 670 ret i64 %or 671} 672 673define signext i32 @packu_i32(i32 signext %a, i32 signext %b) nounwind { 674; RV64I-LABEL: packu_i32: 675; RV64I: # %bb.0: 676; RV64I-NEXT: srliw a0, a0, 16 677; RV64I-NEXT: lui a2, 1048560 678; RV64I-NEXT: and a1, a1, a2 679; RV64I-NEXT: or a0, a1, a0 680; RV64I-NEXT: ret 681; 682; RV64IB-LABEL: packu_i32: 683; RV64IB: # %bb.0: 684; RV64IB-NEXT: packuw a0, a0, a1 685; RV64IB-NEXT: ret 686; 687; RV64IBB-LABEL: packu_i32: 688; RV64IBB: # %bb.0: 689; RV64IBB-NEXT: packuw a0, a0, a1 690; RV64IBB-NEXT: ret 691; 692; RV64IBP-LABEL: packu_i32: 693; RV64IBP: # %bb.0: 694; RV64IBP-NEXT: packuw a0, a0, a1 695; RV64IBP-NEXT: ret 696 %shr = lshr i32 %a, 16 697 %shr1 = and i32 %b, -65536 698 %or = or i32 %shr1, %shr 699 ret i32 %or 700} 701 702define i64 @packu_i64(i64 %a, i64 %b) nounwind { 703; RV64I-LABEL: packu_i64: 704; RV64I: # %bb.0: 705; RV64I-NEXT: srli a0, a0, 32 706; RV64I-NEXT: addi a2, zero, -1 707; RV64I-NEXT: slli a2, a2, 32 708; RV64I-NEXT: and a1, a1, a2 709; RV64I-NEXT: or a0, a1, a0 710; RV64I-NEXT: ret 711; 712; RV64IB-LABEL: packu_i64: 713; RV64IB: # %bb.0: 714; RV64IB-NEXT: packu a0, a0, a1 715; RV64IB-NEXT: ret 716; 717; RV64IBB-LABEL: packu_i64: 718; RV64IBB: # %bb.0: 719; RV64IBB-NEXT: packu a0, a0, a1 720; RV64IBB-NEXT: ret 721; 722; RV64IBP-LABEL: packu_i64: 723; RV64IBP: # %bb.0: 724; RV64IBP-NEXT: packu a0, a0, a1 725; RV64IBP-NEXT: ret 726 %shr = lshr i64 %a, 32 727 %shr1 = and i64 %b, -4294967296 728 %or = or i64 %shr1, %shr 729 ret i64 %or 730} 731 732define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind { 733; RV64I-LABEL: packh_i32: 734; RV64I: # %bb.0: 735; RV64I-NEXT: andi a0, a0, 255 736; RV64I-NEXT: slli a1, a1, 8 737; RV64I-NEXT: lui a2, 16 738; RV64I-NEXT: addiw a2, a2, -256 739; RV64I-NEXT: and a1, a1, a2 740; RV64I-NEXT: or a0, a1, a0 741; RV64I-NEXT: ret 742; 743; RV64IB-LABEL: packh_i32: 744; RV64IB: # %bb.0: 745; RV64IB-NEXT: packh a0, a0, a1 746; RV64IB-NEXT: ret 747; 748; RV64IBB-LABEL: packh_i32: 749; RV64IBB: # %bb.0: 750; RV64IBB-NEXT: packh a0, a0, a1 751; RV64IBB-NEXT: ret 752; 753; RV64IBP-LABEL: packh_i32: 754; RV64IBP: # %bb.0: 755; RV64IBP-NEXT: packh a0, a0, a1 756; RV64IBP-NEXT: ret 757 %and = and i32 %a, 255 758 %and1 = shl i32 %b, 8 759 %shl = and i32 %and1, 65280 760 %or = or i32 %shl, %and 761 ret i32 %or 762} 763 764define i64 @packh_i64(i64 %a, i64 %b) nounwind { 765; RV64I-LABEL: packh_i64: 766; RV64I: # %bb.0: 767; RV64I-NEXT: andi a0, a0, 255 768; RV64I-NEXT: slli a1, a1, 8 769; RV64I-NEXT: lui a2, 16 770; RV64I-NEXT: addiw a2, a2, -256 771; RV64I-NEXT: and a1, a1, a2 772; RV64I-NEXT: or a0, a1, a0 773; RV64I-NEXT: ret 774; 775; RV64IB-LABEL: packh_i64: 776; RV64IB: # %bb.0: 777; RV64IB-NEXT: packh a0, a0, a1 778; RV64IB-NEXT: ret 779; 780; RV64IBB-LABEL: packh_i64: 781; RV64IBB: # %bb.0: 782; RV64IBB-NEXT: packh a0, a0, a1 783; RV64IBB-NEXT: ret 784; 785; RV64IBP-LABEL: packh_i64: 786; RV64IBP: # %bb.0: 787; RV64IBP-NEXT: packh a0, a0, a1 788; RV64IBP-NEXT: ret 789 %and = and i64 %a, 255 790 %and1 = shl i64 %b, 8 791 %shl = and i64 %and1, 65280 792 %or = or i64 %shl, %and 793 ret i64 %or 794} 795 796define i64 @zextw_i64(i64 %a) nounwind { 797; RV64I-LABEL: zextw_i64: 798; RV64I: # %bb.0: 799; RV64I-NEXT: slli a0, a0, 32 800; RV64I-NEXT: srli a0, a0, 32 801; RV64I-NEXT: ret 802; 803; RV64IB-LABEL: zextw_i64: 804; RV64IB: # %bb.0: 805; RV64IB-NEXT: zext.w a0, a0 806; RV64IB-NEXT: ret 807; 808; RV64IBB-LABEL: zextw_i64: 809; RV64IBB: # %bb.0: 810; RV64IBB-NEXT: zext.w a0, a0 811; RV64IBB-NEXT: ret 812; 813; RV64IBP-LABEL: zextw_i64: 814; RV64IBP: # %bb.0: 815; RV64IBP-NEXT: pack a0, a0, zero 816; RV64IBP-NEXT: ret 817 %and = and i64 %a, 4294967295 818 ret i64 %and 819} 820