822 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s3 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, w18; CHECK-NEXT: and w8, w8, #0xff9; CHECK-NEXT: lsr w8, w8, w210; CHECK-NEXT: orr w0, w8, w311; CHECK-NEXT: ret12 %sh1 = lshr i8 %x0, %y13 %sh2 = lshr i8 %x1, %y14 %logic = or i8 %sh1, %z15 %r = or i8 %logic, %sh216 ret i8 %r17}18 19define i32 @or_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) {20; CHECK-LABEL: or_lshr_commute1:21; CHECK: // %bb.0:22; CHECK-NEXT: orr w8, w0, w123; CHECK-NEXT: lsr w8, w8, w224; CHECK-NEXT: orr w0, w8, w325; CHECK-NEXT: ret26 %sh1 = lshr i32 %x0, %y27 %sh2 = lshr i32 %x1, %y28 %logic = or i32 %z, %sh129 %r = or i32 %logic, %sh230 ret i32 %r31}32 33define <8 x i16> @or_lshr_commute2(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {34; CHECK-LABEL: or_lshr_commute2:35; CHECK: // %bb.0:36; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b37; CHECK-NEXT: neg v1.8h, v2.8h38; CHECK-NEXT: ushl v0.8h, v0.8h, v1.8h39; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b40; CHECK-NEXT: ret41 %sh1 = lshr <8 x i16> %x0, %y42 %sh2 = lshr <8 x i16> %x1, %y43 %logic = or <8 x i16> %sh1, %z44 %r = or <8 x i16> %sh2, %logic45 ret <8 x i16> %r46}47 48define <2 x i64> @or_lshr_commute3(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {49; CHECK-LABEL: or_lshr_commute3:50; CHECK: // %bb.0:51; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b52; CHECK-NEXT: neg v1.2d, v2.2d53; CHECK-NEXT: ushl v0.2d, v0.2d, v1.2d54; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b55; CHECK-NEXT: ret56 %sh1 = lshr <2 x i64> %x0, %y57 %sh2 = lshr <2 x i64> %x1, %y58 %logic = or <2 x i64> %z, %sh159 %r = or <2 x i64> %sh2, %logic60 ret <2 x i64> %r61}62 63define i16 @or_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) {64; CHECK-LABEL: or_ashr_commute0:65; CHECK: // %bb.0:66; CHECK-NEXT: orr w8, w0, w167; CHECK-NEXT: sxth w8, w868; CHECK-NEXT: asr w8, w8, w269; CHECK-NEXT: orr w0, w8, w370; CHECK-NEXT: ret71 %sh1 = ashr i16 %x0, %y72 %sh2 = ashr i16 %x1, %y73 %logic = or i16 %sh1, %z74 %r = or i16 %logic, %sh275 ret i16 %r76}77 78define i64 @or_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) {79; CHECK-LABEL: or_ashr_commute1:80; CHECK: // %bb.0:81; CHECK-NEXT: orr x8, x0, x182; CHECK-NEXT: asr x8, x8, x283; CHECK-NEXT: orr x0, x8, x384; CHECK-NEXT: ret85 %sh1 = ashr i64 %x0, %y86 %sh2 = ashr i64 %x1, %y87 %logic = or i64 %z, %sh188 %r = or i64 %logic, %sh289 ret i64 %r90}91 92define <4 x i32> @or_ashr_commute2(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y, <4 x i32> %z) {93; CHECK-LABEL: or_ashr_commute2:94; CHECK: // %bb.0:95; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b96; CHECK-NEXT: neg v1.4s, v2.4s97; CHECK-NEXT: sshl v0.4s, v0.4s, v1.4s98; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b99; CHECK-NEXT: ret100 %sh1 = ashr <4 x i32> %x0, %y101 %sh2 = ashr <4 x i32> %x1, %y102 %logic = or <4 x i32> %sh1, %z103 %r = or <4 x i32> %sh2, %logic104 ret <4 x i32> %r105}106 107define <16 x i8> @or_ashr_commute3(<16 x i8> %x0, <16 x i8> %x1, <16 x i8> %y, <16 x i8> %z) {108; CHECK-LABEL: or_ashr_commute3:109; CHECK: // %bb.0:110; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b111; CHECK-NEXT: neg v1.16b, v2.16b112; CHECK-NEXT: sshl v0.16b, v0.16b, v1.16b113; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b114; CHECK-NEXT: ret115 %sh1 = ashr <16 x i8> %x0, %y116 %sh2 = ashr <16 x i8> %x1, %y117 %logic = or <16 x i8> %z, %sh1118 %r = or <16 x i8> %sh2, %logic119 ret <16 x i8> %r120}121 122define i32 @or_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) {123; CHECK-LABEL: or_shl_commute0:124; CHECK: // %bb.0:125; CHECK-NEXT: orr w8, w0, w1126; CHECK-NEXT: lsl w8, w8, w2127; CHECK-NEXT: orr w0, w8, w3128; CHECK-NEXT: ret129 %sh1 = shl i32 %x0, %y130 %sh2 = shl i32 %x1, %y131 %logic = or i32 %sh1, %z132 %r = or i32 %logic, %sh2133 ret i32 %r134}135 136define i8 @or_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) {137; CHECK-LABEL: or_shl_commute1:138; CHECK: // %bb.0:139; CHECK-NEXT: orr w8, w0, w1140; CHECK-NEXT: lsl w8, w8, w2141; CHECK-NEXT: orr w0, w8, w3142; CHECK-NEXT: ret143 %sh1 = shl i8 %x0, %y144 %sh2 = shl i8 %x1, %y145 %logic = or i8 %z, %sh1146 %r = or i8 %logic, %sh2147 ret i8 %r148}149 150define <2 x i64> @or_shl_commute2(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {151; CHECK-LABEL: or_shl_commute2:152; CHECK: // %bb.0:153; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b154; CHECK-NEXT: ushl v0.2d, v0.2d, v2.2d155; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b156; CHECK-NEXT: ret157 %sh1 = shl <2 x i64> %x0, %y158 %sh2 = shl <2 x i64> %x1, %y159 %logic = or <2 x i64> %sh1, %z160 %r = or <2 x i64> %sh2, %logic161 ret <2 x i64> %r162}163 164define <8 x i16> @or_shl_commute3(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {165; CHECK-LABEL: or_shl_commute3:166; CHECK: // %bb.0:167; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b168; CHECK-NEXT: ushl v0.8h, v0.8h, v2.8h169; CHECK-NEXT: orr v0.16b, v0.16b, v3.16b170; CHECK-NEXT: ret171 %sh1 = shl <8 x i16> %x0, %y172 %sh2 = shl <8 x i16> %x1, %y173 %logic = or <8 x i16> %z, %sh1174 %r = or <8 x i16> %sh2, %logic175 ret <8 x i16> %r176}177 178; negative test - mismatched shift opcodes179 180define i64 @or_mix_shr(i64 %x0, i64 %x1, i64 %y, i64 %z) {181; CHECK-LABEL: or_mix_shr:182; CHECK: // %bb.0:183; CHECK-NEXT: asr x8, x0, x2184; CHECK-NEXT: lsr x9, x1, x2185; CHECK-NEXT: orr x8, x8, x3186; CHECK-NEXT: orr x0, x8, x9187; CHECK-NEXT: ret188 %sh1 = ashr i64 %x0, %y189 %sh2 = lshr i64 %x1, %y190 %logic = or i64 %sh1, %z191 %r = or i64 %logic, %sh2192 ret i64 %r193}194 195; negative test - mixed shift amounts196 197define i64 @or_lshr_mix_shift_amount(i64 %x0, i64 %x1, i64 %y, i64 %z, i64 %w) {198; CHECK-LABEL: or_lshr_mix_shift_amount:199; CHECK: // %bb.0:200; CHECK-NEXT: lsr x8, x0, x2201; CHECK-NEXT: lsr x9, x1, x4202; CHECK-NEXT: orr x8, x8, x3203; CHECK-NEXT: orr x0, x8, x9204; CHECK-NEXT: ret205 %sh1 = lshr i64 %x0, %y206 %sh2 = lshr i64 %x1, %w207 %logic = or i64 %sh1, %z208 %r = or i64 %logic, %sh2209 ret i64 %r210}211 212; negative test - mismatched logic opcodes213 214define i64 @mix_logic_lshr(i64 %x0, i64 %x1, i64 %y, i64 %z) {215; CHECK-LABEL: mix_logic_lshr:216; CHECK: // %bb.0:217; CHECK-NEXT: lsr x8, x0, x2218; CHECK-NEXT: lsr x9, x1, x2219; CHECK-NEXT: eor x8, x8, x3220; CHECK-NEXT: orr x0, x8, x9221; CHECK-NEXT: ret222 %sh1 = lshr i64 %x0, %y223 %sh2 = lshr i64 %x1, %y224 %logic = xor i64 %sh1, %z225 %r = or i64 %logic, %sh2226 ret i64 %r227}228 229define i8 @xor_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) {230; CHECK-LABEL: xor_lshr_commute0:231; CHECK: // %bb.0:232; CHECK-NEXT: eor w8, w0, w1233; CHECK-NEXT: and w8, w8, #0xff234; CHECK-NEXT: lsr w8, w8, w2235; CHECK-NEXT: eor w0, w8, w3236; CHECK-NEXT: ret237 %sh1 = lshr i8 %x0, %y238 %sh2 = lshr i8 %x1, %y239 %logic = xor i8 %sh1, %z240 %r = xor i8 %logic, %sh2241 ret i8 %r242}243 244define i32 @xor_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) {245; CHECK-LABEL: xor_lshr_commute1:246; CHECK: // %bb.0:247; CHECK-NEXT: eor w8, w0, w1248; CHECK-NEXT: lsr w8, w8, w2249; CHECK-NEXT: eor w0, w8, w3250; CHECK-NEXT: ret251 %sh1 = lshr i32 %x0, %y252 %sh2 = lshr i32 %x1, %y253 %logic = xor i32 %z, %sh1254 %r = xor i32 %logic, %sh2255 ret i32 %r256}257 258define <8 x i16> @xor_lshr_commute2(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {259; CHECK-LABEL: xor_lshr_commute2:260; CHECK: // %bb.0:261; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b262; CHECK-NEXT: neg v1.8h, v2.8h263; CHECK-NEXT: ushl v0.8h, v0.8h, v1.8h264; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b265; CHECK-NEXT: ret266 %sh1 = lshr <8 x i16> %x0, %y267 %sh2 = lshr <8 x i16> %x1, %y268 %logic = xor <8 x i16> %sh1, %z269 %r = xor <8 x i16> %sh2, %logic270 ret <8 x i16> %r271}272 273define <2 x i64> @xor_lshr_commute3(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {274; CHECK-LABEL: xor_lshr_commute3:275; CHECK: // %bb.0:276; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b277; CHECK-NEXT: neg v1.2d, v2.2d278; CHECK-NEXT: ushl v0.2d, v0.2d, v1.2d279; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b280; CHECK-NEXT: ret281 %sh1 = lshr <2 x i64> %x0, %y282 %sh2 = lshr <2 x i64> %x1, %y283 %logic = xor <2 x i64> %z, %sh1284 %r = xor <2 x i64> %sh2, %logic285 ret <2 x i64> %r286}287 288define i16 @xor_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) {289; CHECK-LABEL: xor_ashr_commute0:290; CHECK: // %bb.0:291; CHECK-NEXT: eor w8, w0, w1292; CHECK-NEXT: sxth w8, w8293; CHECK-NEXT: asr w8, w8, w2294; CHECK-NEXT: eor w0, w8, w3295; CHECK-NEXT: ret296 %sh1 = ashr i16 %x0, %y297 %sh2 = ashr i16 %x1, %y298 %logic = xor i16 %sh1, %z299 %r = xor i16 %logic, %sh2300 ret i16 %r301}302 303define i64 @xor_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) {304; CHECK-LABEL: xor_ashr_commute1:305; CHECK: // %bb.0:306; CHECK-NEXT: eor x8, x0, x1307; CHECK-NEXT: asr x8, x8, x2308; CHECK-NEXT: eor x0, x8, x3309; CHECK-NEXT: ret310 %sh1 = ashr i64 %x0, %y311 %sh2 = ashr i64 %x1, %y312 %logic = xor i64 %z, %sh1313 %r = xor i64 %logic, %sh2314 ret i64 %r315}316 317define <4 x i32> @xor_ashr_commute2(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y, <4 x i32> %z) {318; CHECK-LABEL: xor_ashr_commute2:319; CHECK: // %bb.0:320; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b321; CHECK-NEXT: neg v1.4s, v2.4s322; CHECK-NEXT: sshl v0.4s, v0.4s, v1.4s323; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b324; CHECK-NEXT: ret325 %sh1 = ashr <4 x i32> %x0, %y326 %sh2 = ashr <4 x i32> %x1, %y327 %logic = xor <4 x i32> %sh1, %z328 %r = xor <4 x i32> %sh2, %logic329 ret <4 x i32> %r330}331 332define <16 x i8> @xor_ashr_commute3(<16 x i8> %x0, <16 x i8> %x1, <16 x i8> %y, <16 x i8> %z) {333; CHECK-LABEL: xor_ashr_commute3:334; CHECK: // %bb.0:335; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b336; CHECK-NEXT: neg v1.16b, v2.16b337; CHECK-NEXT: sshl v0.16b, v0.16b, v1.16b338; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b339; CHECK-NEXT: ret340 %sh1 = ashr <16 x i8> %x0, %y341 %sh2 = ashr <16 x i8> %x1, %y342 %logic = xor <16 x i8> %z, %sh1343 %r = xor <16 x i8> %sh2, %logic344 ret <16 x i8> %r345}346 347define i32 @xor_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) {348; CHECK-LABEL: xor_shl_commute0:349; CHECK: // %bb.0:350; CHECK-NEXT: eor w8, w0, w1351; CHECK-NEXT: lsl w8, w8, w2352; CHECK-NEXT: eor w0, w8, w3353; CHECK-NEXT: ret354 %sh1 = shl i32 %x0, %y355 %sh2 = shl i32 %x1, %y356 %logic = xor i32 %sh1, %z357 %r = xor i32 %logic, %sh2358 ret i32 %r359}360 361define i8 @xor_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) {362; CHECK-LABEL: xor_shl_commute1:363; CHECK: // %bb.0:364; CHECK-NEXT: eor w8, w0, w1365; CHECK-NEXT: lsl w8, w8, w2366; CHECK-NEXT: eor w0, w8, w3367; CHECK-NEXT: ret368 %sh1 = shl i8 %x0, %y369 %sh2 = shl i8 %x1, %y370 %logic = xor i8 %z, %sh1371 %r = xor i8 %logic, %sh2372 ret i8 %r373}374 375define <2 x i64> @xor_shl_commute2(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {376; CHECK-LABEL: xor_shl_commute2:377; CHECK: // %bb.0:378; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b379; CHECK-NEXT: ushl v0.2d, v0.2d, v2.2d380; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b381; CHECK-NEXT: ret382 %sh1 = shl <2 x i64> %x0, %y383 %sh2 = shl <2 x i64> %x1, %y384 %logic = xor <2 x i64> %sh1, %z385 %r = xor <2 x i64> %sh2, %logic386 ret <2 x i64> %r387}388 389define <8 x i16> @xor_shl_commute3(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {390; CHECK-LABEL: xor_shl_commute3:391; CHECK: // %bb.0:392; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b393; CHECK-NEXT: ushl v0.8h, v0.8h, v2.8h394; CHECK-NEXT: eor v0.16b, v0.16b, v3.16b395; CHECK-NEXT: ret396 %sh1 = shl <8 x i16> %x0, %y397 %sh2 = shl <8 x i16> %x1, %y398 %logic = xor <8 x i16> %z, %sh1399 %r = xor <8 x i16> %sh2, %logic400 ret <8 x i16> %r401}402 403; negative test - mismatched shift opcodes404 405define i64 @xor_mix_shr(i64 %x0, i64 %x1, i64 %y, i64 %z) {406; CHECK-LABEL: xor_mix_shr:407; CHECK: // %bb.0:408; CHECK-NEXT: asr x8, x0, x2409; CHECK-NEXT: lsr x9, x1, x2410; CHECK-NEXT: eor x8, x8, x3411; CHECK-NEXT: eor x0, x8, x9412; CHECK-NEXT: ret413 %sh1 = ashr i64 %x0, %y414 %sh2 = lshr i64 %x1, %y415 %logic = xor i64 %sh1, %z416 %r = xor i64 %logic, %sh2417 ret i64 %r418}419 420; negative test - mismatched shift amounts421 422define i64 @xor_lshr_mix_shift_amount(i64 %x0, i64 %x1, i64 %y, i64 %z, i64 %w) {423; CHECK-LABEL: xor_lshr_mix_shift_amount:424; CHECK: // %bb.0:425; CHECK-NEXT: lsr x8, x0, x2426; CHECK-NEXT: lsr x9, x1, x4427; CHECK-NEXT: eor x8, x8, x3428; CHECK-NEXT: eor x0, x8, x9429; CHECK-NEXT: ret430 %sh1 = lshr i64 %x0, %y431 %sh2 = lshr i64 %x1, %w432 %logic = xor i64 %sh1, %z433 %r = xor i64 %logic, %sh2434 ret i64 %r435}436 437; negative test - mismatched logic opcodes438 439define i64 @mix_logic_ashr(i64 %x0, i64 %x1, i64 %y, i64 %z) {440; CHECK-LABEL: mix_logic_ashr:441; CHECK: // %bb.0:442; CHECK-NEXT: asr x8, x0, x2443; CHECK-NEXT: asr x9, x1, x2444; CHECK-NEXT: orr x8, x8, x3445; CHECK-NEXT: eor x0, x8, x9446; CHECK-NEXT: ret447 %sh1 = ashr i64 %x0, %y448 %sh2 = ashr i64 %x1, %y449 %logic = or i64 %sh1, %z450 %r = xor i64 %logic, %sh2451 ret i64 %r452}453 454define i8 @and_lshr_commute0(i8 %x0, i8 %x1, i8 %y, i8 %z) {455; CHECK-LABEL: and_lshr_commute0:456; CHECK: // %bb.0:457; CHECK-NEXT: and w8, w0, w1458; CHECK-NEXT: and w8, w8, #0xff459; CHECK-NEXT: lsr w8, w8, w2460; CHECK-NEXT: and w0, w8, w3461; CHECK-NEXT: ret462 %sh1 = lshr i8 %x0, %y463 %sh2 = lshr i8 %x1, %y464 %logic = and i8 %sh1, %z465 %r = and i8 %logic, %sh2466 ret i8 %r467}468 469define i32 @and_lshr_commute1(i32 %x0, i32 %x1, i32 %y, i32 %z) {470; CHECK-LABEL: and_lshr_commute1:471; CHECK: // %bb.0:472; CHECK-NEXT: and w8, w0, w1473; CHECK-NEXT: lsr w8, w8, w2474; CHECK-NEXT: and w0, w8, w3475; CHECK-NEXT: ret476 %sh1 = lshr i32 %x0, %y477 %sh2 = lshr i32 %x1, %y478 %logic = and i32 %z, %sh1479 %r = and i32 %logic, %sh2480 ret i32 %r481}482 483define <8 x i16> @and_lshr_commute2(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {484; CHECK-LABEL: and_lshr_commute2:485; CHECK: // %bb.0:486; CHECK-NEXT: and v0.16b, v0.16b, v1.16b487; CHECK-NEXT: neg v1.8h, v2.8h488; CHECK-NEXT: ushl v0.8h, v0.8h, v1.8h489; CHECK-NEXT: and v0.16b, v0.16b, v3.16b490; CHECK-NEXT: ret491 %sh1 = lshr <8 x i16> %x0, %y492 %sh2 = lshr <8 x i16> %x1, %y493 %logic = and <8 x i16> %sh1, %z494 %r = and <8 x i16> %sh2, %logic495 ret <8 x i16> %r496}497 498define <2 x i64> @and_lshr_commute3(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {499; CHECK-LABEL: and_lshr_commute3:500; CHECK: // %bb.0:501; CHECK-NEXT: and v0.16b, v0.16b, v1.16b502; CHECK-NEXT: neg v1.2d, v2.2d503; CHECK-NEXT: ushl v0.2d, v0.2d, v1.2d504; CHECK-NEXT: and v0.16b, v0.16b, v3.16b505; CHECK-NEXT: ret506 %sh1 = lshr <2 x i64> %x0, %y507 %sh2 = lshr <2 x i64> %x1, %y508 %logic = and <2 x i64> %z, %sh1509 %r = and <2 x i64> %sh2, %logic510 ret <2 x i64> %r511}512 513define i16 @and_ashr_commute0(i16 %x0, i16 %x1, i16 %y, i16 %z) {514; CHECK-LABEL: and_ashr_commute0:515; CHECK: // %bb.0:516; CHECK-NEXT: and w8, w0, w1517; CHECK-NEXT: sxth w8, w8518; CHECK-NEXT: asr w8, w8, w2519; CHECK-NEXT: and w0, w8, w3520; CHECK-NEXT: ret521 %sh1 = ashr i16 %x0, %y522 %sh2 = ashr i16 %x1, %y523 %logic = and i16 %sh1, %z524 %r = and i16 %logic, %sh2525 ret i16 %r526}527 528define i64 @and_ashr_commute1(i64 %x0, i64 %x1, i64 %y, i64 %z) {529; CHECK-LABEL: and_ashr_commute1:530; CHECK: // %bb.0:531; CHECK-NEXT: and x8, x0, x1532; CHECK-NEXT: asr x8, x8, x2533; CHECK-NEXT: and x0, x8, x3534; CHECK-NEXT: ret535 %sh1 = ashr i64 %x0, %y536 %sh2 = ashr i64 %x1, %y537 %logic = and i64 %z, %sh1538 %r = and i64 %logic, %sh2539 ret i64 %r540}541 542define <4 x i32> @and_ashr_commute2(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %y, <4 x i32> %z) {543; CHECK-LABEL: and_ashr_commute2:544; CHECK: // %bb.0:545; CHECK-NEXT: and v0.16b, v0.16b, v1.16b546; CHECK-NEXT: neg v1.4s, v2.4s547; CHECK-NEXT: sshl v0.4s, v0.4s, v1.4s548; CHECK-NEXT: and v0.16b, v0.16b, v3.16b549; CHECK-NEXT: ret550 %sh1 = ashr <4 x i32> %x0, %y551 %sh2 = ashr <4 x i32> %x1, %y552 %logic = and <4 x i32> %sh1, %z553 %r = and <4 x i32> %sh2, %logic554 ret <4 x i32> %r555}556 557define <16 x i8> @and_ashr_commute3(<16 x i8> %x0, <16 x i8> %x1, <16 x i8> %y, <16 x i8> %z) {558; CHECK-LABEL: and_ashr_commute3:559; CHECK: // %bb.0:560; CHECK-NEXT: and v0.16b, v0.16b, v1.16b561; CHECK-NEXT: neg v1.16b, v2.16b562; CHECK-NEXT: sshl v0.16b, v0.16b, v1.16b563; CHECK-NEXT: and v0.16b, v0.16b, v3.16b564; CHECK-NEXT: ret565 %sh1 = ashr <16 x i8> %x0, %y566 %sh2 = ashr <16 x i8> %x1, %y567 %logic = and <16 x i8> %z, %sh1568 %r = and <16 x i8> %sh2, %logic569 ret <16 x i8> %r570}571 572define i32 @and_shl_commute0(i32 %x0, i32 %x1, i32 %y, i32 %z) {573; CHECK-LABEL: and_shl_commute0:574; CHECK: // %bb.0:575; CHECK-NEXT: and w8, w0, w1576; CHECK-NEXT: lsl w8, w8, w2577; CHECK-NEXT: and w0, w8, w3578; CHECK-NEXT: ret579 %sh1 = shl i32 %x0, %y580 %sh2 = shl i32 %x1, %y581 %logic = and i32 %sh1, %z582 %r = and i32 %logic, %sh2583 ret i32 %r584}585 586define i8 @and_shl_commute1(i8 %x0, i8 %x1, i8 %y, i8 %z) {587; CHECK-LABEL: and_shl_commute1:588; CHECK: // %bb.0:589; CHECK-NEXT: and w8, w0, w1590; CHECK-NEXT: lsl w8, w8, w2591; CHECK-NEXT: and w0, w8, w3592; CHECK-NEXT: ret593 %sh1 = shl i8 %x0, %y594 %sh2 = shl i8 %x1, %y595 %logic = and i8 %z, %sh1596 %r = and i8 %logic, %sh2597 ret i8 %r598}599 600define <2 x i64> @and_shl_commute2(<2 x i64> %x0, <2 x i64> %x1, <2 x i64> %y, <2 x i64> %z) {601; CHECK-LABEL: and_shl_commute2:602; CHECK: // %bb.0:603; CHECK-NEXT: and v0.16b, v0.16b, v1.16b604; CHECK-NEXT: ushl v0.2d, v0.2d, v2.2d605; CHECK-NEXT: and v0.16b, v0.16b, v3.16b606; CHECK-NEXT: ret607 %sh1 = shl <2 x i64> %x0, %y608 %sh2 = shl <2 x i64> %x1, %y609 %logic = and <2 x i64> %sh1, %z610 %r = and <2 x i64> %sh2, %logic611 ret <2 x i64> %r612}613 614define <8 x i16> @and_shl_commute3(<8 x i16> %x0, <8 x i16> %x1, <8 x i16> %y, <8 x i16> %z) {615; CHECK-LABEL: and_shl_commute3:616; CHECK: // %bb.0:617; CHECK-NEXT: and v0.16b, v0.16b, v1.16b618; CHECK-NEXT: ushl v0.8h, v0.8h, v2.8h619; CHECK-NEXT: and v0.16b, v0.16b, v3.16b620; CHECK-NEXT: ret621 %sh1 = shl <8 x i16> %x0, %y622 %sh2 = shl <8 x i16> %x1, %y623 %logic = and <8 x i16> %z, %sh1624 %r = and <8 x i16> %sh2, %logic625 ret <8 x i16> %r626}627 628; negative test - mismatched shift opcodes629 630define i64 @and_mix_shr(i64 %x0, i64 %x1, i64 %y, i64 %z) {631; CHECK-LABEL: and_mix_shr:632; CHECK: // %bb.0:633; CHECK-NEXT: lsr x8, x0, x2634; CHECK-NEXT: asr x9, x1, x2635; CHECK-NEXT: and x8, x8, x3636; CHECK-NEXT: and x0, x8, x9637; CHECK-NEXT: ret638 %sh1 = lshr i64 %x0, %y639 %sh2 = ashr i64 %x1, %y640 %logic = and i64 %sh1, %z641 %r = and i64 %logic, %sh2642 ret i64 %r643}644 645; negative test - mismatched shift amounts646 647define i64 @and_lshr_mix_shift_amount(i64 %x0, i64 %x1, i64 %y, i64 %z, i64 %w) {648; CHECK-LABEL: and_lshr_mix_shift_amount:649; CHECK: // %bb.0:650; CHECK-NEXT: lsr x8, x0, x2651; CHECK-NEXT: lsr x9, x1, x4652; CHECK-NEXT: and x8, x8, x3653; CHECK-NEXT: and x0, x8, x9654; CHECK-NEXT: ret655 %sh1 = lshr i64 %x0, %y656 %sh2 = lshr i64 %x1, %w657 %logic = and i64 %sh1, %z658 %r = and i64 %logic, %sh2659 ret i64 %r660}661 662; negative test - mismatched logic opcodes663 664define i64 @mix_logic_shl(i64 %x0, i64 %x1, i64 %y, i64 %z) {665; CHECK-LABEL: mix_logic_shl:666; CHECK: // %bb.0:667; CHECK-NEXT: lsl x8, x0, x2668; CHECK-NEXT: lsl x9, x1, x2669; CHECK-NEXT: eor x8, x8, x3670; CHECK-NEXT: and x0, x8, x9671; CHECK-NEXT: ret672 %sh1 = shl i64 %x0, %y673 %sh2 = shl i64 %x1, %y674 %logic = xor i64 %sh1, %z675 %r = and i64 %logic, %sh2676 ret i64 %r677}678 679; (shl (X | Y), C1) | (srl X, C2) --> (rotl X, C1) | (shl Y, C1)680 681define i32 @or_fshl_commute0(i32 %x, i32 %y) {682; CHECK-LABEL: or_fshl_commute0:683; CHECK: // %bb.0:684; CHECK-NEXT: orr w8, w0, w1685; CHECK-NEXT: extr w0, w8, w0, #27686; CHECK-NEXT: ret687 %or1 = or i32 %x, %y688 %sh1 = shl i32 %or1, 5689 %sh2 = lshr i32 %x, 27690 %r = or i32 %sh1, %sh2691 ret i32 %r692}693 694define i64 @or_fshl_commute1(i64 %x, i64 %y) {695; CHECK-LABEL: or_fshl_commute1:696; CHECK: // %bb.0:697; CHECK-NEXT: orr w8, w1, w0698; CHECK-NEXT: extr x0, x8, x0, #29699; CHECK-NEXT: ret700 %or1 = or i64 %y, %x701 %sh1 = shl i64 %or1, 35702 %sh2 = lshr i64 %x, 29703 %r = or i64 %sh1, %sh2704 ret i64 %r705}706 707define i16 @or_fshl_commute2(i16 %x, i16 %y) {708; CHECK-LABEL: or_fshl_commute2:709; CHECK: // %bb.0:710; CHECK-NEXT: orr w8, w0, w1711; CHECK-NEXT: lsl w8, w8, #2712; CHECK-NEXT: bfxil w8, w0, #14, #2713; CHECK-NEXT: mov w0, w8714; CHECK-NEXT: ret715 %or1 = or i16 %x, %y716 %sh1 = shl i16 %or1, 2717 %sh2 = lshr i16 %x, 14718 %r = or i16 %sh2, %sh1719 ret i16 %r720}721 722define i8 @or_fshl_commute3(i8 %x, i8 %y) {723; CHECK-LABEL: or_fshl_commute3:724; CHECK: // %bb.0:725; CHECK-NEXT: orr w8, w1, w0726; CHECK-NEXT: lsl w8, w8, #5727; CHECK-NEXT: bfxil w8, w0, #3, #5728; CHECK-NEXT: mov w0, w8729; CHECK-NEXT: ret730 %or1 = or i8 %y, %x731 %sh1 = shl i8 %or1, 5732 %sh2 = lshr i8 %x, 3733 %r = or i8 %sh2, %sh1734 ret i8 %r735}736 737define i32 @or_fshl_wrong_shift(i32 %x, i32 %y) {738; CHECK-LABEL: or_fshl_wrong_shift:739; CHECK: // %bb.0:740; CHECK-NEXT: orr w8, w0, w1741; CHECK-NEXT: lsl w8, w8, #20742; CHECK-NEXT: orr w0, w8, w0, lsr #11743; CHECK-NEXT: ret744 %or1 = or i32 %x, %y745 %sh1 = shl i32 %or1, 20746 %sh2 = lshr i32 %x, 11747 %r = or i32 %sh1, %sh2748 ret i32 %r749}750 751; (shl X, C1) | (srl (X | Y), C2) --> (rotl X, C1) | (srl Y, C2)752 753define i64 @or_fshr_commute0(i64 %x, i64 %y) {754; CHECK-LABEL: or_fshr_commute0:755; CHECK: // %bb.0:756; CHECK-NEXT: orr x8, x0, x1757; CHECK-NEXT: extr x0, x0, x8, #24758; CHECK-NEXT: ret759 %or1 = or i64 %x, %y760 %sh1 = shl i64 %x, 40761 %sh2 = lshr i64 %or1, 24762 %r = or i64 %sh1, %sh2763 ret i64 %r764}765 766define i32 @or_fshr_commute1(i32 %x, i32 %y) {767; CHECK-LABEL: or_fshr_commute1:768; CHECK: // %bb.0:769; CHECK-NEXT: orr w8, w1, w0770; CHECK-NEXT: extr w0, w0, w8, #29771; CHECK-NEXT: ret772 %or1 = or i32 %y, %x773 %sh1 = shl i32 %x, 3774 %sh2 = lshr i32 %or1, 29775 %r = or i32 %sh1, %sh2776 ret i32 %r777}778 779define i16 @or_fshr_commute2(i16 %x, i16 %y) {780; CHECK-LABEL: or_fshr_commute2:781; CHECK: // %bb.0:782; CHECK-NEXT: lsl w8, w0, #9783; CHECK-NEXT: orr w9, w0, w1784; CHECK-NEXT: bfxil w8, w9, #7, #9785; CHECK-NEXT: mov w0, w8786; CHECK-NEXT: ret787 %or1 = or i16 %x, %y788 %sh1 = shl i16 %x, 9789 %sh2 = lshr i16 %or1, 7790 %r = or i16 %sh2, %sh1791 ret i16 %r792}793 794define i8 @or_fshr_commute3(i8 %x, i8 %y) {795; CHECK-LABEL: or_fshr_commute3:796; CHECK: // %bb.0:797; CHECK-NEXT: lsl w8, w0, #2798; CHECK-NEXT: orr w9, w1, w0799; CHECK-NEXT: bfxil w8, w9, #6, #2800; CHECK-NEXT: mov w0, w8801; CHECK-NEXT: ret802 %or1 = or i8 %y, %x803 %sh1 = shl i8 %x, 2804 %sh2 = lshr i8 %or1, 6805 %r = or i8 %sh2, %sh1806 ret i8 %r807}808 809define i32 @or_fshr_wrong_shift(i32 %x, i32 %y) {810; CHECK-LABEL: or_fshr_wrong_shift:811; CHECK: // %bb.0:812; CHECK-NEXT: orr w8, w0, w1813; CHECK-NEXT: lsr w8, w8, #26814; CHECK-NEXT: orr w0, w8, w0, lsl #7815; CHECK-NEXT: ret816 %or1 = or i32 %x, %y817 %sh1 = shl i32 %x, 7818 %sh2 = lshr i32 %or1, 26819 %r = or i32 %sh1, %sh2820 ret i32 %r821}822