1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I 4; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBKB 6; RUN: llc -mtriple=riscv32 -mattr=+zbkb -verify-machineinstrs < %s \ 7; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBKB 8 9define i32 @andn_i32(i32 %a, i32 %b) nounwind { 10; RV32I-LABEL: andn_i32: 11; RV32I: # %bb.0: 12; RV32I-NEXT: not a1, a1 13; RV32I-NEXT: and a0, a1, a0 14; RV32I-NEXT: ret 15; 16; RV32ZBB-ZBKB-LABEL: andn_i32: 17; RV32ZBB-ZBKB: # %bb.0: 18; RV32ZBB-ZBKB-NEXT: andn a0, a0, a1 19; RV32ZBB-ZBKB-NEXT: ret 20 %neg = xor i32 %b, -1 21 %and = and i32 %neg, %a 22 ret i32 %and 23} 24 25define i64 @andn_i64(i64 %a, i64 %b) nounwind { 26; RV32I-LABEL: andn_i64: 27; RV32I: # %bb.0: 28; RV32I-NEXT: not a3, a3 29; RV32I-NEXT: not a2, a2 30; RV32I-NEXT: and a0, a2, a0 31; RV32I-NEXT: and a1, a3, a1 32; RV32I-NEXT: ret 33; 34; RV32ZBB-ZBKB-LABEL: andn_i64: 35; RV32ZBB-ZBKB: # %bb.0: 36; RV32ZBB-ZBKB-NEXT: andn a0, a0, a2 37; RV32ZBB-ZBKB-NEXT: andn a1, a1, a3 38; RV32ZBB-ZBKB-NEXT: ret 39 %neg = xor i64 %b, -1 40 %and = and i64 %neg, %a 41 ret i64 %and 42} 43 44define i32 @orn_i32(i32 %a, i32 %b) nounwind { 45; RV32I-LABEL: orn_i32: 46; RV32I: # %bb.0: 47; RV32I-NEXT: not a1, a1 48; RV32I-NEXT: or a0, a1, a0 49; RV32I-NEXT: ret 50; 51; RV32ZBB-ZBKB-LABEL: orn_i32: 52; RV32ZBB-ZBKB: # %bb.0: 53; RV32ZBB-ZBKB-NEXT: orn a0, a0, a1 54; RV32ZBB-ZBKB-NEXT: ret 55 %neg = xor i32 %b, -1 56 %or = or i32 %neg, %a 57 ret i32 %or 58} 59 60define i64 @orn_i64(i64 %a, i64 %b) nounwind { 61; RV32I-LABEL: orn_i64: 62; RV32I: # %bb.0: 63; RV32I-NEXT: not a3, a3 64; RV32I-NEXT: not a2, a2 65; RV32I-NEXT: or a0, a2, a0 66; RV32I-NEXT: or a1, a3, a1 67; RV32I-NEXT: ret 68; 69; RV32ZBB-ZBKB-LABEL: orn_i64: 70; RV32ZBB-ZBKB: # %bb.0: 71; RV32ZBB-ZBKB-NEXT: orn a0, a0, a2 72; RV32ZBB-ZBKB-NEXT: orn a1, a1, a3 73; RV32ZBB-ZBKB-NEXT: ret 74 %neg = xor i64 %b, -1 75 %or = or i64 %neg, %a 76 ret i64 %or 77} 78 79define i32 @xnor_i32(i32 %a, i32 %b) nounwind { 80; RV32I-LABEL: xnor_i32: 81; RV32I: # %bb.0: 82; RV32I-NEXT: xor a0, a0, a1 83; RV32I-NEXT: not a0, a0 84; RV32I-NEXT: ret 85; 86; RV32ZBB-ZBKB-LABEL: xnor_i32: 87; RV32ZBB-ZBKB: # %bb.0: 88; RV32ZBB-ZBKB-NEXT: xnor a0, a0, a1 89; RV32ZBB-ZBKB-NEXT: ret 90 %neg = xor i32 %a, -1 91 %xor = xor i32 %neg, %b 92 ret i32 %xor 93} 94 95define i64 @xnor_i64(i64 %a, i64 %b) nounwind { 96; RV32I-LABEL: xnor_i64: 97; RV32I: # %bb.0: 98; RV32I-NEXT: xor a1, a1, a3 99; RV32I-NEXT: xor a0, a0, a2 100; RV32I-NEXT: not a0, a0 101; RV32I-NEXT: not a1, a1 102; RV32I-NEXT: ret 103; 104; RV32ZBB-ZBKB-LABEL: xnor_i64: 105; RV32ZBB-ZBKB: # %bb.0: 106; RV32ZBB-ZBKB-NEXT: xnor a0, a0, a2 107; RV32ZBB-ZBKB-NEXT: xnor a1, a1, a3 108; RV32ZBB-ZBKB-NEXT: ret 109 %neg = xor i64 %a, -1 110 %xor = xor i64 %neg, %b 111 ret i64 %xor 112} 113 114declare i32 @llvm.fshl.i32(i32, i32, i32) 115 116define i32 @rol_i32(i32 %a, i32 %b) nounwind { 117; RV32I-LABEL: rol_i32: 118; RV32I: # %bb.0: 119; RV32I-NEXT: sll a2, a0, a1 120; RV32I-NEXT: neg a1, a1 121; RV32I-NEXT: srl a0, a0, a1 122; RV32I-NEXT: or a0, a2, a0 123; RV32I-NEXT: ret 124; 125; RV32ZBB-ZBKB-LABEL: rol_i32: 126; RV32ZBB-ZBKB: # %bb.0: 127; RV32ZBB-ZBKB-NEXT: rol a0, a0, a1 128; RV32ZBB-ZBKB-NEXT: ret 129 %or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b) 130 ret i32 %or 131} 132 133; This test is presented here in case future expansions of the Bitmanip 134; extensions introduce instructions suitable for this pattern. 135 136declare i64 @llvm.fshl.i64(i64, i64, i64) 137 138define i64 @rol_i64(i64 %a, i64 %b) nounwind { 139; CHECK-LABEL: rol_i64: 140; CHECK: # %bb.0: 141; CHECK-NEXT: slli a5, a2, 26 142; CHECK-NEXT: srli a5, a5, 31 143; CHECK-NEXT: mv a3, a1 144; CHECK-NEXT: bnez a5, .LBB7_2 145; CHECK-NEXT: # %bb.1: 146; CHECK-NEXT: mv a3, a0 147; CHECK-NEXT: .LBB7_2: 148; CHECK-NEXT: sll a4, a3, a2 149; CHECK-NEXT: bnez a5, .LBB7_4 150; CHECK-NEXT: # %bb.3: 151; CHECK-NEXT: mv a0, a1 152; CHECK-NEXT: .LBB7_4: 153; CHECK-NEXT: srli a1, a0, 1 154; CHECK-NEXT: not a5, a2 155; CHECK-NEXT: sll a2, a0, a2 156; CHECK-NEXT: srli a3, a3, 1 157; CHECK-NEXT: srl a0, a1, a5 158; CHECK-NEXT: srl a1, a3, a5 159; CHECK-NEXT: or a0, a4, a0 160; CHECK-NEXT: or a1, a2, a1 161; CHECK-NEXT: ret 162 %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b) 163 ret i64 %or 164} 165 166declare i32 @llvm.fshr.i32(i32, i32, i32) 167 168define i32 @ror_i32(i32 %a, i32 %b) nounwind { 169; RV32I-LABEL: ror_i32: 170; RV32I: # %bb.0: 171; RV32I-NEXT: srl a2, a0, a1 172; RV32I-NEXT: neg a1, a1 173; RV32I-NEXT: sll a0, a0, a1 174; RV32I-NEXT: or a0, a2, a0 175; RV32I-NEXT: ret 176; 177; RV32ZBB-ZBKB-LABEL: ror_i32: 178; RV32ZBB-ZBKB: # %bb.0: 179; RV32ZBB-ZBKB-NEXT: ror a0, a0, a1 180; RV32ZBB-ZBKB-NEXT: ret 181 %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b) 182 ret i32 %or 183} 184 185; This test is presented here in case future expansions of the Bitmanip 186; extensions introduce instructions suitable for this pattern. 187 188declare i64 @llvm.fshr.i64(i64, i64, i64) 189 190define i64 @ror_i64(i64 %a, i64 %b) nounwind { 191; CHECK-LABEL: ror_i64: 192; CHECK: # %bb.0: 193; CHECK-NEXT: andi a5, a2, 32 194; CHECK-NEXT: mv a3, a0 195; CHECK-NEXT: beqz a5, .LBB9_2 196; CHECK-NEXT: # %bb.1: 197; CHECK-NEXT: mv a3, a1 198; CHECK-NEXT: .LBB9_2: 199; CHECK-NEXT: srl a4, a3, a2 200; CHECK-NEXT: beqz a5, .LBB9_4 201; CHECK-NEXT: # %bb.3: 202; CHECK-NEXT: mv a1, a0 203; CHECK-NEXT: .LBB9_4: 204; CHECK-NEXT: slli a0, a1, 1 205; CHECK-NEXT: not a5, a2 206; CHECK-NEXT: srl a1, a1, a2 207; CHECK-NEXT: slli a3, a3, 1 208; CHECK-NEXT: sll a0, a0, a5 209; CHECK-NEXT: sll a2, a3, a5 210; CHECK-NEXT: or a0, a0, a4 211; CHECK-NEXT: or a1, a2, a1 212; CHECK-NEXT: ret 213 %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b) 214 ret i64 %or 215} 216 217define i32 @rori_i32_fshl(i32 %a) nounwind { 218; RV32I-LABEL: rori_i32_fshl: 219; RV32I: # %bb.0: 220; RV32I-NEXT: srli a1, a0, 1 221; RV32I-NEXT: slli a0, a0, 31 222; RV32I-NEXT: or a0, a0, a1 223; RV32I-NEXT: ret 224; 225; RV32ZBB-ZBKB-LABEL: rori_i32_fshl: 226; RV32ZBB-ZBKB: # %bb.0: 227; RV32ZBB-ZBKB-NEXT: rori a0, a0, 1 228; RV32ZBB-ZBKB-NEXT: ret 229 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31) 230 ret i32 %1 231} 232 233define i32 @rori_i32_fshr(i32 %a) nounwind { 234; RV32I-LABEL: rori_i32_fshr: 235; RV32I: # %bb.0: 236; RV32I-NEXT: slli a1, a0, 1 237; RV32I-NEXT: srli a0, a0, 31 238; RV32I-NEXT: or a0, a0, a1 239; RV32I-NEXT: ret 240; 241; RV32ZBB-ZBKB-LABEL: rori_i32_fshr: 242; RV32ZBB-ZBKB: # %bb.0: 243; RV32ZBB-ZBKB-NEXT: rori a0, a0, 31 244; RV32ZBB-ZBKB-NEXT: ret 245 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31) 246 ret i32 %1 247} 248 249define i64 @rori_i64(i64 %a) nounwind { 250; CHECK-LABEL: rori_i64: 251; CHECK: # %bb.0: 252; CHECK-NEXT: srli a2, a0, 1 253; CHECK-NEXT: slli a3, a1, 31 254; CHECK-NEXT: srli a1, a1, 1 255; CHECK-NEXT: slli a4, a0, 31 256; CHECK-NEXT: or a0, a3, a2 257; CHECK-NEXT: or a1, a4, a1 258; CHECK-NEXT: ret 259 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63) 260 ret i64 %1 261} 262 263define i64 @rori_i64_fshr(i64 %a) nounwind { 264; CHECK-LABEL: rori_i64_fshr: 265; CHECK: # %bb.0: 266; CHECK-NEXT: srli a2, a1, 31 267; CHECK-NEXT: slli a3, a0, 1 268; CHECK-NEXT: srli a4, a0, 31 269; CHECK-NEXT: slli a1, a1, 1 270; CHECK-NEXT: or a0, a3, a2 271; CHECK-NEXT: or a1, a1, a4 272; CHECK-NEXT: ret 273 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63) 274 ret i64 %1 275} 276 277define i32 @not_shl_one_i32(i32 %x) { 278; RV32I-LABEL: not_shl_one_i32: 279; RV32I: # %bb.0: 280; RV32I-NEXT: li a1, 1 281; RV32I-NEXT: sll a0, a1, a0 282; RV32I-NEXT: not a0, a0 283; RV32I-NEXT: ret 284; 285; RV32ZBB-ZBKB-LABEL: not_shl_one_i32: 286; RV32ZBB-ZBKB: # %bb.0: 287; RV32ZBB-ZBKB-NEXT: li a1, -2 288; RV32ZBB-ZBKB-NEXT: rol a0, a1, a0 289; RV32ZBB-ZBKB-NEXT: ret 290 %1 = shl i32 1, %x 291 %2 = xor i32 %1, -1 292 ret i32 %2 293} 294 295define i64 @not_shl_one_i64(i64 %x) { 296; CHECK-LABEL: not_shl_one_i64: 297; CHECK: # %bb.0: 298; CHECK-NEXT: addi a1, a0, -32 299; CHECK-NEXT: li a2, 1 300; CHECK-NEXT: slti a1, a1, 0 301; CHECK-NEXT: sll a0, a2, a0 302; CHECK-NEXT: neg a2, a1 303; CHECK-NEXT: addi a1, a1, -1 304; CHECK-NEXT: and a2, a2, a0 305; CHECK-NEXT: and a1, a1, a0 306; CHECK-NEXT: not a0, a2 307; CHECK-NEXT: not a1, a1 308; CHECK-NEXT: ret 309 %1 = shl i64 1, %x 310 %2 = xor i64 %1, -1 311 ret i64 %2 312} 313 314define i8 @srli_i8(i8 %a) nounwind { 315; CHECK-LABEL: srli_i8: 316; CHECK: # %bb.0: 317; CHECK-NEXT: slli a0, a0, 24 318; CHECK-NEXT: srli a0, a0, 30 319; CHECK-NEXT: ret 320 %1 = lshr i8 %a, 6 321 ret i8 %1 322} 323 324; We could use sext.b+srai, but slli+srai offers more opportunities for 325; comppressed instructions. 326define i8 @srai_i8(i8 %a) nounwind { 327; CHECK-LABEL: srai_i8: 328; CHECK: # %bb.0: 329; CHECK-NEXT: slli a0, a0, 24 330; CHECK-NEXT: srai a0, a0, 29 331; CHECK-NEXT: ret 332 %1 = ashr i8 %a, 5 333 ret i8 %1 334} 335 336; We could use zext.h+srli, but slli+srli offers more opportunities for 337; comppressed instructions. 338define i16 @srli_i16(i16 %a) nounwind { 339; CHECK-LABEL: srli_i16: 340; CHECK: # %bb.0: 341; CHECK-NEXT: slli a0, a0, 16 342; CHECK-NEXT: srli a0, a0, 22 343; CHECK-NEXT: ret 344 %1 = lshr i16 %a, 6 345 ret i16 %1 346} 347 348; We could use sext.h+srai, but slli+srai offers more opportunities for 349; comppressed instructions. 350define i16 @srai_i16(i16 %a) nounwind { 351; CHECK-LABEL: srai_i16: 352; CHECK: # %bb.0: 353; CHECK-NEXT: slli a0, a0, 16 354; CHECK-NEXT: srai a0, a0, 25 355; CHECK-NEXT: ret 356 %1 = ashr i16 %a, 9 357 ret i16 %1 358} 359 360define i1 @andn_seqz_i32(i32 %a, i32 %b) nounwind { 361; RV32I-LABEL: andn_seqz_i32: 362; RV32I: # %bb.0: 363; RV32I-NEXT: and a0, a0, a1 364; RV32I-NEXT: xor a0, a0, a1 365; RV32I-NEXT: seqz a0, a0 366; RV32I-NEXT: ret 367; 368; RV32ZBB-ZBKB-LABEL: andn_seqz_i32: 369; RV32ZBB-ZBKB: # %bb.0: 370; RV32ZBB-ZBKB-NEXT: andn a0, a1, a0 371; RV32ZBB-ZBKB-NEXT: seqz a0, a0 372; RV32ZBB-ZBKB-NEXT: ret 373 %and = and i32 %a, %b 374 %cmpeq = icmp eq i32 %and, %b 375 ret i1 %cmpeq 376} 377 378define i1 @andn_seqz_i64(i64 %a, i64 %b) nounwind { 379; RV32I-LABEL: andn_seqz_i64: 380; RV32I: # %bb.0: 381; RV32I-NEXT: not a0, a0 382; RV32I-NEXT: not a1, a1 383; RV32I-NEXT: and a1, a1, a3 384; RV32I-NEXT: and a0, a0, a2 385; RV32I-NEXT: or a0, a0, a1 386; RV32I-NEXT: seqz a0, a0 387; RV32I-NEXT: ret 388; 389; RV32ZBB-ZBKB-LABEL: andn_seqz_i64: 390; RV32ZBB-ZBKB: # %bb.0: 391; RV32ZBB-ZBKB-NEXT: andn a1, a3, a1 392; RV32ZBB-ZBKB-NEXT: andn a0, a2, a0 393; RV32ZBB-ZBKB-NEXT: or a0, a0, a1 394; RV32ZBB-ZBKB-NEXT: seqz a0, a0 395; RV32ZBB-ZBKB-NEXT: ret 396 %and = and i64 %a, %b 397 %cmpeq = icmp eq i64 %and, %b 398 ret i1 %cmpeq 399} 400 401define i1 @andn_snez_i32(i32 %a, i32 %b) nounwind { 402; RV32I-LABEL: andn_snez_i32: 403; RV32I: # %bb.0: 404; RV32I-NEXT: and a0, a0, a1 405; RV32I-NEXT: xor a0, a0, a1 406; RV32I-NEXT: snez a0, a0 407; RV32I-NEXT: ret 408; 409; RV32ZBB-ZBKB-LABEL: andn_snez_i32: 410; RV32ZBB-ZBKB: # %bb.0: 411; RV32ZBB-ZBKB-NEXT: andn a0, a1, a0 412; RV32ZBB-ZBKB-NEXT: snez a0, a0 413; RV32ZBB-ZBKB-NEXT: ret 414 %and = and i32 %a, %b 415 %cmpeq = icmp ne i32 %and, %b 416 ret i1 %cmpeq 417} 418 419define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind { 420; RV32I-LABEL: andn_snez_i64: 421; RV32I: # %bb.0: 422; RV32I-NEXT: not a0, a0 423; RV32I-NEXT: not a1, a1 424; RV32I-NEXT: and a1, a1, a3 425; RV32I-NEXT: and a0, a0, a2 426; RV32I-NEXT: or a0, a0, a1 427; RV32I-NEXT: snez a0, a0 428; RV32I-NEXT: ret 429; 430; RV32ZBB-ZBKB-LABEL: andn_snez_i64: 431; RV32ZBB-ZBKB: # %bb.0: 432; RV32ZBB-ZBKB-NEXT: andn a1, a3, a1 433; RV32ZBB-ZBKB-NEXT: andn a0, a2, a0 434; RV32ZBB-ZBKB-NEXT: or a0, a0, a1 435; RV32ZBB-ZBKB-NEXT: snez a0, a0 436; RV32ZBB-ZBKB-NEXT: ret 437 %and = and i64 %a, %b 438 %cmpeq = icmp ne i64 %and, %b 439 ret i1 %cmpeq 440} 441