1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s 3 4define i8 @or_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) { 5; CHECK-LABEL: or_lshr_commute0: 6; CHECK: // %bb.0: 7; CHECK-NEXT: orr w8, w0, w1 8; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2 9; CHECK-NEXT: and w8, w8, #0xff 10; CHECK-NEXT: lsr w8, w8, w2 11; CHECK-NEXT: orr w0, w8, w3 12; CHECK-NEXT: ret 13 %sh1 = lshr i8 %x0, %y 14 %sh2 = lshr i8 %x1, %y 15 %logic = or i8 %sh1, %z 16 %r = or i8 %logic, %sh2 17 ret i8 %r 18} 19 20define i32 @or_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) { 21; CHECK-LABEL: or_lshr_commute1: 22; CHECK: // %bb.0: 23; CHECK-NEXT: orr w8, w0, w1 24; CHECK-NEXT: lsr w8, w8, w2 25; CHECK-NEXT: orr w0, w8, w3 26; CHECK-NEXT: ret 27 %sh1 = lshr i32 %x0, %y 28 %sh2 = lshr i32 %x1, %y 29 %logic = or i32 %z, %sh1 30 %r = or i32 %logic, %sh2 31 ret i32 %r 32} 33 34define <8 x i16> @or_lshr_commute2(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) { 35; CHECK-LABEL: or_lshr_commute2: 36; CHECK: // %bb.0: 37; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b 38; CHECK-NEXT: neg v1.8h, v2.8h 39; CHECK-NEXT: ushl v0.8h, v0.8h, v1.8h 40; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b 41; CHECK-NEXT: ret 42 %sh1 = lshr <8 x i16> %x0, %y 43 %sh2 = lshr <8 x i16> %x1, %y 44 %logic = or <8 x i16> %sh1, %z 45 %r = or <8 x i16> %sh2, %logic 46 ret <8 x i16> %r 47} 48 49define <2 x i64> @or_lshr_commute3(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) { 50; CHECK-LABEL: or_lshr_commute3: 51; CHECK: // %bb.0: 52; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b 53; CHECK-NEXT: neg v1.2d, v2.2d 54; CHECK-NEXT: ushl v0.2d, v0.2d, v1.2d 55; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b 56; CHECK-NEXT: ret 57 %sh1 = lshr <2 x i64> %x0, %y 58 %sh2 = lshr <2 x i64> %x1, %y 59 %logic = or <2 x i64> %z, %sh1 60 %r = or <2 x i64> %sh2, %logic 61 ret <2 x i64> %r 62} 63 64define i16 @or_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) { 65; CHECK-LABEL: or_ashr_commute0: 66; CHECK: // %bb.0: 67; CHECK-NEXT: orr w8, w0, w1 68; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2 69; CHECK-NEXT: sxth w8, w8 70; CHECK-NEXT: asr w8, w8, w2 71; CHECK-NEXT: orr w0, w8, w3 72; CHECK-NEXT: ret 73 %sh1 = ashr i16 %x0, %y 74 %sh2 = ashr i16 %x1, %y 75 %logic = or i16 %sh1, %z 76 %r = or i16 %logic, %sh2 77 ret i16 %r 78} 79 80define i64 @or_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) { 81; CHECK-LABEL: or_ashr_commute1: 82; CHECK: // %bb.0: 83; CHECK-NEXT: orr x8, x0, x1 84; CHECK-NEXT: asr x8, x8, x2 85; CHECK-NEXT: orr x0, x8, x3 86; CHECK-NEXT: ret 87 %sh1 = ashr i64 %x0, %y 88 %sh2 = ashr i64 %x1, %y 89 %logic = or i64 %z, %sh1 90 %r = or i64 %logic, %sh2 91 ret i64 %r 92} 93 94define <4 x i32> @or_ashr_commute2(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y, <4 x i32> %z) { 95; CHECK-LABEL: or_ashr_commute2: 96; CHECK: // %bb.0: 97; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b 98; CHECK-NEXT: neg v1.4s, v2.4s 99; CHECK-NEXT: sshl v0.4s, v0.4s, v1.4s 100; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b 101; CHECK-NEXT: ret 102 %sh1 = ashr <4 x i32> %x0, %y 103 %sh2 = ashr <4 x i32> %x1, %y 104 %logic = or <4 x i32> %sh1, %z 105 %r = or <4 x i32> %sh2, %logic 106 ret <4 x i32> %r 107} 108 109define <16 x i8> @or_ashr_commute3(<16 x i8> %x0, <16 x i8> %x1, <16 x i8> %y, <16 x i8> %z) { 110; CHECK-LABEL: or_ashr_commute3: 111; CHECK: // %bb.0: 112; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b 113; CHECK-NEXT: neg v1.16b, v2.16b 114; CHECK-NEXT: sshl v0.16b, v0.16b, v1.16b 115; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b 116; CHECK-NEXT: ret 117 %sh1 = ashr <16 x i8> %x0, %y 118 %sh2 = ashr <16 x i8> %x1, %y 119 %logic = or <16 x i8> %z, %sh1 120 %r = or <16 x i8> %sh2, %logic 121 ret <16 x i8> %r 122} 123 124define i32 @or_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) { 125; CHECK-LABEL: or_shl_commute0: 126; CHECK: // %bb.0: 127; CHECK-NEXT: orr w8, w0, w1 128; CHECK-NEXT: lsl w8, w8, w2 129; CHECK-NEXT: orr w0, w8, w3 130; CHECK-NEXT: ret 131 %sh1 = shl i32 %x0, %y 132 %sh2 = shl i32 %x1, %y 133 %logic = or i32 %sh1, %z 134 %r = or i32 %logic, %sh2 135 ret i32 %r 136} 137 138define i8 @or_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) { 139; CHECK-LABEL: or_shl_commute1: 140; CHECK: // %bb.0: 141; CHECK-NEXT: orr w8, w0, w1 142; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2 143; CHECK-NEXT: lsl w8, w8, w2 144; CHECK-NEXT: orr w0, w8, w3 145; CHECK-NEXT: ret 146 %sh1 = shl i8 %x0, %y 147 %sh2 = shl i8 %x1, %y 148 %logic = or i8 %z, %sh1 149 %r = or i8 %logic, %sh2 150 ret i8 %r 151} 152 153define <2 x i64> @or_shl_commute2(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) { 154; CHECK-LABEL: or_shl_commute2: 155; CHECK: // %bb.0: 156; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b 157; CHECK-NEXT: ushl v0.2d, v0.2d, v2.2d 158; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b 159; CHECK-NEXT: ret 160 %sh1 = shl <2 x i64> %x0, %y 161 %sh2 = shl <2 x i64> %x1, %y 162 %logic = or <2 x i64> %sh1, %z 163 %r = or <2 x i64> %sh2, %logic 164 ret <2 x i64> %r 165} 166 167define <8 x i16> @or_shl_commute3(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) { 168; CHECK-LABEL: or_shl_commute3: 169; CHECK: // %bb.0: 170; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b 171; CHECK-NEXT: ushl v0.8h, v0.8h, v2.8h 172; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b 173; CHECK-NEXT: ret 174 %sh1 = shl <8 x i16> %x0, %y 175 %sh2 = shl <8 x i16> %x1, %y 176 %logic = or <8 x i16> %z, %sh1 177 %r = or <8 x i16> %sh2, %logic 178 ret <8 x i16> %r 179} 180 181; negative test - mismatched shift opcodes 182 183define i64 @or_mix_shr(i64 %x0, i64 %x1, i64 %y, i64 %z) { 184; CHECK-LABEL: or_mix_shr: 185; CHECK: // %bb.0: 186; CHECK-NEXT: asr x8, x0, x2 187; CHECK-NEXT: lsr x9, x1, x2 188; CHECK-NEXT: orr x8, x8, x3 189; CHECK-NEXT: orr x0, x8, x9 190; CHECK-NEXT: ret 191 %sh1 = ashr i64 %x0, %y 192 %sh2 = lshr i64 %x1, %y 193 %logic = or i64 %sh1, %z 194 %r = or i64 %logic, %sh2 195 ret i64 %r 196} 197 198; negative test - mixed shift amounts 199 200define i64 @or_lshr_mix_shift_amount(i64 %x0, i64 %x1, i64 %y, i64 %z, i64 %w) { 201; CHECK-LABEL: or_lshr_mix_shift_amount: 202; CHECK: // %bb.0: 203; CHECK-NEXT: lsr x8, x0, x2 204; CHECK-NEXT: lsr x9, x1, x4 205; CHECK-NEXT: orr x8, x8, x3 206; CHECK-NEXT: orr x0, x8, x9 207; CHECK-NEXT: ret 208 %sh1 = lshr i64 %x0, %y 209 %sh2 = lshr i64 %x1, %w 210 %logic = or i64 %sh1, %z 211 %r = or i64 %logic, %sh2 212 ret i64 %r 213} 214 215; negative test - mismatched logic opcodes 216 217define i64 @mix_logic_lshr(i64 %x0, i64 %x1, i64 %y, i64 %z) { 218; CHECK-LABEL: mix_logic_lshr: 219; CHECK: // %bb.0: 220; CHECK-NEXT: lsr x8, x0, x2 221; CHECK-NEXT: lsr x9, x1, x2 222; CHECK-NEXT: eor x8, x8, x3 223; CHECK-NEXT: orr x0, x8, x9 224; CHECK-NEXT: ret 225 %sh1 = lshr i64 %x0, %y 226 %sh2 = lshr i64 %x1, %y 227 %logic = xor i64 %sh1, %z 228 %r = or i64 %logic, %sh2 229 ret i64 %r 230} 231 232define i8 @xor_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) { 233; CHECK-LABEL: xor_lshr_commute0: 234; CHECK: // %bb.0: 235; CHECK-NEXT: eor w8, w0, w1 236; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2 237; CHECK-NEXT: and w8, w8, #0xff 238; CHECK-NEXT: lsr w8, w8, w2 239; CHECK-NEXT: eor w0, w8, w3 240; CHECK-NEXT: ret 241 %sh1 = lshr i8 %x0, %y 242 %sh2 = lshr i8 %x1, %y 243 %logic = xor i8 %sh1, %z 244 %r = xor i8 %logic, %sh2 245 ret i8 %r 246} 247 248define i32 @xor_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) { 249; CHECK-LABEL: xor_lshr_commute1: 250; CHECK: // %bb.0: 251; CHECK-NEXT: eor w8, w0, w1 252; CHECK-NEXT: lsr w8, w8, w2 253; CHECK-NEXT: eor w0, w8, w3 254; CHECK-NEXT: ret 255 %sh1 = lshr i32 %x0, %y 256 %sh2 = lshr i32 %x1, %y 257 %logic = xor i32 %z, %sh1 258 %r = xor i32 %logic, %sh2 259 ret i32 %r 260} 261 262define <8 x i16> @xor_lshr_commute2(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) { 263; CHECK-LABEL: xor_lshr_commute2: 264; CHECK: // %bb.0: 265; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b 266; CHECK-NEXT: neg v1.8h, v2.8h 267; CHECK-NEXT: ushl v0.8h, v0.8h, v1.8h 268; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b 269; CHECK-NEXT: ret 270 %sh1 = lshr <8 x i16> %x0, %y 271 %sh2 = lshr <8 x i16> %x1, %y 272 %logic = xor <8 x i16> %sh1, %z 273 %r = xor <8 x i16> %sh2, %logic 274 ret <8 x i16> %r 275} 276 277define <2 x i64> @xor_lshr_commute3(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) { 278; CHECK-LABEL: xor_lshr_commute3: 279; CHECK: // %bb.0: 280; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b 281; CHECK-NEXT: neg v1.2d, v2.2d 282; CHECK-NEXT: ushl v0.2d, v0.2d, v1.2d 283; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b 284; CHECK-NEXT: ret 285 %sh1 = lshr <2 x i64> %x0, %y 286 %sh2 = lshr <2 x i64> %x1, %y 287 %logic = xor <2 x i64> %z, %sh1 288 %r = xor <2 x i64> %sh2, %logic 289 ret <2 x i64> %r 290} 291 292define i16 @xor_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) { 293; CHECK-LABEL: xor_ashr_commute0: 294; CHECK: // %bb.0: 295; CHECK-NEXT: eor w8, w0, w1 296; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2 297; CHECK-NEXT: sxth w8, w8 298; CHECK-NEXT: asr w8, w8, w2 299; CHECK-NEXT: eor w0, w8, w3 300; CHECK-NEXT: ret 301 %sh1 = ashr i16 %x0, %y 302 %sh2 = ashr i16 %x1, %y 303 %logic = xor i16 %sh1, %z 304 %r = xor i16 %logic, %sh2 305 ret i16 %r 306} 307 308define i64 @xor_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) { 309; CHECK-LABEL: xor_ashr_commute1: 310; CHECK: // %bb.0: 311; CHECK-NEXT: eor x8, x0, x1 312; CHECK-NEXT: asr x8, x8, x2 313; CHECK-NEXT: eor x0, x8, x3 314; CHECK-NEXT: ret 315 %sh1 = ashr i64 %x0, %y 316 %sh2 = ashr i64 %x1, %y 317 %logic = xor i64 %z, %sh1 318 %r = xor i64 %logic, %sh2 319 ret i64 %r 320} 321 322define <4 x i32> @xor_ashr_commute2(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y, <4 x i32> %z) { 323; CHECK-LABEL: xor_ashr_commute2: 324; CHECK: // %bb.0: 325; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b 326; CHECK-NEXT: neg v1.4s, v2.4s 327; CHECK-NEXT: sshl v0.4s, v0.4s, v1.4s 328; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b 329; CHECK-NEXT: ret 330 %sh1 = ashr <4 x i32> %x0, %y 331 %sh2 = ashr <4 x i32> %x1, %y 332 %logic = xor <4 x i32> %sh1, %z 333 %r = xor <4 x i32> %sh2, %logic 334 ret <4 x i32> %r 335} 336 337define <16 x i8> @xor_ashr_commute3(<16 x i8> %x0, <16 x i8> %x1, <16 x i8> %y, <16 x i8> %z) { 338; CHECK-LABEL: xor_ashr_commute3: 339; CHECK: // %bb.0: 340; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b 341; CHECK-NEXT: neg v1.16b, v2.16b 342; CHECK-NEXT: sshl v0.16b, v0.16b, v1.16b 343; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b 344; CHECK-NEXT: ret 345 %sh1 = ashr <16 x i8> %x0, %y 346 %sh2 = ashr <16 x i8> %x1, %y 347 %logic = xor <16 x i8> %z, %sh1 348 %r = xor <16 x i8> %sh2, %logic 349 ret <16 x i8> %r 350} 351 352define i32 @xor_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) { 353; CHECK-LABEL: xor_shl_commute0: 354; CHECK: // %bb.0: 355; CHECK-NEXT: eor w8, w0, w1 356; CHECK-NEXT: lsl w8, w8, w2 357; CHECK-NEXT: eor w0, w8, w3 358; CHECK-NEXT: ret 359 %sh1 = shl i32 %x0, %y 360 %sh2 = shl i32 %x1, %y 361 %logic = xor i32 %sh1, %z 362 %r = xor i32 %logic, %sh2 363 ret i32 %r 364} 365 366define i8 @xor_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) { 367; CHECK-LABEL: xor_shl_commute1: 368; CHECK: // %bb.0: 369; CHECK-NEXT: eor w8, w0, w1 370; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2 371; CHECK-NEXT: lsl w8, w8, w2 372; CHECK-NEXT: eor w0, w8, w3 373; CHECK-NEXT: ret 374 %sh1 = shl i8 %x0, %y 375 %sh2 = shl i8 %x1, %y 376 %logic = xor i8 %z, %sh1 377 %r = xor i8 %logic, %sh2 378 ret i8 %r 379} 380 381define <2 x i64> @xor_shl_commute2(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) { 382; CHECK-LABEL: xor_shl_commute2: 383; CHECK: // %bb.0: 384; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b 385; CHECK-NEXT: ushl v0.2d, v0.2d, v2.2d 386; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b 387; CHECK-NEXT: ret 388 %sh1 = shl <2 x i64> %x0, %y 389 %sh2 = shl <2 x i64> %x1, %y 390 %logic = xor <2 x i64> %sh1, %z 391 %r = xor <2 x i64> %sh2, %logic 392 ret <2 x i64> %r 393} 394 395define <8 x i16> @xor_shl_commute3(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) { 396; CHECK-LABEL: xor_shl_commute3: 397; CHECK: // %bb.0: 398; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b 399; CHECK-NEXT: ushl v0.8h, v0.8h, v2.8h 400; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b 401; CHECK-NEXT: ret 402 %sh1 = shl <8 x i16> %x0, %y 403 %sh2 = shl <8 x i16> %x1, %y 404 %logic = xor <8 x i16> %z, %sh1 405 %r = xor <8 x i16> %sh2, %logic 406 ret <8 x i16> %r 407} 408 409; negative test - mismatched shift opcodes 410 411define i64 @xor_mix_shr(i64 %x0, i64 %x1, i64 %y, i64 %z) { 412; CHECK-LABEL: xor_mix_shr: 413; CHECK: // %bb.0: 414; CHECK-NEXT: asr x8, x0, x2 415; CHECK-NEXT: lsr x9, x1, x2 416; CHECK-NEXT: eor x8, x8, x3 417; CHECK-NEXT: eor x0, x8, x9 418; CHECK-NEXT: ret 419 %sh1 = ashr i64 %x0, %y 420 %sh2 = lshr i64 %x1, %y 421 %logic = xor i64 %sh1, %z 422 %r = xor i64 %logic, %sh2 423 ret i64 %r 424} 425 426; negative test - mismatched shift amounts 427 428define i64 @xor_lshr_mix_shift_amount(i64 %x0, i64 %x1, i64 %y, i64 %z, i64 %w) { 429; CHECK-LABEL: xor_lshr_mix_shift_amount: 430; CHECK: // %bb.0: 431; CHECK-NEXT: lsr x8, x0, x2 432; CHECK-NEXT: lsr x9, x1, x4 433; CHECK-NEXT: eor x8, x8, x3 434; CHECK-NEXT: eor x0, x8, x9 435; CHECK-NEXT: ret 436 %sh1 = lshr i64 %x0, %y 437 %sh2 = lshr i64 %x1, %w 438 %logic = xor i64 %sh1, %z 439 %r = xor i64 %logic, %sh2 440 ret i64 %r 441} 442 443; negative test - mismatched logic opcodes 444 445define i64 @mix_logic_ashr(i64 %x0, i64 %x1, i64 %y, i64 %z) { 446; CHECK-LABEL: mix_logic_ashr: 447; CHECK: // %bb.0: 448; CHECK-NEXT: asr x8, x0, x2 449; CHECK-NEXT: asr x9, x1, x2 450; CHECK-NEXT: orr x8, x8, x3 451; CHECK-NEXT: eor x0, x8, x9 452; CHECK-NEXT: ret 453 %sh1 = ashr i64 %x0, %y 454 %sh2 = ashr i64 %x1, %y 455 %logic = or i64 %sh1, %z 456 %r = xor i64 %logic, %sh2 457 ret i64 %r 458} 459 460define i8 @and_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) { 461; CHECK-LABEL: and_lshr_commute0: 462; CHECK: // %bb.0: 463; CHECK-NEXT: and w8, w0, w1 464; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2 465; CHECK-NEXT: and w8, w8, #0xff 466; CHECK-NEXT: lsr w8, w8, w2 467; CHECK-NEXT: and w0, w8, w3 468; CHECK-NEXT: ret 469 %sh1 = lshr i8 %x0, %y 470 %sh2 = lshr i8 %x1, %y 471 %logic = and i8 %sh1, %z 472 %r = and i8 %logic, %sh2 473 ret i8 %r 474} 475 476define i32 @and_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) { 477; CHECK-LABEL: and_lshr_commute1: 478; CHECK: // %bb.0: 479; CHECK-NEXT: and w8, w0, w1 480; CHECK-NEXT: lsr w8, w8, w2 481; CHECK-NEXT: and w0, w8, w3 482; CHECK-NEXT: ret 483 %sh1 = lshr i32 %x0, %y 484 %sh2 = lshr i32 %x1, %y 485 %logic = and i32 %z, %sh1 486 %r = and i32 %logic, %sh2 487 ret i32 %r 488} 489 490define <8 x i16> @and_lshr_commute2(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) { 491; CHECK-LABEL: and_lshr_commute2: 492; CHECK: // %bb.0: 493; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 494; CHECK-NEXT: neg v1.8h, v2.8h 495; CHECK-NEXT: ushl v0.8h, v0.8h, v1.8h 496; CHECK-NEXT: and v0.16b, v0.16b, v3.16b 497; CHECK-NEXT: ret 498 %sh1 = lshr <8 x i16> %x0, %y 499 %sh2 = lshr <8 x i16> %x1, %y 500 %logic = and <8 x i16> %sh1, %z 501 %r = and <8 x i16> %sh2, %logic 502 ret <8 x i16> %r 503} 504 505define <2 x i64> @and_lshr_commute3(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) { 506; CHECK-LABEL: and_lshr_commute3: 507; CHECK: // %bb.0: 508; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 509; CHECK-NEXT: neg v1.2d, v2.2d 510; CHECK-NEXT: ushl v0.2d, v0.2d, v1.2d 511; CHECK-NEXT: and v0.16b, v0.16b, v3.16b 512; CHECK-NEXT: ret 513 %sh1 = lshr <2 x i64> %x0, %y 514 %sh2 = lshr <2 x i64> %x1, %y 515 %logic = and <2 x i64> %z, %sh1 516 %r = and <2 x i64> %sh2, %logic 517 ret <2 x i64> %r 518} 519 520define i16 @and_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) { 521; CHECK-LABEL: and_ashr_commute0: 522; CHECK: // %bb.0: 523; CHECK-NEXT: and w8, w0, w1 524; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2 525; CHECK-NEXT: sxth w8, w8 526; CHECK-NEXT: asr w8, w8, w2 527; CHECK-NEXT: and w0, w8, w3 528; CHECK-NEXT: ret 529 %sh1 = ashr i16 %x0, %y 530 %sh2 = ashr i16 %x1, %y 531 %logic = and i16 %sh1, %z 532 %r = and i16 %logic, %sh2 533 ret i16 %r 534} 535 536define i64 @and_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) { 537; CHECK-LABEL: and_ashr_commute1: 538; CHECK: // %bb.0: 539; CHECK-NEXT: and x8, x0, x1 540; CHECK-NEXT: asr x8, x8, x2 541; CHECK-NEXT: and x0, x8, x3 542; CHECK-NEXT: ret 543 %sh1 = ashr i64 %x0, %y 544 %sh2 = ashr i64 %x1, %y 545 %logic = and i64 %z, %sh1 546 %r = and i64 %logic, %sh2 547 ret i64 %r 548} 549 550define <4 x i32> @and_ashr_commute2(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y, <4 x i32> %z) { 551; CHECK-LABEL: and_ashr_commute2: 552; CHECK: // %bb.0: 553; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 554; CHECK-NEXT: neg v1.4s, v2.4s 555; CHECK-NEXT: sshl v0.4s, v0.4s, v1.4s 556; CHECK-NEXT: and v0.16b, v0.16b, v3.16b 557; CHECK-NEXT: ret 558 %sh1 = ashr <4 x i32> %x0, %y 559 %sh2 = ashr <4 x i32> %x1, %y 560 %logic = and <4 x i32> %sh1, %z 561 %r = and <4 x i32> %sh2, %logic 562 ret <4 x i32> %r 563} 564 565define <16 x i8> @and_ashr_commute3(<16 x i8> %x0, <16 x i8> %x1, <16 x i8> %y, <16 x i8> %z) { 566; CHECK-LABEL: and_ashr_commute3: 567; CHECK: // %bb.0: 568; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 569; CHECK-NEXT: neg v1.16b, v2.16b 570; CHECK-NEXT: sshl v0.16b, v0.16b, v1.16b 571; CHECK-NEXT: and v0.16b, v0.16b, v3.16b 572; CHECK-NEXT: ret 573 %sh1 = ashr <16 x i8> %x0, %y 574 %sh2 = ashr <16 x i8> %x1, %y 575 %logic = and <16 x i8> %z, %sh1 576 %r = and <16 x i8> %sh2, %logic 577 ret <16 x i8> %r 578} 579 580define i32 @and_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) { 581; CHECK-LABEL: and_shl_commute0: 582; CHECK: // %bb.0: 583; CHECK-NEXT: and w8, w0, w1 584; CHECK-NEXT: lsl w8, w8, w2 585; CHECK-NEXT: and w0, w8, w3 586; CHECK-NEXT: ret 587 %sh1 = shl i32 %x0, %y 588 %sh2 = shl i32 %x1, %y 589 %logic = and i32 %sh1, %z 590 %r = and i32 %logic, %sh2 591 ret i32 %r 592} 593 594define i8 @and_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) { 595; CHECK-LABEL: and_shl_commute1: 596; CHECK: // %bb.0: 597; CHECK-NEXT: and w8, w0, w1 598; CHECK-NEXT: // kill: def $w2 killed $w2 def $x2 599; CHECK-NEXT: lsl w8, w8, w2 600; CHECK-NEXT: and w0, w8, w3 601; CHECK-NEXT: ret 602 %sh1 = shl i8 %x0, %y 603 %sh2 = shl i8 %x1, %y 604 %logic = and i8 %z, %sh1 605 %r = and i8 %logic, %sh2 606 ret i8 %r 607} 608 609define <2 x i64> @and_shl_commute2(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) { 610; CHECK-LABEL: and_shl_commute2: 611; CHECK: // %bb.0: 612; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 613; CHECK-NEXT: ushl v0.2d, v0.2d, v2.2d 614; CHECK-NEXT: and v0.16b, v0.16b, v3.16b 615; CHECK-NEXT: ret 616 %sh1 = shl <2 x i64> %x0, %y 617 %sh2 = shl <2 x i64> %x1, %y 618 %logic = and <2 x i64> %sh1, %z 619 %r = and <2 x i64> %sh2, %logic 620 ret <2 x i64> %r 621} 622 623define <8 x i16> @and_shl_commute3(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) { 624; CHECK-LABEL: and_shl_commute3: 625; CHECK: // %bb.0: 626; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 627; CHECK-NEXT: ushl v0.8h, v0.8h, v2.8h 628; CHECK-NEXT: and v0.16b, v0.16b, v3.16b 629; CHECK-NEXT: ret 630 %sh1 = shl <8 x i16> %x0, %y 631 %sh2 = shl <8 x i16> %x1, %y 632 %logic = and <8 x i16> %z, %sh1 633 %r = and <8 x i16> %sh2, %logic 634 ret <8 x i16> %r 635} 636 637; negative test - mismatched shift opcodes 638 639define i64 @and_mix_shr(i64 %x0, i64 %x1, i64 %y, i64 %z) { 640; CHECK-LABEL: and_mix_shr: 641; CHECK: // %bb.0: 642; CHECK-NEXT: lsr x8, x0, x2 643; CHECK-NEXT: asr x9, x1, x2 644; CHECK-NEXT: and x8, x8, x3 645; CHECK-NEXT: and x0, x8, x9 646; CHECK-NEXT: ret 647 %sh1 = lshr i64 %x0, %y 648 %sh2 = ashr i64 %x1, %y 649 %logic = and i64 %sh1, %z 650 %r = and i64 %logic, %sh2 651 ret i64 %r 652} 653 654; negative test - mismatched shift amounts 655 656define i64 @and_lshr_mix_shift_amount(i64 %x0, i64 %x1, i64 %y, i64 %z, i64 %w) { 657; CHECK-LABEL: and_lshr_mix_shift_amount: 658; CHECK: // %bb.0: 659; CHECK-NEXT: lsr x8, x0, x2 660; CHECK-NEXT: lsr x9, x1, x4 661; CHECK-NEXT: and x8, x8, x3 662; CHECK-NEXT: and x0, x8, x9 663; CHECK-NEXT: ret 664 %sh1 = lshr i64 %x0, %y 665 %sh2 = lshr i64 %x1, %w 666 %logic = and i64 %sh1, %z 667 %r = and i64 %logic, %sh2 668 ret i64 %r 669} 670 671; negative test - mismatched logic opcodes 672 673define i64 @mix_logic_shl(i64 %x0, i64 %x1, i64 %y, i64 %z) { 674; CHECK-LABEL: mix_logic_shl: 675; CHECK: // %bb.0: 676; CHECK-NEXT: lsl x8, x0, x2 677; CHECK-NEXT: lsl x9, x1, x2 678; CHECK-NEXT: eor x8, x8, x3 679; CHECK-NEXT: and x0, x8, x9 680; CHECK-NEXT: ret 681 %sh1 = shl i64 %x0, %y 682 %sh2 = shl i64 %x1, %y 683 %logic = xor i64 %sh1, %z 684 %r = and i64 %logic, %sh2 685 ret i64 %r 686} 687 688; (shl (X | Y), C1) | (srl X, C2) --> (rotl X, C1) | (shl Y, C1) 689 690define i32 @or_fshl_commute0(i32 %x, i32 %y) { 691; CHECK-LABEL: or_fshl_commute0: 692; CHECK: // %bb.0: 693; CHECK-NEXT: orr w8, w0, w1 694; CHECK-NEXT: extr w0, w8, w0, #27 695; CHECK-NEXT: ret 696 %or1 = or i32 %x, %y 697 %sh1 = shl i32 %or1, 5 698 %sh2 = lshr i32 %x, 27 699 %r = or i32 %sh1, %sh2 700 ret i32 %r 701} 702 703define i64 @or_fshl_commute1(i64 %x, i64 %y) { 704; CHECK-LABEL: or_fshl_commute1: 705; CHECK: // %bb.0: 706; CHECK-NEXT: orr w8, w1, w0 707; CHECK-NEXT: extr x0, x8, x0, #29 708; CHECK-NEXT: ret 709 %or1 = or i64 %y, %x 710 %sh1 = shl i64 %or1, 35 711 %sh2 = lshr i64 %x, 29 712 %r = or i64 %sh1, %sh2 713 ret i64 %r 714} 715 716define i16 @or_fshl_commute2(i16 %x, i16 %y) { 717; CHECK-LABEL: or_fshl_commute2: 718; CHECK: // %bb.0: 719; CHECK-NEXT: orr w8, w0, w1 720; CHECK-NEXT: lsl w8, w8, #2 721; CHECK-NEXT: bfxil w8, w0, #14, #2 722; CHECK-NEXT: mov w0, w8 723; CHECK-NEXT: ret 724 %or1 = or i16 %x, %y 725 %sh1 = shl i16 %or1, 2 726 %sh2 = lshr i16 %x, 14 727 %r = or i16 %sh2, %sh1 728 ret i16 %r 729} 730 731define i8 @or_fshl_commute3(i8 %x, i8 %y) { 732; CHECK-LABEL: or_fshl_commute3: 733; CHECK: // %bb.0: 734; CHECK-NEXT: orr w8, w1, w0 735; CHECK-NEXT: lsl w8, w8, #5 736; CHECK-NEXT: bfxil w8, w0, #3, #5 737; CHECK-NEXT: mov w0, w8 738; CHECK-NEXT: ret 739 %or1 = or i8 %y, %x 740 %sh1 = shl i8 %or1, 5 741 %sh2 = lshr i8 %x, 3 742 %r = or i8 %sh2, %sh1 743 ret i8 %r 744} 745 746define i32 @or_fshl_wrong_shift(i32 %x, i32 %y) { 747; CHECK-LABEL: or_fshl_wrong_shift: 748; CHECK: // %bb.0: 749; CHECK-NEXT: orr w8, w0, w1 750; CHECK-NEXT: lsl w8, w8, #20 751; CHECK-NEXT: orr w0, w8, w0, lsr #11 752; CHECK-NEXT: ret 753 %or1 = or i32 %x, %y 754 %sh1 = shl i32 %or1, 20 755 %sh2 = lshr i32 %x, 11 756 %r = or i32 %sh1, %sh2 757 ret i32 %r 758} 759 760; (shl X, C1) | (srl (X | Y), C2) --> (rotl X, C1) | (srl Y, C2) 761 762define i64 @or_fshr_commute0(i64 %x, i64 %y) { 763; CHECK-LABEL: or_fshr_commute0: 764; CHECK: // %bb.0: 765; CHECK-NEXT: orr x8, x0, x1 766; CHECK-NEXT: extr x0, x0, x8, #24 767; CHECK-NEXT: ret 768 %or1 = or i64 %x, %y 769 %sh1 = shl i64 %x, 40 770 %sh2 = lshr i64 %or1, 24 771 %r = or i64 %sh1, %sh2 772 ret i64 %r 773} 774 775define i32 @or_fshr_commute1(i32 %x, i32 %y) { 776; CHECK-LABEL: or_fshr_commute1: 777; CHECK: // %bb.0: 778; CHECK-NEXT: orr w8, w1, w0 779; CHECK-NEXT: extr w0, w0, w8, #29 780; CHECK-NEXT: ret 781 %or1 = or i32 %y, %x 782 %sh1 = shl i32 %x, 3 783 %sh2 = lshr i32 %or1, 29 784 %r = or i32 %sh1, %sh2 785 ret i32 %r 786} 787 788define i16 @or_fshr_commute2(i16 %x, i16 %y) { 789; CHECK-LABEL: or_fshr_commute2: 790; CHECK: // %bb.0: 791; CHECK-NEXT: lsl w8, w0, #9 792; CHECK-NEXT: orr w9, w0, w1 793; CHECK-NEXT: bfxil w8, w9, #7, #9 794; CHECK-NEXT: mov w0, w8 795; CHECK-NEXT: ret 796 %or1 = or i16 %x, %y 797 %sh1 = shl i16 %x, 9 798 %sh2 = lshr i16 %or1, 7 799 %r = or i16 %sh2, %sh1 800 ret i16 %r 801} 802 803define i8 @or_fshr_commute3(i8 %x, i8 %y) { 804; CHECK-LABEL: or_fshr_commute3: 805; CHECK: // %bb.0: 806; CHECK-NEXT: lsl w8, w0, #2 807; CHECK-NEXT: orr w9, w1, w0 808; CHECK-NEXT: bfxil w8, w9, #6, #2 809; CHECK-NEXT: mov w0, w8 810; CHECK-NEXT: ret 811 %or1 = or i8 %y, %x 812 %sh1 = shl i8 %x, 2 813 %sh2 = lshr i8 %or1, 6 814 %r = or i8 %sh2, %sh1 815 ret i8 %r 816} 817 818define i32 @or_fshr_wrong_shift(i32 %x, i32 %y) { 819; CHECK-LABEL: or_fshr_wrong_shift: 820; CHECK: // %bb.0: 821; CHECK-NEXT: orr w8, w0, w1 822; CHECK-NEXT: lsr w8, w8, #26 823; CHECK-NEXT: orr w0, w8, w0, lsl #7 824; CHECK-NEXT: ret 825 %or1 = or i32 %x, %y 826 %sh1 = shl i32 %x, 7 827 %sh2 = lshr i32 %or1, 26 828 %r = or i32 %sh1, %sh2 829 ret i32 %r 830} 831