768 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s3 4; *Please* keep in sync with test/CodeGen/X86/extract-lowbits.ll5 6; https://bugs.llvm.org/show_bug.cgi?id=364197; https://bugs.llvm.org/show_bug.cgi?id=376038; https://bugs.llvm.org/show_bug.cgi?id=376109 10; Patterns:11; a) x & (1 << nbits) - 112; b) x & ~(-1 << nbits)13; c) x & (-1 >> (32 - y))14; d) x << (32 - y) >> (32 - y)15; are equivalent.16 17; ---------------------------------------------------------------------------- ;18; Pattern a. 32-bit19; ---------------------------------------------------------------------------- ;20 21define i32 @bzhi32_a0(i32 %val, i32 %numlowbits) nounwind {22; CHECK-LABEL: bzhi32_a0:23; CHECK: // %bb.0:24; CHECK-NEXT: mov w8, #1 // =0x125; CHECK-NEXT: lsl w8, w8, w126; CHECK-NEXT: sub w8, w8, #127; CHECK-NEXT: and w0, w8, w028; CHECK-NEXT: ret29 %onebit = shl i32 1, %numlowbits30 %mask = add nsw i32 %onebit, -131 %masked = and i32 %mask, %val32 ret i32 %masked33}34 35define i32 @bzhi32_a1_indexzext(i32 %val, i8 zeroext %numlowbits) nounwind {36; CHECK-LABEL: bzhi32_a1_indexzext:37; CHECK: // %bb.0:38; CHECK-NEXT: mov w8, #1 // =0x139; CHECK-NEXT: lsl w8, w8, w140; CHECK-NEXT: sub w8, w8, #141; CHECK-NEXT: and w0, w8, w042; CHECK-NEXT: ret43 %conv = zext i8 %numlowbits to i3244 %onebit = shl i32 1, %conv45 %mask = add nsw i32 %onebit, -146 %masked = and i32 %mask, %val47 ret i32 %masked48}49 50define i32 @bzhi32_a2_load(ptr %w, i32 %numlowbits) nounwind {51; CHECK-LABEL: bzhi32_a2_load:52; CHECK: // %bb.0:53; CHECK-NEXT: mov w8, #1 // =0x154; CHECK-NEXT: ldr w9, [x0]55; CHECK-NEXT: lsl w8, w8, w156; CHECK-NEXT: sub w8, w8, #157; CHECK-NEXT: and w0, w8, w958; CHECK-NEXT: ret59 %val = load i32, ptr %w60 %onebit = shl i32 1, %numlowbits61 %mask = add nsw i32 %onebit, -162 %masked = and i32 %mask, %val63 ret i32 %masked64}65 66define i32 @bzhi32_a3_load_indexzext(ptr %w, i8 zeroext %numlowbits) nounwind {67; CHECK-LABEL: bzhi32_a3_load_indexzext:68; CHECK: // %bb.0:69; CHECK-NEXT: mov w8, #1 // =0x170; CHECK-NEXT: ldr w9, [x0]71; CHECK-NEXT: lsl w8, w8, w172; CHECK-NEXT: sub w8, w8, #173; CHECK-NEXT: and w0, w8, w974; CHECK-NEXT: ret75 %val = load i32, ptr %w76 %conv = zext i8 %numlowbits to i3277 %onebit = shl i32 1, %conv78 %mask = add nsw i32 %onebit, -179 %masked = and i32 %mask, %val80 ret i32 %masked81}82 83define i32 @bzhi32_a4_commutative(i32 %val, i32 %numlowbits) nounwind {84; CHECK-LABEL: bzhi32_a4_commutative:85; CHECK: // %bb.0:86; CHECK-NEXT: mov w8, #1 // =0x187; CHECK-NEXT: lsl w8, w8, w188; CHECK-NEXT: sub w8, w8, #189; CHECK-NEXT: and w0, w0, w890; CHECK-NEXT: ret91 %onebit = shl i32 1, %numlowbits92 %mask = add nsw i32 %onebit, -193 %masked = and i32 %val, %mask ; swapped order94 ret i32 %masked95}96 97; 64-bit98 99define i64 @bzhi64_a0(i64 %val, i64 %numlowbits) nounwind {100; CHECK-LABEL: bzhi64_a0:101; CHECK: // %bb.0:102; CHECK-NEXT: mov w8, #1 // =0x1103; CHECK-NEXT: lsl x8, x8, x1104; CHECK-NEXT: sub x8, x8, #1105; CHECK-NEXT: and x0, x8, x0106; CHECK-NEXT: ret107 %onebit = shl i64 1, %numlowbits108 %mask = add nsw i64 %onebit, -1109 %masked = and i64 %mask, %val110 ret i64 %masked111}112 113; Check that we don't throw away the vreg_width-1 mask if not using shifts114define i64 @bzhi64_a0_masked(i64 %val, i64 %numlowbits) nounwind {115; CHECK-LABEL: bzhi64_a0_masked:116; CHECK: // %bb.0:117; CHECK-NEXT: mov w8, #1 // =0x1118; CHECK-NEXT: lsl x8, x8, x1119; CHECK-NEXT: sub x8, x8, #1120; CHECK-NEXT: and x0, x8, x0121; CHECK-NEXT: ret122 %numlowbits.masked = and i64 %numlowbits, 63123 %onebit = shl i64 1, %numlowbits.masked124 %mask = add nsw i64 %onebit, -1125 %masked = and i64 %mask, %val126 ret i64 %masked127}128 129define i64 @bzhi64_a1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind {130; CHECK-LABEL: bzhi64_a1_indexzext:131; CHECK: // %bb.0:132; CHECK-NEXT: mov w8, #1 // =0x1133; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1134; CHECK-NEXT: lsl x8, x8, x1135; CHECK-NEXT: sub x8, x8, #1136; CHECK-NEXT: and x0, x8, x0137; CHECK-NEXT: ret138 %conv = zext i8 %numlowbits to i64139 %onebit = shl i64 1, %conv140 %mask = add nsw i64 %onebit, -1141 %masked = and i64 %mask, %val142 ret i64 %masked143}144 145define i64 @bzhi64_a2_load(ptr %w, i64 %numlowbits) nounwind {146; CHECK-LABEL: bzhi64_a2_load:147; CHECK: // %bb.0:148; CHECK-NEXT: mov w8, #1 // =0x1149; CHECK-NEXT: ldr x9, [x0]150; CHECK-NEXT: lsl x8, x8, x1151; CHECK-NEXT: sub x8, x8, #1152; CHECK-NEXT: and x0, x8, x9153; CHECK-NEXT: ret154 %val = load i64, ptr %w155 %onebit = shl i64 1, %numlowbits156 %mask = add nsw i64 %onebit, -1157 %masked = and i64 %mask, %val158 ret i64 %masked159}160 161define i64 @bzhi64_a3_load_indexzext(ptr %w, i8 zeroext %numlowbits) nounwind {162; CHECK-LABEL: bzhi64_a3_load_indexzext:163; CHECK: // %bb.0:164; CHECK-NEXT: mov w8, #1 // =0x1165; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1166; CHECK-NEXT: ldr x9, [x0]167; CHECK-NEXT: lsl x8, x8, x1168; CHECK-NEXT: sub x8, x8, #1169; CHECK-NEXT: and x0, x8, x9170; CHECK-NEXT: ret171 %val = load i64, ptr %w172 %conv = zext i8 %numlowbits to i64173 %onebit = shl i64 1, %conv174 %mask = add nsw i64 %onebit, -1175 %masked = and i64 %mask, %val176 ret i64 %masked177}178 179define i64 @bzhi64_a4_commutative(i64 %val, i64 %numlowbits) nounwind {180; CHECK-LABEL: bzhi64_a4_commutative:181; CHECK: // %bb.0:182; CHECK-NEXT: mov w8, #1 // =0x1183; CHECK-NEXT: lsl x8, x8, x1184; CHECK-NEXT: sub x8, x8, #1185; CHECK-NEXT: and x0, x0, x8186; CHECK-NEXT: ret187 %onebit = shl i64 1, %numlowbits188 %mask = add nsw i64 %onebit, -1189 %masked = and i64 %val, %mask ; swapped order190 ret i64 %masked191}192 193; ---------------------------------------------------------------------------- ;194; Pattern b. 32-bit195; ---------------------------------------------------------------------------- ;196 197define i32 @bzhi32_b0(i32 %val, i32 %numlowbits) nounwind {198; CHECK-LABEL: bzhi32_b0:199; CHECK: // %bb.0:200; CHECK-NEXT: mov w8, #-1 // =0xffffffff201; CHECK-NEXT: lsl w8, w8, w1202; CHECK-NEXT: bic w0, w0, w8203; CHECK-NEXT: ret204 %notmask = shl i32 -1, %numlowbits205 %mask = xor i32 %notmask, -1206 %masked = and i32 %mask, %val207 ret i32 %masked208}209 210define i32 @bzhi32_b1_indexzext(i32 %val, i8 zeroext %numlowbits) nounwind {211; CHECK-LABEL: bzhi32_b1_indexzext:212; CHECK: // %bb.0:213; CHECK-NEXT: mov w8, #-1 // =0xffffffff214; CHECK-NEXT: lsl w8, w8, w1215; CHECK-NEXT: bic w0, w0, w8216; CHECK-NEXT: ret217 %conv = zext i8 %numlowbits to i32218 %notmask = shl i32 -1, %conv219 %mask = xor i32 %notmask, -1220 %masked = and i32 %mask, %val221 ret i32 %masked222}223 224define i32 @bzhi32_b2_load(ptr %w, i32 %numlowbits) nounwind {225; CHECK-LABEL: bzhi32_b2_load:226; CHECK: // %bb.0:227; CHECK-NEXT: mov w8, #-1 // =0xffffffff228; CHECK-NEXT: ldr w9, [x0]229; CHECK-NEXT: lsl w8, w8, w1230; CHECK-NEXT: bic w0, w9, w8231; CHECK-NEXT: ret232 %val = load i32, ptr %w233 %notmask = shl i32 -1, %numlowbits234 %mask = xor i32 %notmask, -1235 %masked = and i32 %mask, %val236 ret i32 %masked237}238 239define i32 @bzhi32_b3_load_indexzext(ptr %w, i8 zeroext %numlowbits) nounwind {240; CHECK-LABEL: bzhi32_b3_load_indexzext:241; CHECK: // %bb.0:242; CHECK-NEXT: mov w8, #-1 // =0xffffffff243; CHECK-NEXT: ldr w9, [x0]244; CHECK-NEXT: lsl w8, w8, w1245; CHECK-NEXT: bic w0, w9, w8246; CHECK-NEXT: ret247 %val = load i32, ptr %w248 %conv = zext i8 %numlowbits to i32249 %notmask = shl i32 -1, %conv250 %mask = xor i32 %notmask, -1251 %masked = and i32 %mask, %val252 ret i32 %masked253}254 255define i32 @bzhi32_b4_commutative(i32 %val, i32 %numlowbits) nounwind {256; CHECK-LABEL: bzhi32_b4_commutative:257; CHECK: // %bb.0:258; CHECK-NEXT: mov w8, #-1 // =0xffffffff259; CHECK-NEXT: lsl w8, w8, w1260; CHECK-NEXT: bic w0, w0, w8261; CHECK-NEXT: ret262 %notmask = shl i32 -1, %numlowbits263 %mask = xor i32 %notmask, -1264 %masked = and i32 %val, %mask ; swapped order265 ret i32 %masked266}267 268; 64-bit269 270define i64 @bzhi64_b0(i64 %val, i64 %numlowbits) nounwind {271; CHECK-LABEL: bzhi64_b0:272; CHECK: // %bb.0:273; CHECK-NEXT: mov x8, #-1 // =0xffffffffffffffff274; CHECK-NEXT: lsl x8, x8, x1275; CHECK-NEXT: bic x0, x0, x8276; CHECK-NEXT: ret277 %notmask = shl i64 -1, %numlowbits278 %mask = xor i64 %notmask, -1279 %masked = and i64 %mask, %val280 ret i64 %masked281}282 283define i64 @bzhi64_b1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind {284; CHECK-LABEL: bzhi64_b1_indexzext:285; CHECK: // %bb.0:286; CHECK-NEXT: mov x8, #-1 // =0xffffffffffffffff287; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1288; CHECK-NEXT: lsl x8, x8, x1289; CHECK-NEXT: bic x0, x0, x8290; CHECK-NEXT: ret291 %conv = zext i8 %numlowbits to i64292 %notmask = shl i64 -1, %conv293 %mask = xor i64 %notmask, -1294 %masked = and i64 %mask, %val295 ret i64 %masked296}297 298define i64 @bzhi64_b2_load(ptr %w, i64 %numlowbits) nounwind {299; CHECK-LABEL: bzhi64_b2_load:300; CHECK: // %bb.0:301; CHECK-NEXT: mov x8, #-1 // =0xffffffffffffffff302; CHECK-NEXT: ldr x9, [x0]303; CHECK-NEXT: lsl x8, x8, x1304; CHECK-NEXT: bic x0, x9, x8305; CHECK-NEXT: ret306 %val = load i64, ptr %w307 %notmask = shl i64 -1, %numlowbits308 %mask = xor i64 %notmask, -1309 %masked = and i64 %mask, %val310 ret i64 %masked311}312 313define i64 @bzhi64_b3_load_indexzext(ptr %w, i8 zeroext %numlowbits) nounwind {314; CHECK-LABEL: bzhi64_b3_load_indexzext:315; CHECK: // %bb.0:316; CHECK-NEXT: mov x8, #-1 // =0xffffffffffffffff317; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1318; CHECK-NEXT: ldr x9, [x0]319; CHECK-NEXT: lsl x8, x8, x1320; CHECK-NEXT: bic x0, x9, x8321; CHECK-NEXT: ret322 %val = load i64, ptr %w323 %conv = zext i8 %numlowbits to i64324 %notmask = shl i64 -1, %conv325 %mask = xor i64 %notmask, -1326 %masked = and i64 %mask, %val327 ret i64 %masked328}329 330define i64 @bzhi64_b4_commutative(i64 %val, i64 %numlowbits) nounwind {331; CHECK-LABEL: bzhi64_b4_commutative:332; CHECK: // %bb.0:333; CHECK-NEXT: mov x8, #-1 // =0xffffffffffffffff334; CHECK-NEXT: lsl x8, x8, x1335; CHECK-NEXT: bic x0, x0, x8336; CHECK-NEXT: ret337 %notmask = shl i64 -1, %numlowbits338 %mask = xor i64 %notmask, -1339 %masked = and i64 %val, %mask ; swapped order340 ret i64 %masked341}342 343; ---------------------------------------------------------------------------- ;344; Pattern c. 32-bit345; ---------------------------------------------------------------------------- ;346 347define i32 @bzhi32_c0(i32 %val, i32 %numlowbits) nounwind {348; CHECK-LABEL: bzhi32_c0:349; CHECK: // %bb.0:350; CHECK-NEXT: neg w8, w1351; CHECK-NEXT: lsl w9, w0, w8352; CHECK-NEXT: lsr w0, w9, w8353; CHECK-NEXT: ret354 %numhighbits = sub i32 32, %numlowbits355 %mask = lshr i32 -1, %numhighbits356 %masked = and i32 %mask, %val357 ret i32 %masked358}359 360define i32 @bzhi32_c1_indexzext(i32 %val, i8 %numlowbits) nounwind {361; CHECK-LABEL: bzhi32_c1_indexzext:362; CHECK: // %bb.0:363; CHECK-NEXT: mov w8, #32 // =0x20364; CHECK-NEXT: sub w8, w8, w1365; CHECK-NEXT: lsl w9, w0, w8366; CHECK-NEXT: lsr w0, w9, w8367; CHECK-NEXT: ret368 %numhighbits = sub i8 32, %numlowbits369 %sh_prom = zext i8 %numhighbits to i32370 %mask = lshr i32 -1, %sh_prom371 %masked = and i32 %mask, %val372 ret i32 %masked373}374 375define i32 @bzhi32_c2_load(ptr %w, i32 %numlowbits) nounwind {376; CHECK-LABEL: bzhi32_c2_load:377; CHECK: // %bb.0:378; CHECK-NEXT: ldr w8, [x0]379; CHECK-NEXT: neg w9, w1380; CHECK-NEXT: lsl w8, w8, w9381; CHECK-NEXT: lsr w0, w8, w9382; CHECK-NEXT: ret383 %val = load i32, ptr %w384 %numhighbits = sub i32 32, %numlowbits385 %mask = lshr i32 -1, %numhighbits386 %masked = and i32 %mask, %val387 ret i32 %masked388}389 390define i32 @bzhi32_c3_load_indexzext(ptr %w, i8 %numlowbits) nounwind {391; CHECK-LABEL: bzhi32_c3_load_indexzext:392; CHECK: // %bb.0:393; CHECK-NEXT: mov w8, #32 // =0x20394; CHECK-NEXT: ldr w9, [x0]395; CHECK-NEXT: sub w8, w8, w1396; CHECK-NEXT: lsl w9, w9, w8397; CHECK-NEXT: lsr w0, w9, w8398; CHECK-NEXT: ret399 %val = load i32, ptr %w400 %numhighbits = sub i8 32, %numlowbits401 %sh_prom = zext i8 %numhighbits to i32402 %mask = lshr i32 -1, %sh_prom403 %masked = and i32 %mask, %val404 ret i32 %masked405}406 407define i32 @bzhi32_c4_commutative(i32 %val, i32 %numlowbits) nounwind {408; CHECK-LABEL: bzhi32_c4_commutative:409; CHECK: // %bb.0:410; CHECK-NEXT: neg w8, w1411; CHECK-NEXT: lsl w9, w0, w8412; CHECK-NEXT: lsr w0, w9, w8413; CHECK-NEXT: ret414 %numhighbits = sub i32 32, %numlowbits415 %mask = lshr i32 -1, %numhighbits416 %masked = and i32 %val, %mask ; swapped order417 ret i32 %masked418}419 420; 64-bit421 422define i64 @bzhi64_c0(i64 %val, i64 %numlowbits) nounwind {423; CHECK-LABEL: bzhi64_c0:424; CHECK: // %bb.0:425; CHECK-NEXT: neg x8, x1426; CHECK-NEXT: lsl x9, x0, x8427; CHECK-NEXT: lsr x0, x9, x8428; CHECK-NEXT: ret429 %numhighbits = sub i64 64, %numlowbits430 %mask = lshr i64 -1, %numhighbits431 %masked = and i64 %mask, %val432 ret i64 %masked433}434 435define i64 @bzhi64_c1_indexzext(i64 %val, i8 %numlowbits) nounwind {436; CHECK-LABEL: bzhi64_c1_indexzext:437; CHECK: // %bb.0:438; CHECK-NEXT: mov w8, #64 // =0x40439; CHECK-NEXT: sub w8, w8, w1440; CHECK-NEXT: lsl x9, x0, x8441; CHECK-NEXT: lsr x0, x9, x8442; CHECK-NEXT: ret443 %numhighbits = sub i8 64, %numlowbits444 %sh_prom = zext i8 %numhighbits to i64445 %mask = lshr i64 -1, %sh_prom446 %masked = and i64 %mask, %val447 ret i64 %masked448}449 450define i64 @bzhi64_c2_load(ptr %w, i64 %numlowbits) nounwind {451; CHECK-LABEL: bzhi64_c2_load:452; CHECK: // %bb.0:453; CHECK-NEXT: ldr x8, [x0]454; CHECK-NEXT: neg x9, x1455; CHECK-NEXT: lsl x8, x8, x9456; CHECK-NEXT: lsr x0, x8, x9457; CHECK-NEXT: ret458 %val = load i64, ptr %w459 %numhighbits = sub i64 64, %numlowbits460 %mask = lshr i64 -1, %numhighbits461 %masked = and i64 %mask, %val462 ret i64 %masked463}464 465define i64 @bzhi64_c3_load_indexzext(ptr %w, i8 %numlowbits) nounwind {466; CHECK-LABEL: bzhi64_c3_load_indexzext:467; CHECK: // %bb.0:468; CHECK-NEXT: mov w8, #64 // =0x40469; CHECK-NEXT: ldr x9, [x0]470; CHECK-NEXT: sub w8, w8, w1471; CHECK-NEXT: lsl x9, x9, x8472; CHECK-NEXT: lsr x0, x9, x8473; CHECK-NEXT: ret474 %val = load i64, ptr %w475 %numhighbits = sub i8 64, %numlowbits476 %sh_prom = zext i8 %numhighbits to i64477 %mask = lshr i64 -1, %sh_prom478 %masked = and i64 %mask, %val479 ret i64 %masked480}481 482define i64 @bzhi64_c4_commutative(i64 %val, i64 %numlowbits) nounwind {483; CHECK-LABEL: bzhi64_c4_commutative:484; CHECK: // %bb.0:485; CHECK-NEXT: neg x8, x1486; CHECK-NEXT: lsl x9, x0, x8487; CHECK-NEXT: lsr x0, x9, x8488; CHECK-NEXT: ret489 %numhighbits = sub i64 64, %numlowbits490 %mask = lshr i64 -1, %numhighbits491 %masked = and i64 %val, %mask ; swapped order492 ret i64 %masked493}494 495; ---------------------------------------------------------------------------- ;496; Pattern d. 32-bit.497; ---------------------------------------------------------------------------- ;498 499define i32 @bzhi32_d0(i32 %val, i32 %numlowbits) nounwind {500; CHECK-LABEL: bzhi32_d0:501; CHECK: // %bb.0:502; CHECK-NEXT: neg w8, w1503; CHECK-NEXT: lsl w9, w0, w8504; CHECK-NEXT: lsr w0, w9, w8505; CHECK-NEXT: ret506 %numhighbits = sub i32 32, %numlowbits507 %highbitscleared = shl i32 %val, %numhighbits508 %masked = lshr i32 %highbitscleared, %numhighbits509 ret i32 %masked510}511 512define i32 @bzhi32_d1_indexzext(i32 %val, i8 %numlowbits) nounwind {513; CHECK-LABEL: bzhi32_d1_indexzext:514; CHECK: // %bb.0:515; CHECK-NEXT: mov w8, #32 // =0x20516; CHECK-NEXT: sub w8, w8, w1517; CHECK-NEXT: lsl w9, w0, w8518; CHECK-NEXT: lsr w0, w9, w8519; CHECK-NEXT: ret520 %numhighbits = sub i8 32, %numlowbits521 %sh_prom = zext i8 %numhighbits to i32522 %highbitscleared = shl i32 %val, %sh_prom523 %masked = lshr i32 %highbitscleared, %sh_prom524 ret i32 %masked525}526 527define i32 @bzhi32_d2_load(ptr %w, i32 %numlowbits) nounwind {528; CHECK-LABEL: bzhi32_d2_load:529; CHECK: // %bb.0:530; CHECK-NEXT: ldr w8, [x0]531; CHECK-NEXT: neg w9, w1532; CHECK-NEXT: lsl w8, w8, w9533; CHECK-NEXT: lsr w0, w8, w9534; CHECK-NEXT: ret535 %val = load i32, ptr %w536 %numhighbits = sub i32 32, %numlowbits537 %highbitscleared = shl i32 %val, %numhighbits538 %masked = lshr i32 %highbitscleared, %numhighbits539 ret i32 %masked540}541 542define i32 @bzhi32_d3_load_indexzext(ptr %w, i8 %numlowbits) nounwind {543; CHECK-LABEL: bzhi32_d3_load_indexzext:544; CHECK: // %bb.0:545; CHECK-NEXT: mov w8, #32 // =0x20546; CHECK-NEXT: ldr w9, [x0]547; CHECK-NEXT: sub w8, w8, w1548; CHECK-NEXT: lsl w9, w9, w8549; CHECK-NEXT: lsr w0, w9, w8550; CHECK-NEXT: ret551 %val = load i32, ptr %w552 %numhighbits = sub i8 32, %numlowbits553 %sh_prom = zext i8 %numhighbits to i32554 %highbitscleared = shl i32 %val, %sh_prom555 %masked = lshr i32 %highbitscleared, %sh_prom556 ret i32 %masked557}558 559; 64-bit.560 561define i64 @bzhi64_d0(i64 %val, i64 %numlowbits) nounwind {562; CHECK-LABEL: bzhi64_d0:563; CHECK: // %bb.0:564; CHECK-NEXT: neg x8, x1565; CHECK-NEXT: lsl x9, x0, x8566; CHECK-NEXT: lsr x0, x9, x8567; CHECK-NEXT: ret568 %numhighbits = sub i64 64, %numlowbits569 %highbitscleared = shl i64 %val, %numhighbits570 %masked = lshr i64 %highbitscleared, %numhighbits571 ret i64 %masked572}573 574define i64 @bzhi64_d1_indexzext(i64 %val, i8 %numlowbits) nounwind {575; CHECK-LABEL: bzhi64_d1_indexzext:576; CHECK: // %bb.0:577; CHECK-NEXT: mov w8, #64 // =0x40578; CHECK-NEXT: sub w8, w8, w1579; CHECK-NEXT: lsl x9, x0, x8580; CHECK-NEXT: lsr x0, x9, x8581; CHECK-NEXT: ret582 %numhighbits = sub i8 64, %numlowbits583 %sh_prom = zext i8 %numhighbits to i64584 %highbitscleared = shl i64 %val, %sh_prom585 %masked = lshr i64 %highbitscleared, %sh_prom586 ret i64 %masked587}588 589define i64 @bzhi64_d2_load(ptr %w, i64 %numlowbits) nounwind {590; CHECK-LABEL: bzhi64_d2_load:591; CHECK: // %bb.0:592; CHECK-NEXT: ldr x8, [x0]593; CHECK-NEXT: neg x9, x1594; CHECK-NEXT: lsl x8, x8, x9595; CHECK-NEXT: lsr x0, x8, x9596; CHECK-NEXT: ret597 %val = load i64, ptr %w598 %numhighbits = sub i64 64, %numlowbits599 %highbitscleared = shl i64 %val, %numhighbits600 %masked = lshr i64 %highbitscleared, %numhighbits601 ret i64 %masked602}603 604define i64 @bzhi64_d3_load_indexzext(ptr %w, i8 %numlowbits) nounwind {605; CHECK-LABEL: bzhi64_d3_load_indexzext:606; CHECK: // %bb.0:607; CHECK-NEXT: mov w8, #64 // =0x40608; CHECK-NEXT: ldr x9, [x0]609; CHECK-NEXT: sub w8, w8, w1610; CHECK-NEXT: lsl x9, x9, x8611; CHECK-NEXT: lsr x0, x9, x8612; CHECK-NEXT: ret613 %val = load i64, ptr %w614 %numhighbits = sub i8 64, %numlowbits615 %sh_prom = zext i8 %numhighbits to i64616 %highbitscleared = shl i64 %val, %sh_prom617 %masked = lshr i64 %highbitscleared, %sh_prom618 ret i64 %masked619}620 621; ---------------------------------------------------------------------------- ;622; Constant mask623; ---------------------------------------------------------------------------- ;624 625; 32-bit626 627define i32 @bzhi32_constant_mask32(i32 %val) nounwind {628; CHECK-LABEL: bzhi32_constant_mask32:629; CHECK: // %bb.0:630; CHECK-NEXT: and w0, w0, #0x7fffffff631; CHECK-NEXT: ret632 %masked = and i32 %val, 2147483647633 ret i32 %masked634}635 636define i32 @bzhi32_constant_mask32_load(ptr %val) nounwind {637; CHECK-LABEL: bzhi32_constant_mask32_load:638; CHECK: // %bb.0:639; CHECK-NEXT: ldr w8, [x0]640; CHECK-NEXT: and w0, w8, #0x7fffffff641; CHECK-NEXT: ret642 %val1 = load i32, ptr %val643 %masked = and i32 %val1, 2147483647644 ret i32 %masked645}646 647define i32 @bzhi32_constant_mask16(i32 %val) nounwind {648; CHECK-LABEL: bzhi32_constant_mask16:649; CHECK: // %bb.0:650; CHECK-NEXT: and w0, w0, #0x7fff651; CHECK-NEXT: ret652 %masked = and i32 %val, 32767653 ret i32 %masked654}655 656define i32 @bzhi32_constant_mask16_load(ptr %val) nounwind {657; CHECK-LABEL: bzhi32_constant_mask16_load:658; CHECK: // %bb.0:659; CHECK-NEXT: ldr w8, [x0]660; CHECK-NEXT: and w0, w8, #0x7fff661; CHECK-NEXT: ret662 %val1 = load i32, ptr %val663 %masked = and i32 %val1, 32767664 ret i32 %masked665}666 667define i32 @bzhi32_constant_mask8(i32 %val) nounwind {668; CHECK-LABEL: bzhi32_constant_mask8:669; CHECK: // %bb.0:670; CHECK-NEXT: and w0, w0, #0x7f671; CHECK-NEXT: ret672 %masked = and i32 %val, 127673 ret i32 %masked674}675 676define i32 @bzhi32_constant_mask8_load(ptr %val) nounwind {677; CHECK-LABEL: bzhi32_constant_mask8_load:678; CHECK: // %bb.0:679; CHECK-NEXT: ldr w8, [x0]680; CHECK-NEXT: and w0, w8, #0x7f681; CHECK-NEXT: ret682 %val1 = load i32, ptr %val683 %masked = and i32 %val1, 127684 ret i32 %masked685}686 687; 64-bit688 689define i64 @bzhi64_constant_mask64(i64 %val) nounwind {690; CHECK-LABEL: bzhi64_constant_mask64:691; CHECK: // %bb.0:692; CHECK-NEXT: and x0, x0, #0x3fffffffffffffff693; CHECK-NEXT: ret694 %masked = and i64 %val, 4611686018427387903695 ret i64 %masked696}697 698define i64 @bzhi64_constant_mask64_load(ptr %val) nounwind {699; CHECK-LABEL: bzhi64_constant_mask64_load:700; CHECK: // %bb.0:701; CHECK-NEXT: ldr x8, [x0]702; CHECK-NEXT: and x0, x8, #0x3fffffffffffffff703; CHECK-NEXT: ret704 %val1 = load i64, ptr %val705 %masked = and i64 %val1, 4611686018427387903706 ret i64 %masked707}708 709define i64 @bzhi64_constant_mask32(i64 %val) nounwind {710; CHECK-LABEL: bzhi64_constant_mask32:711; CHECK: // %bb.0:712; CHECK-NEXT: and x0, x0, #0x7fffffff713; CHECK-NEXT: ret714 %masked = and i64 %val, 2147483647715 ret i64 %masked716}717 718define i64 @bzhi64_constant_mask32_load(ptr %val) nounwind {719; CHECK-LABEL: bzhi64_constant_mask32_load:720; CHECK: // %bb.0:721; CHECK-NEXT: ldr x8, [x0]722; CHECK-NEXT: and x0, x8, #0x7fffffff723; CHECK-NEXT: ret724 %val1 = load i64, ptr %val725 %masked = and i64 %val1, 2147483647726 ret i64 %masked727}728 729define i64 @bzhi64_constant_mask16(i64 %val) nounwind {730; CHECK-LABEL: bzhi64_constant_mask16:731; CHECK: // %bb.0:732; CHECK-NEXT: and x0, x0, #0x7fff733; CHECK-NEXT: ret734 %masked = and i64 %val, 32767735 ret i64 %masked736}737 738define i64 @bzhi64_constant_mask16_load(ptr %val) nounwind {739; CHECK-LABEL: bzhi64_constant_mask16_load:740; CHECK: // %bb.0:741; CHECK-NEXT: ldr x8, [x0]742; CHECK-NEXT: and x0, x8, #0x7fff743; CHECK-NEXT: ret744 %val1 = load i64, ptr %val745 %masked = and i64 %val1, 32767746 ret i64 %masked747}748 749define i64 @bzhi64_constant_mask8(i64 %val) nounwind {750; CHECK-LABEL: bzhi64_constant_mask8:751; CHECK: // %bb.0:752; CHECK-NEXT: and x0, x0, #0x7f753; CHECK-NEXT: ret754 %masked = and i64 %val, 127755 ret i64 %masked756}757 758define i64 @bzhi64_constant_mask8_load(ptr %val) nounwind {759; CHECK-LABEL: bzhi64_constant_mask8_load:760; CHECK: // %bb.0:761; CHECK-NEXT: ldr x8, [x0]762; CHECK-NEXT: and x0, x8, #0x7f763; CHECK-NEXT: ret764 %val1 = load i64, ptr %val765 %masked = and i64 %val1, 127766 ret i64 %masked767}768