brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.6 KiB · 5a96116 Raw
1158 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-bits.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 >> start) &  (1 << nbits) - 112;   b) (x >> start) & ~(-1 << nbits)13;   c) (x >> start) &  (-1 >> (32 - y))14;   d) (x >> start) << (32 - y) >> (32 - y)15; are equivalent.16 17; ---------------------------------------------------------------------------- ;18; Pattern a. 32-bit19; ---------------------------------------------------------------------------- ;20 21define i32 @bextr32_a0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {22; CHECK-LABEL: bextr32_a0:23; CHECK:       // %bb.0:24; CHECK-NEXT:    mov w8, #1 // =0x125; CHECK-NEXT:    lsr w9, w0, w126; CHECK-NEXT:    lsl w8, w8, w227; CHECK-NEXT:    sub w8, w8, #128; CHECK-NEXT:    and w0, w8, w929; CHECK-NEXT:    ret30  %shifted = lshr i32 %val, %numskipbits31  %onebit = shl i32 1, %numlowbits32  %mask = add nsw i32 %onebit, -133  %masked = and i32 %mask, %shifted34  ret i32 %masked35}36 37define i32 @bextr32_a0_arithmetic(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {38; CHECK-LABEL: bextr32_a0_arithmetic:39; CHECK:       // %bb.0:40; CHECK-NEXT:    mov w8, #1 // =0x141; CHECK-NEXT:    asr w9, w0, w142; CHECK-NEXT:    lsl w8, w8, w243; CHECK-NEXT:    sub w8, w8, #144; CHECK-NEXT:    and w0, w8, w945; CHECK-NEXT:    ret46  %shifted = ashr i32 %val, %numskipbits47  %onebit = shl i32 1, %numlowbits48  %mask = add nsw i32 %onebit, -149  %masked = and i32 %mask, %shifted50  ret i32 %masked51}52 53define i32 @bextr32_a1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {54; CHECK-LABEL: bextr32_a1_indexzext:55; CHECK:       // %bb.0:56; CHECK-NEXT:    mov w8, #1 // =0x157; CHECK-NEXT:    lsr w9, w0, w158; CHECK-NEXT:    lsl w8, w8, w259; CHECK-NEXT:    sub w8, w8, #160; CHECK-NEXT:    and w0, w8, w961; CHECK-NEXT:    ret62  %skip = zext i8 %numskipbits to i3263  %shifted = lshr i32 %val, %skip64  %conv = zext i8 %numlowbits to i3265  %onebit = shl i32 1, %conv66  %mask = add nsw i32 %onebit, -167  %masked = and i32 %mask, %shifted68  ret i32 %masked69}70 71define i32 @bextr32_a2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {72; CHECK-LABEL: bextr32_a2_load:73; CHECK:       // %bb.0:74; CHECK-NEXT:    ldr w8, [x0]75; CHECK-NEXT:    mov w9, #1 // =0x176; CHECK-NEXT:    lsl w9, w9, w277; CHECK-NEXT:    lsr w8, w8, w178; CHECK-NEXT:    sub w9, w9, #179; CHECK-NEXT:    and w0, w9, w880; CHECK-NEXT:    ret81  %val = load i32, ptr %w82  %shifted = lshr i32 %val, %numskipbits83  %onebit = shl i32 1, %numlowbits84  %mask = add nsw i32 %onebit, -185  %masked = and i32 %mask, %shifted86  ret i32 %masked87}88 89define i32 @bextr32_a3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {90; CHECK-LABEL: bextr32_a3_load_indexzext:91; CHECK:       // %bb.0:92; CHECK-NEXT:    ldr w8, [x0]93; CHECK-NEXT:    mov w9, #1 // =0x194; CHECK-NEXT:    lsl w9, w9, w295; CHECK-NEXT:    lsr w8, w8, w196; CHECK-NEXT:    sub w9, w9, #197; CHECK-NEXT:    and w0, w9, w898; CHECK-NEXT:    ret99  %val = load i32, ptr %w100  %skip = zext i8 %numskipbits to i32101  %shifted = lshr i32 %val, %skip102  %conv = zext i8 %numlowbits to i32103  %onebit = shl i32 1, %conv104  %mask = add nsw i32 %onebit, -1105  %masked = and i32 %mask, %shifted106  ret i32 %masked107}108 109define i32 @bextr32_a4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {110; CHECK-LABEL: bextr32_a4_commutative:111; CHECK:       // %bb.0:112; CHECK-NEXT:    mov w8, #1 // =0x1113; CHECK-NEXT:    lsr w9, w0, w1114; CHECK-NEXT:    lsl w8, w8, w2115; CHECK-NEXT:    sub w8, w8, #1116; CHECK-NEXT:    and w0, w9, w8117; CHECK-NEXT:    ret118  %shifted = lshr i32 %val, %numskipbits119  %onebit = shl i32 1, %numlowbits120  %mask = add nsw i32 %onebit, -1121  %masked = and i32 %shifted, %mask ; swapped order122  ret i32 %masked123}124 125; 64-bit126 127define i64 @bextr64_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {128; CHECK-LABEL: bextr64_a0:129; CHECK:       // %bb.0:130; CHECK-NEXT:    mov w8, #1 // =0x1131; CHECK-NEXT:    lsr x9, x0, x1132; CHECK-NEXT:    lsl x8, x8, x2133; CHECK-NEXT:    sub x8, x8, #1134; CHECK-NEXT:    and x0, x8, x9135; CHECK-NEXT:    ret136  %shifted = lshr i64 %val, %numskipbits137  %onebit = shl i64 1, %numlowbits138  %mask = add nsw i64 %onebit, -1139  %masked = and i64 %mask, %shifted140  ret i64 %masked141}142 143define i64 @bextr64_a0_arithmetic(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {144; CHECK-LABEL: bextr64_a0_arithmetic:145; CHECK:       // %bb.0:146; CHECK-NEXT:    mov w8, #1 // =0x1147; CHECK-NEXT:    asr x9, x0, x1148; CHECK-NEXT:    lsl x8, x8, x2149; CHECK-NEXT:    sub x8, x8, #1150; CHECK-NEXT:    and x0, x8, x9151; CHECK-NEXT:    ret152  %shifted = ashr i64 %val, %numskipbits153  %onebit = shl i64 1, %numlowbits154  %mask = add nsw i64 %onebit, -1155  %masked = and i64 %mask, %shifted156  ret i64 %masked157}158 159define i64 @bextr64_a1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {160; CHECK-LABEL: bextr64_a1_indexzext:161; CHECK:       // %bb.0:162; CHECK-NEXT:    mov w8, #1 // =0x1163; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2164; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1165; CHECK-NEXT:    lsr x9, x0, x1166; CHECK-NEXT:    lsl x8, x8, x2167; CHECK-NEXT:    sub x8, x8, #1168; CHECK-NEXT:    and x0, x8, x9169; CHECK-NEXT:    ret170  %skip = zext i8 %numskipbits to i64171  %shifted = lshr i64 %val, %skip172  %conv = zext i8 %numlowbits to i64173  %onebit = shl i64 1, %conv174  %mask = add nsw i64 %onebit, -1175  %masked = and i64 %mask, %shifted176  ret i64 %masked177}178 179define i64 @bextr64_a2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {180; CHECK-LABEL: bextr64_a2_load:181; CHECK:       // %bb.0:182; CHECK-NEXT:    ldr x8, [x0]183; CHECK-NEXT:    mov w9, #1 // =0x1184; CHECK-NEXT:    lsl x9, x9, x2185; CHECK-NEXT:    lsr x8, x8, x1186; CHECK-NEXT:    sub x9, x9, #1187; CHECK-NEXT:    and x0, x9, x8188; CHECK-NEXT:    ret189  %val = load i64, ptr %w190  %shifted = lshr i64 %val, %numskipbits191  %onebit = shl i64 1, %numlowbits192  %mask = add nsw i64 %onebit, -1193  %masked = and i64 %mask, %shifted194  ret i64 %masked195}196 197define i64 @bextr64_a3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {198; CHECK-LABEL: bextr64_a3_load_indexzext:199; CHECK:       // %bb.0:200; CHECK-NEXT:    ldr x8, [x0]201; CHECK-NEXT:    mov w9, #1 // =0x1202; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2203; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1204; CHECK-NEXT:    lsl x9, x9, x2205; CHECK-NEXT:    lsr x8, x8, x1206; CHECK-NEXT:    sub x9, x9, #1207; CHECK-NEXT:    and x0, x9, x8208; CHECK-NEXT:    ret209  %val = load i64, ptr %w210  %skip = zext i8 %numskipbits to i64211  %shifted = lshr i64 %val, %skip212  %conv = zext i8 %numlowbits to i64213  %onebit = shl i64 1, %conv214  %mask = add nsw i64 %onebit, -1215  %masked = and i64 %mask, %shifted216  ret i64 %masked217}218 219define i64 @bextr64_a4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {220; CHECK-LABEL: bextr64_a4_commutative:221; CHECK:       // %bb.0:222; CHECK-NEXT:    mov w8, #1 // =0x1223; CHECK-NEXT:    lsr x9, x0, x1224; CHECK-NEXT:    lsl x8, x8, x2225; CHECK-NEXT:    sub x8, x8, #1226; CHECK-NEXT:    and x0, x9, x8227; CHECK-NEXT:    ret228  %shifted = lshr i64 %val, %numskipbits229  %onebit = shl i64 1, %numlowbits230  %mask = add nsw i64 %onebit, -1231  %masked = and i64 %shifted, %mask ; swapped order232  ret i64 %masked233}234 235; 64-bit, but with 32-bit output236 237; Everything done in 64-bit, truncation happens last.238define i32 @bextr64_32_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {239; CHECK-LABEL: bextr64_32_a0:240; CHECK:       // %bb.0:241; CHECK-NEXT:    mov w8, #1 // =0x1242; CHECK-NEXT:    lsr x9, x0, x1243; CHECK-NEXT:    lsl x8, x8, x2244; CHECK-NEXT:    sub w8, w8, #1245; CHECK-NEXT:    and w0, w8, w9246; CHECK-NEXT:    ret247  %shifted = lshr i64 %val, %numskipbits248  %onebit = shl i64 1, %numlowbits249  %mask = add nsw i64 %onebit, -1250  %masked = and i64 %mask, %shifted251  %res = trunc i64 %masked to i32252  ret i32 %res253}254 255; Shifting happens in 64-bit, then truncation. Masking is 32-bit.256define i32 @bextr64_32_a1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {257; CHECK-LABEL: bextr64_32_a1:258; CHECK:       // %bb.0:259; CHECK-NEXT:    mov w8, #1 // =0x1260; CHECK-NEXT:    lsr x9, x0, x1261; CHECK-NEXT:    lsl w8, w8, w2262; CHECK-NEXT:    sub w8, w8, #1263; CHECK-NEXT:    and w0, w8, w9264; CHECK-NEXT:    ret265  %shifted = lshr i64 %val, %numskipbits266  %truncshifted = trunc i64 %shifted to i32267  %onebit = shl i32 1, %numlowbits268  %mask = add nsw i32 %onebit, -1269  %masked = and i32 %mask, %truncshifted270  ret i32 %masked271}272 273; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.274; Masking is 64-bit. Then truncation.275define i32 @bextr64_32_a2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {276; CHECK-LABEL: bextr64_32_a2:277; CHECK:       // %bb.0:278; CHECK-NEXT:    mov w8, #1 // =0x1279; CHECK-NEXT:    lsr x9, x0, x1280; CHECK-NEXT:    lsl w8, w8, w2281; CHECK-NEXT:    sub w8, w8, #1282; CHECK-NEXT:    and w0, w8, w9283; CHECK-NEXT:    ret284  %shifted = lshr i64 %val, %numskipbits285  %onebit = shl i32 1, %numlowbits286  %mask = add nsw i32 %onebit, -1287  %zextmask = zext i32 %mask to i64288  %masked = and i64 %zextmask, %shifted289  %truncmasked = trunc i64 %masked to i32290  ret i32 %truncmasked291}292 293; ---------------------------------------------------------------------------- ;294; Pattern b. 32-bit295; ---------------------------------------------------------------------------- ;296 297define i32 @bextr32_b0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {298; CHECK-LABEL: bextr32_b0:299; CHECK:       // %bb.0:300; CHECK-NEXT:    mov w8, #-1 // =0xffffffff301; CHECK-NEXT:    lsr w9, w0, w1302; CHECK-NEXT:    lsl w8, w8, w2303; CHECK-NEXT:    bic w0, w9, w8304; CHECK-NEXT:    ret305  %shifted = lshr i32 %val, %numskipbits306  %notmask = shl i32 -1, %numlowbits307  %mask = xor i32 %notmask, -1308  %masked = and i32 %mask, %shifted309  ret i32 %masked310}311 312define i32 @bextr32_b1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {313; CHECK-LABEL: bextr32_b1_indexzext:314; CHECK:       // %bb.0:315; CHECK-NEXT:    mov w8, #-1 // =0xffffffff316; CHECK-NEXT:    lsr w9, w0, w1317; CHECK-NEXT:    lsl w8, w8, w2318; CHECK-NEXT:    bic w0, w9, w8319; CHECK-NEXT:    ret320  %skip = zext i8 %numskipbits to i32321  %shifted = lshr i32 %val, %skip322  %conv = zext i8 %numlowbits to i32323  %notmask = shl i32 -1, %conv324  %mask = xor i32 %notmask, -1325  %masked = and i32 %mask, %shifted326  ret i32 %masked327}328 329define i32 @bextr32_b2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {330; CHECK-LABEL: bextr32_b2_load:331; CHECK:       // %bb.0:332; CHECK-NEXT:    ldr w8, [x0]333; CHECK-NEXT:    mov w9, #-1 // =0xffffffff334; CHECK-NEXT:    lsl w9, w9, w2335; CHECK-NEXT:    lsr w8, w8, w1336; CHECK-NEXT:    bic w0, w8, w9337; CHECK-NEXT:    ret338  %val = load i32, ptr %w339  %shifted = lshr i32 %val, %numskipbits340  %notmask = shl i32 -1, %numlowbits341  %mask = xor i32 %notmask, -1342  %masked = and i32 %mask, %shifted343  ret i32 %masked344}345 346define i32 @bextr32_b3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {347; CHECK-LABEL: bextr32_b3_load_indexzext:348; CHECK:       // %bb.0:349; CHECK-NEXT:    ldr w8, [x0]350; CHECK-NEXT:    mov w9, #-1 // =0xffffffff351; CHECK-NEXT:    lsl w9, w9, w2352; CHECK-NEXT:    lsr w8, w8, w1353; CHECK-NEXT:    bic w0, w8, w9354; CHECK-NEXT:    ret355  %val = load i32, ptr %w356  %skip = zext i8 %numskipbits to i32357  %shifted = lshr i32 %val, %skip358  %conv = zext i8 %numlowbits to i32359  %notmask = shl i32 -1, %conv360  %mask = xor i32 %notmask, -1361  %masked = and i32 %mask, %shifted362  ret i32 %masked363}364 365define i32 @bextr32_b4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {366; CHECK-LABEL: bextr32_b4_commutative:367; CHECK:       // %bb.0:368; CHECK-NEXT:    mov w8, #-1 // =0xffffffff369; CHECK-NEXT:    lsr w9, w0, w1370; CHECK-NEXT:    lsl w8, w8, w2371; CHECK-NEXT:    bic w0, w9, w8372; CHECK-NEXT:    ret373  %shifted = lshr i32 %val, %numskipbits374  %notmask = shl i32 -1, %numlowbits375  %mask = xor i32 %notmask, -1376  %masked = and i32 %shifted, %mask ; swapped order377  ret i32 %masked378}379 380; 64-bit381 382define i64 @bextr64_b0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {383; CHECK-LABEL: bextr64_b0:384; CHECK:       // %bb.0:385; CHECK-NEXT:    mov x8, #-1 // =0xffffffffffffffff386; CHECK-NEXT:    lsr x9, x0, x1387; CHECK-NEXT:    lsl x8, x8, x2388; CHECK-NEXT:    bic x0, x9, x8389; CHECK-NEXT:    ret390  %shifted = lshr i64 %val, %numskipbits391  %notmask = shl i64 -1, %numlowbits392  %mask = xor i64 %notmask, -1393  %masked = and i64 %mask, %shifted394  ret i64 %masked395}396 397define i64 @bextr64_b1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {398; CHECK-LABEL: bextr64_b1_indexzext:399; CHECK:       // %bb.0:400; CHECK-NEXT:    mov x8, #-1 // =0xffffffffffffffff401; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2402; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1403; CHECK-NEXT:    lsr x9, x0, x1404; CHECK-NEXT:    lsl x8, x8, x2405; CHECK-NEXT:    bic x0, x9, x8406; CHECK-NEXT:    ret407  %skip = zext i8 %numskipbits to i64408  %shifted = lshr i64 %val, %skip409  %conv = zext i8 %numlowbits to i64410  %notmask = shl i64 -1, %conv411  %mask = xor i64 %notmask, -1412  %masked = and i64 %mask, %shifted413  ret i64 %masked414}415 416define i64 @bextr64_b2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {417; CHECK-LABEL: bextr64_b2_load:418; CHECK:       // %bb.0:419; CHECK-NEXT:    ldr x8, [x0]420; CHECK-NEXT:    mov x9, #-1 // =0xffffffffffffffff421; CHECK-NEXT:    lsl x9, x9, x2422; CHECK-NEXT:    lsr x8, x8, x1423; CHECK-NEXT:    bic x0, x8, x9424; CHECK-NEXT:    ret425  %val = load i64, ptr %w426  %shifted = lshr i64 %val, %numskipbits427  %notmask = shl i64 -1, %numlowbits428  %mask = xor i64 %notmask, -1429  %masked = and i64 %mask, %shifted430  ret i64 %masked431}432 433define i64 @bextr64_b3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind {434; CHECK-LABEL: bextr64_b3_load_indexzext:435; CHECK:       // %bb.0:436; CHECK-NEXT:    ldr x8, [x0]437; CHECK-NEXT:    mov x9, #-1 // =0xffffffffffffffff438; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2439; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1440; CHECK-NEXT:    lsl x9, x9, x2441; CHECK-NEXT:    lsr x8, x8, x1442; CHECK-NEXT:    bic x0, x8, x9443; CHECK-NEXT:    ret444  %val = load i64, ptr %w445  %skip = zext i8 %numskipbits to i64446  %shifted = lshr i64 %val, %skip447  %conv = zext i8 %numlowbits to i64448  %notmask = shl i64 -1, %conv449  %mask = xor i64 %notmask, -1450  %masked = and i64 %mask, %shifted451  ret i64 %masked452}453 454define i64 @bextr64_b4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {455; CHECK-LABEL: bextr64_b4_commutative:456; CHECK:       // %bb.0:457; CHECK-NEXT:    mov x8, #-1 // =0xffffffffffffffff458; CHECK-NEXT:    lsr x9, x0, x1459; CHECK-NEXT:    lsl x8, x8, x2460; CHECK-NEXT:    bic x0, x9, x8461; CHECK-NEXT:    ret462  %shifted = lshr i64 %val, %numskipbits463  %notmask = shl i64 -1, %numlowbits464  %mask = xor i64 %notmask, -1465  %masked = and i64 %shifted, %mask ; swapped order466  ret i64 %masked467}468 469; 64-bit, but with 32-bit output470 471; Everything done in 64-bit, truncation happens last.472define i32 @bextr64_32_b0(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {473; CHECK-LABEL: bextr64_32_b0:474; CHECK:       // %bb.0:475; CHECK-NEXT:    mov x8, #-1 // =0xffffffffffffffff476; CHECK-NEXT:    // kill: def $w2 killed $w2 def $x2477; CHECK-NEXT:    lsr x9, x0, x1478; CHECK-NEXT:    lsl x8, x8, x2479; CHECK-NEXT:    bic w0, w9, w8480; CHECK-NEXT:    ret481  %shiftedval = lshr i64 %val, %numskipbits482  %widenumlowbits = zext i8 %numlowbits to i64483  %notmask = shl nsw i64 -1, %widenumlowbits484  %mask = xor i64 %notmask, -1485  %wideres = and i64 %shiftedval, %mask486  %res = trunc i64 %wideres to i32487  ret i32 %res488}489 490; Shifting happens in 64-bit, then truncation. Masking is 32-bit.491define i32 @bextr64_32_b1(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {492; CHECK-LABEL: bextr64_32_b1:493; CHECK:       // %bb.0:494; CHECK-NEXT:    mov w8, #-1 // =0xffffffff495; CHECK-NEXT:    lsr x9, x0, x1496; CHECK-NEXT:    lsl w8, w8, w2497; CHECK-NEXT:    bic w0, w9, w8498; CHECK-NEXT:    ret499  %shiftedval = lshr i64 %val, %numskipbits500  %truncshiftedval = trunc i64 %shiftedval to i32501  %widenumlowbits = zext i8 %numlowbits to i32502  %notmask = shl nsw i32 -1, %widenumlowbits503  %mask = xor i32 %notmask, -1504  %res = and i32 %truncshiftedval, %mask505  ret i32 %res506}507 508; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.509; Masking is 64-bit. Then truncation.510define i32 @bextr64_32_b2(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind {511; CHECK-LABEL: bextr64_32_b2:512; CHECK:       // %bb.0:513; CHECK-NEXT:    mov w8, #-1 // =0xffffffff514; CHECK-NEXT:    lsr x9, x0, x1515; CHECK-NEXT:    lsl w8, w8, w2516; CHECK-NEXT:    bic w0, w9, w8517; CHECK-NEXT:    ret518  %shiftedval = lshr i64 %val, %numskipbits519  %widenumlowbits = zext i8 %numlowbits to i32520  %notmask = shl nsw i32 -1, %widenumlowbits521  %mask = xor i32 %notmask, -1522  %zextmask = zext i32 %mask to i64523  %wideres = and i64 %shiftedval, %zextmask524  %res = trunc i64 %wideres to i32525  ret i32 %res526}527 528; ---------------------------------------------------------------------------- ;529; Pattern c. 32-bit530; ---------------------------------------------------------------------------- ;531 532define i32 @bextr32_c0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {533; CHECK-LABEL: bextr32_c0:534; CHECK:       // %bb.0:535; CHECK-NEXT:    lsr w8, w0, w1536; CHECK-NEXT:    neg w9, w2537; CHECK-NEXT:    lsl w8, w8, w9538; CHECK-NEXT:    lsr w0, w8, w9539; CHECK-NEXT:    ret540  %shifted = lshr i32 %val, %numskipbits541  %numhighbits = sub i32 32, %numlowbits542  %mask = lshr i32 -1, %numhighbits543  %masked = and i32 %mask, %shifted544  ret i32 %masked545}546 547define i32 @bextr32_c1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {548; CHECK-LABEL: bextr32_c1_indexzext:549; CHECK:       // %bb.0:550; CHECK-NEXT:    lsr w8, w0, w1551; CHECK-NEXT:    mov w9, #32 // =0x20552; CHECK-NEXT:    sub w9, w9, w2553; CHECK-NEXT:    lsl w8, w8, w9554; CHECK-NEXT:    lsr w0, w8, w9555; CHECK-NEXT:    ret556  %skip = zext i8 %numskipbits to i32557  %shifted = lshr i32 %val, %skip558  %numhighbits = sub i8 32, %numlowbits559  %sh_prom = zext i8 %numhighbits to i32560  %mask = lshr i32 -1, %sh_prom561  %masked = and i32 %mask, %shifted562  ret i32 %masked563}564 565define i32 @bextr32_c2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {566; CHECK-LABEL: bextr32_c2_load:567; CHECK:       // %bb.0:568; CHECK-NEXT:    ldr w8, [x0]569; CHECK-NEXT:    neg w9, w2570; CHECK-NEXT:    lsr w8, w8, w1571; CHECK-NEXT:    lsl w8, w8, w9572; CHECK-NEXT:    lsr w0, w8, w9573; CHECK-NEXT:    ret574  %val = load i32, ptr %w575  %shifted = lshr i32 %val, %numskipbits576  %numhighbits = sub i32 32, %numlowbits577  %mask = lshr i32 -1, %numhighbits578  %masked = and i32 %mask, %shifted579  ret i32 %masked580}581 582define i32 @bextr32_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {583; CHECK-LABEL: bextr32_c3_load_indexzext:584; CHECK:       // %bb.0:585; CHECK-NEXT:    ldr w8, [x0]586; CHECK-NEXT:    mov w9, #32 // =0x20587; CHECK-NEXT:    sub w9, w9, w2588; CHECK-NEXT:    lsr w8, w8, w1589; CHECK-NEXT:    lsl w8, w8, w9590; CHECK-NEXT:    lsr w0, w8, w9591; CHECK-NEXT:    ret592  %val = load i32, ptr %w593  %skip = zext i8 %numskipbits to i32594  %shifted = lshr i32 %val, %skip595  %numhighbits = sub i8 32, %numlowbits596  %sh_prom = zext i8 %numhighbits to i32597  %mask = lshr i32 -1, %sh_prom598  %masked = and i32 %mask, %shifted599  ret i32 %masked600}601 602define i32 @bextr32_c4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {603; CHECK-LABEL: bextr32_c4_commutative:604; CHECK:       // %bb.0:605; CHECK-NEXT:    lsr w8, w0, w1606; CHECK-NEXT:    neg w9, w2607; CHECK-NEXT:    lsl w8, w8, w9608; CHECK-NEXT:    lsr w0, w8, w9609; CHECK-NEXT:    ret610  %shifted = lshr i32 %val, %numskipbits611  %numhighbits = sub i32 32, %numlowbits612  %mask = lshr i32 -1, %numhighbits613  %masked = and i32 %shifted, %mask ; swapped order614  ret i32 %masked615}616 617; 64-bit618 619define i64 @bextr64_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {620; CHECK-LABEL: bextr64_c0:621; CHECK:       // %bb.0:622; CHECK-NEXT:    lsr x8, x0, x1623; CHECK-NEXT:    neg x9, x2624; CHECK-NEXT:    lsl x8, x8, x9625; CHECK-NEXT:    lsr x0, x8, x9626; CHECK-NEXT:    ret627  %shifted = lshr i64 %val, %numskipbits628  %numhighbits = sub i64 64, %numlowbits629  %mask = lshr i64 -1, %numhighbits630  %masked = and i64 %mask, %shifted631  ret i64 %masked632}633 634define i64 @bextr64_c1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {635; CHECK-LABEL: bextr64_c1_indexzext:636; CHECK:       // %bb.0:637; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1638; CHECK-NEXT:    lsr x8, x0, x1639; CHECK-NEXT:    mov w9, #64 // =0x40640; CHECK-NEXT:    sub w9, w9, w2641; CHECK-NEXT:    lsl x8, x8, x9642; CHECK-NEXT:    lsr x0, x8, x9643; CHECK-NEXT:    ret644  %skip = zext i8 %numskipbits to i64645  %shifted = lshr i64 %val, %skip646  %numhighbits = sub i8 64, %numlowbits647  %sh_prom = zext i8 %numhighbits to i64648  %mask = lshr i64 -1, %sh_prom649  %masked = and i64 %mask, %shifted650  ret i64 %masked651}652 653define i64 @bextr64_c2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {654; CHECK-LABEL: bextr64_c2_load:655; CHECK:       // %bb.0:656; CHECK-NEXT:    ldr x8, [x0]657; CHECK-NEXT:    neg x9, x2658; CHECK-NEXT:    lsr x8, x8, x1659; CHECK-NEXT:    lsl x8, x8, x9660; CHECK-NEXT:    lsr x0, x8, x9661; CHECK-NEXT:    ret662  %val = load i64, ptr %w663  %shifted = lshr i64 %val, %numskipbits664  %numhighbits = sub i64 64, %numlowbits665  %mask = lshr i64 -1, %numhighbits666  %masked = and i64 %mask, %shifted667  ret i64 %masked668}669 670define i64 @bextr64_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {671; CHECK-LABEL: bextr64_c3_load_indexzext:672; CHECK:       // %bb.0:673; CHECK-NEXT:    ldr x8, [x0]674; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1675; CHECK-NEXT:    mov w9, #64 // =0x40676; CHECK-NEXT:    sub w9, w9, w2677; CHECK-NEXT:    lsr x8, x8, x1678; CHECK-NEXT:    lsl x8, x8, x9679; CHECK-NEXT:    lsr x0, x8, x9680; CHECK-NEXT:    ret681  %val = load i64, ptr %w682  %skip = zext i8 %numskipbits to i64683  %shifted = lshr i64 %val, %skip684  %numhighbits = sub i8 64, %numlowbits685  %sh_prom = zext i8 %numhighbits to i64686  %mask = lshr i64 -1, %sh_prom687  %masked = and i64 %mask, %shifted688  ret i64 %masked689}690 691define i64 @bextr64_c4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {692; CHECK-LABEL: bextr64_c4_commutative:693; CHECK:       // %bb.0:694; CHECK-NEXT:    lsr x8, x0, x1695; CHECK-NEXT:    neg x9, x2696; CHECK-NEXT:    lsl x8, x8, x9697; CHECK-NEXT:    lsr x0, x8, x9698; CHECK-NEXT:    ret699  %shifted = lshr i64 %val, %numskipbits700  %numhighbits = sub i64 64, %numlowbits701  %mask = lshr i64 -1, %numhighbits702  %masked = and i64 %shifted, %mask ; swapped order703  ret i64 %masked704}705 706; 64-bit, but with 32-bit output707 708; Everything done in 64-bit, truncation happens last.709define i32 @bextr64_32_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {710; CHECK-LABEL: bextr64_32_c0:711; CHECK:       // %bb.0:712; CHECK-NEXT:    neg x8, x2713; CHECK-NEXT:    mov x9, #-1 // =0xffffffffffffffff714; CHECK-NEXT:    lsr x10, x0, x1715; CHECK-NEXT:    lsr x8, x9, x8716; CHECK-NEXT:    and w0, w8, w10717; CHECK-NEXT:    ret718  %shifted = lshr i64 %val, %numskipbits719  %numhighbits = sub i64 64, %numlowbits720  %mask = lshr i64 -1, %numhighbits721  %masked = and i64 %mask, %shifted722  %res = trunc i64 %masked to i32723  ret i32 %res724}725 726; Shifting happens in 64-bit, then truncation. Masking is 32-bit.727define i32 @bextr64_32_c1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {728; CHECK-LABEL: bextr64_32_c1:729; CHECK:       // %bb.0:730; CHECK-NEXT:    lsr x8, x0, x1731; CHECK-NEXT:    neg w9, w2732; CHECK-NEXT:    lsl w8, w8, w9733; CHECK-NEXT:    lsr w0, w8, w9734; CHECK-NEXT:    ret735  %shifted = lshr i64 %val, %numskipbits736  %truncshifted = trunc i64 %shifted to i32737  %numhighbits = sub i32 32, %numlowbits738  %mask = lshr i32 -1, %numhighbits739  %masked = and i32 %mask, %truncshifted740  ret i32 %masked741}742 743; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit.744; Masking is 64-bit. Then truncation.745define i32 @bextr64_32_c2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {746; CHECK-LABEL: bextr64_32_c2:747; CHECK:       // %bb.0:748; CHECK-NEXT:    lsr x8, x0, x1749; CHECK-NEXT:    neg w9, w2750; CHECK-NEXT:    lsl w8, w8, w9751; CHECK-NEXT:    lsr w0, w8, w9752; CHECK-NEXT:    ret753  %shifted = lshr i64 %val, %numskipbits754  %numhighbits = sub i32 32, %numlowbits755  %mask = lshr i32 -1, %numhighbits756  %zextmask = zext i32 %mask to i64757  %masked = and i64 %zextmask, %shifted758  %truncmasked = trunc i64 %masked to i32759  ret i32 %truncmasked760}761 762; ---------------------------------------------------------------------------- ;763; Pattern d. 32-bit.764; ---------------------------------------------------------------------------- ;765 766define i32 @bextr32_d0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind {767; CHECK-LABEL: bextr32_d0:768; CHECK:       // %bb.0:769; CHECK-NEXT:    lsr w8, w0, w1770; CHECK-NEXT:    neg w9, w2771; CHECK-NEXT:    lsl w8, w8, w9772; CHECK-NEXT:    lsr w0, w8, w9773; CHECK-NEXT:    ret774  %shifted = lshr i32 %val, %numskipbits775  %numhighbits = sub i32 32, %numlowbits776  %highbitscleared = shl i32 %shifted, %numhighbits777  %masked = lshr i32 %highbitscleared, %numhighbits778  ret i32 %masked779}780 781define i32 @bextr32_d1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind {782; CHECK-LABEL: bextr32_d1_indexzext:783; CHECK:       // %bb.0:784; CHECK-NEXT:    lsr w8, w0, w1785; CHECK-NEXT:    mov w9, #32 // =0x20786; CHECK-NEXT:    sub w9, w9, w2787; CHECK-NEXT:    lsl w8, w8, w9788; CHECK-NEXT:    lsr w0, w8, w9789; CHECK-NEXT:    ret790  %skip = zext i8 %numskipbits to i32791  %shifted = lshr i32 %val, %skip792  %numhighbits = sub i8 32, %numlowbits793  %sh_prom = zext i8 %numhighbits to i32794  %highbitscleared = shl i32 %shifted, %sh_prom795  %masked = lshr i32 %highbitscleared, %sh_prom796  ret i32 %masked797}798 799define i32 @bextr32_d2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind {800; CHECK-LABEL: bextr32_d2_load:801; CHECK:       // %bb.0:802; CHECK-NEXT:    ldr w8, [x0]803; CHECK-NEXT:    neg w9, w2804; CHECK-NEXT:    lsr w8, w8, w1805; CHECK-NEXT:    lsl w8, w8, w9806; CHECK-NEXT:    lsr w0, w8, w9807; CHECK-NEXT:    ret808  %val = load i32, ptr %w809  %shifted = lshr i32 %val, %numskipbits810  %numhighbits = sub i32 32, %numlowbits811  %highbitscleared = shl i32 %shifted, %numhighbits812  %masked = lshr i32 %highbitscleared, %numhighbits813  ret i32 %masked814}815 816define i32 @bextr32_d3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {817; CHECK-LABEL: bextr32_d3_load_indexzext:818; CHECK:       // %bb.0:819; CHECK-NEXT:    ldr w8, [x0]820; CHECK-NEXT:    mov w9, #32 // =0x20821; CHECK-NEXT:    sub w9, w9, w2822; CHECK-NEXT:    lsr w8, w8, w1823; CHECK-NEXT:    lsl w8, w8, w9824; CHECK-NEXT:    lsr w0, w8, w9825; CHECK-NEXT:    ret826  %val = load i32, ptr %w827  %skip = zext i8 %numskipbits to i32828  %shifted = lshr i32 %val, %skip829  %numhighbits = sub i8 32, %numlowbits830  %sh_prom = zext i8 %numhighbits to i32831  %highbitscleared = shl i32 %shifted, %sh_prom832  %masked = lshr i32 %highbitscleared, %sh_prom833  ret i32 %masked834}835 836; 64-bit.837 838define i64 @bextr64_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {839; CHECK-LABEL: bextr64_d0:840; CHECK:       // %bb.0:841; CHECK-NEXT:    lsr x8, x0, x1842; CHECK-NEXT:    neg x9, x2843; CHECK-NEXT:    lsl x8, x8, x9844; CHECK-NEXT:    lsr x0, x8, x9845; CHECK-NEXT:    ret846  %shifted = lshr i64 %val, %numskipbits847  %numhighbits = sub i64 64, %numlowbits848  %highbitscleared = shl i64 %shifted, %numhighbits849  %masked = lshr i64 %highbitscleared, %numhighbits850  ret i64 %masked851}852 853define i64 @bextr64_d1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind {854; CHECK-LABEL: bextr64_d1_indexzext:855; CHECK:       // %bb.0:856; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1857; CHECK-NEXT:    lsr x8, x0, x1858; CHECK-NEXT:    mov w9, #64 // =0x40859; CHECK-NEXT:    sub w9, w9, w2860; CHECK-NEXT:    lsl x8, x8, x9861; CHECK-NEXT:    lsr x0, x8, x9862; CHECK-NEXT:    ret863  %skip = zext i8 %numskipbits to i64864  %shifted = lshr i64 %val, %skip865  %numhighbits = sub i8 64, %numlowbits866  %sh_prom = zext i8 %numhighbits to i64867  %highbitscleared = shl i64 %shifted, %sh_prom868  %masked = lshr i64 %highbitscleared, %sh_prom869  ret i64 %masked870}871 872define i64 @bextr64_d2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind {873; CHECK-LABEL: bextr64_d2_load:874; CHECK:       // %bb.0:875; CHECK-NEXT:    ldr x8, [x0]876; CHECK-NEXT:    neg x9, x2877; CHECK-NEXT:    lsr x8, x8, x1878; CHECK-NEXT:    lsl x8, x8, x9879; CHECK-NEXT:    lsr x0, x8, x9880; CHECK-NEXT:    ret881  %val = load i64, ptr %w882  %shifted = lshr i64 %val, %numskipbits883  %numhighbits = sub i64 64, %numlowbits884  %highbitscleared = shl i64 %shifted, %numhighbits885  %masked = lshr i64 %highbitscleared, %numhighbits886  ret i64 %masked887}888 889define i64 @bextr64_d3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind {890; CHECK-LABEL: bextr64_d3_load_indexzext:891; CHECK:       // %bb.0:892; CHECK-NEXT:    ldr x8, [x0]893; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1894; CHECK-NEXT:    mov w9, #64 // =0x40895; CHECK-NEXT:    sub w9, w9, w2896; CHECK-NEXT:    lsr x8, x8, x1897; CHECK-NEXT:    lsl x8, x8, x9898; CHECK-NEXT:    lsr x0, x8, x9899; CHECK-NEXT:    ret900  %val = load i64, ptr %w901  %skip = zext i8 %numskipbits to i64902  %shifted = lshr i64 %val, %skip903  %numhighbits = sub i8 64, %numlowbits904  %sh_prom = zext i8 %numhighbits to i64905  %highbitscleared = shl i64 %shifted, %sh_prom906  %masked = lshr i64 %highbitscleared, %sh_prom907  ret i64 %masked908}909 910; 64-bit, but with 32-bit output911 912; Everything done in 64-bit, truncation happens last.913define i32 @bextr64_32_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind {914; CHECK-LABEL: bextr64_32_d0:915; CHECK:       // %bb.0:916; CHECK-NEXT:    lsr x8, x0, x1917; CHECK-NEXT:    neg x9, x2918; CHECK-NEXT:    lsl x8, x8, x9919; CHECK-NEXT:    lsr x0, x8, x9920; CHECK-NEXT:    // kill: def $w0 killed $w0 killed $x0921; CHECK-NEXT:    ret922  %shifted = lshr i64 %val, %numskipbits923  %numhighbits = sub i64 64, %numlowbits924  %highbitscleared = shl i64 %shifted, %numhighbits925  %masked = lshr i64 %highbitscleared, %numhighbits926  %res = trunc i64 %masked to i32927  ret i32 %res928}929 930; Shifting happens in 64-bit, then truncation. Masking is 32-bit.931define i32 @bextr64_32_d1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind {932; CHECK-LABEL: bextr64_32_d1:933; CHECK:       // %bb.0:934; CHECK-NEXT:    lsr x8, x0, x1935; CHECK-NEXT:    neg w9, w2936; CHECK-NEXT:    lsl w8, w8, w9937; CHECK-NEXT:    lsr w0, w8, w9938; CHECK-NEXT:    ret939  %shifted = lshr i64 %val, %numskipbits940  %truncshifted = trunc i64 %shifted to i32941  %numhighbits = sub i32 32, %numlowbits942  %highbitscleared = shl i32 %truncshifted, %numhighbits943  %masked = lshr i32 %highbitscleared, %numhighbits944  ret i32 %masked945}946 947; ---------------------------------------------------------------------------- ;948; Constant949; ---------------------------------------------------------------------------- ;950 951; https://bugs.llvm.org/show_bug.cgi?id=38938952define void @pr38938(ptr %a0, ptr %a1) nounwind {953; CHECK-LABEL: pr38938:954; CHECK:       // %bb.0:955; CHECK-NEXT:    ldr x8, [x1]956; CHECK-NEXT:    ubfx x8, x8, #21, #10957; CHECK-NEXT:    ldr w9, [x0, x8, lsl #2]958; CHECK-NEXT:    add w9, w9, #1959; CHECK-NEXT:    str w9, [x0, x8, lsl #2]960; CHECK-NEXT:    ret961  %tmp = load i64, ptr %a1, align 8962  %tmp1 = lshr i64 %tmp, 21963  %tmp2 = and i64 %tmp1, 1023964  %tmp3 = getelementptr inbounds i32, ptr %a0, i64 %tmp2965  %tmp4 = load i32, ptr %tmp3, align 4966  %tmp5 = add nsw i32 %tmp4, 1967  store i32 %tmp5, ptr %tmp3, align 4968  ret void969}970 971; The most canonical variant972define i32 @c0_i32(i32 %arg) nounwind {973; CHECK-LABEL: c0_i32:974; CHECK:       // %bb.0:975; CHECK-NEXT:    ubfx w0, w0, #19, #10976; CHECK-NEXT:    ret977  %tmp0 = lshr i32 %arg, 19978  %tmp1 = and i32 %tmp0, 1023979  ret i32 %tmp1980}981 982; Should be still fine, but the mask is shifted983define i32 @c1_i32(i32 %arg) nounwind {984; CHECK-LABEL: c1_i32:985; CHECK:       // %bb.0:986; CHECK-NEXT:    lsr w8, w0, #19987; CHECK-NEXT:    and w0, w8, #0xffc988; CHECK-NEXT:    ret989  %tmp0 = lshr i32 %arg, 19990  %tmp1 = and i32 %tmp0, 4092991  ret i32 %tmp1992}993 994; Should be still fine, but the result is shifted left afterwards995define i32 @c2_i32(i32 %arg) nounwind {996; CHECK-LABEL: c2_i32:997; CHECK:       // %bb.0:998; CHECK-NEXT:    lsr w8, w0, #17999; CHECK-NEXT:    and w0, w8, #0xffc1000; CHECK-NEXT:    ret1001  %tmp0 = lshr i32 %arg, 191002  %tmp1 = and i32 %tmp0, 10231003  %tmp2 = shl i32 %tmp1, 21004  ret i32 %tmp21005}1006 1007; The mask covers newly shifted-in bit1008define i32 @c4_i32_bad(i32 %arg) nounwind {1009; CHECK-LABEL: c4_i32_bad:1010; CHECK:       // %bb.0:1011; CHECK-NEXT:    lsr w8, w0, #191012; CHECK-NEXT:    and w0, w8, #0x1ffe1013; CHECK-NEXT:    ret1014  %tmp0 = lshr i32 %arg, 191015  %tmp1 = and i32 %tmp0, 163821016  ret i32 %tmp11017}1018 1019; i641020 1021; The most canonical variant1022define i64 @c0_i64(i64 %arg) nounwind {1023; CHECK-LABEL: c0_i64:1024; CHECK:       // %bb.0:1025; CHECK-NEXT:    ubfx x0, x0, #51, #101026; CHECK-NEXT:    ret1027  %tmp0 = lshr i64 %arg, 511028  %tmp1 = and i64 %tmp0, 10231029  ret i64 %tmp11030}1031 1032; Should be still fine, but the mask is shifted1033define i64 @c1_i64(i64 %arg) nounwind {1034; CHECK-LABEL: c1_i64:1035; CHECK:       // %bb.0:1036; CHECK-NEXT:    lsr x8, x0, #511037; CHECK-NEXT:    and x0, x8, #0xffc1038; CHECK-NEXT:    ret1039  %tmp0 = lshr i64 %arg, 511040  %tmp1 = and i64 %tmp0, 40921041  ret i64 %tmp11042}1043 1044; Should be still fine, but the result is shifted left afterwards1045define i64 @c2_i64(i64 %arg) nounwind {1046; CHECK-LABEL: c2_i64:1047; CHECK:       // %bb.0:1048; CHECK-NEXT:    lsr x8, x0, #491049; CHECK-NEXT:    and x0, x8, #0xffc1050; CHECK-NEXT:    ret1051  %tmp0 = lshr i64 %arg, 511052  %tmp1 = and i64 %tmp0, 10231053  %tmp2 = shl i64 %tmp1, 21054  ret i64 %tmp21055}1056 1057; The mask covers newly shifted-in bit1058define i64 @c4_i64_bad(i64 %arg) nounwind {1059; CHECK-LABEL: c4_i64_bad:1060; CHECK:       // %bb.0:1061; CHECK-NEXT:    lsr x8, x0, #511062; CHECK-NEXT:    and x0, x8, #0x1ffe1063; CHECK-NEXT:    ret1064  %tmp0 = lshr i64 %arg, 511065  %tmp1 = and i64 %tmp0, 163821066  ret i64 %tmp11067}1068 1069; ---------------------------------------------------------------------------- ;1070; Constant, storing the result afterwards.1071; ---------------------------------------------------------------------------- ;1072 1073; i321074 1075; The most canonical variant1076define void @c5_i32(i32 %arg, ptr %ptr) nounwind {1077; CHECK-LABEL: c5_i32:1078; CHECK:       // %bb.0:1079; CHECK-NEXT:    ubfx w8, w0, #19, #101080; CHECK-NEXT:    str w8, [x1]1081; CHECK-NEXT:    ret1082  %tmp0 = lshr i32 %arg, 191083  %tmp1 = and i32 %tmp0, 10231084  store i32 %tmp1, ptr %ptr1085  ret void1086}1087 1088; Should be still fine, but the mask is shifted1089define void @c6_i32(i32 %arg, ptr %ptr) nounwind {1090; CHECK-LABEL: c6_i32:1091; CHECK:       // %bb.0:1092; CHECK-NEXT:    ubfx w8, w0, #19, #121093; CHECK-NEXT:    str w8, [x1]1094; CHECK-NEXT:    ret1095  %tmp0 = lshr i32 %arg, 191096  %tmp1 = and i32 %tmp0, 40951097  store i32 %tmp1, ptr %ptr1098  ret void1099}1100 1101; Should be still fine, but the result is shifted left afterwards1102define void @c7_i32(i32 %arg, ptr %ptr) nounwind {1103; CHECK-LABEL: c7_i32:1104; CHECK:       // %bb.0:1105; CHECK-NEXT:    lsr w8, w0, #171106; CHECK-NEXT:    and w8, w8, #0xffc1107; CHECK-NEXT:    str w8, [x1]1108; CHECK-NEXT:    ret1109  %tmp0 = lshr i32 %arg, 191110  %tmp1 = and i32 %tmp0, 10231111  %tmp2 = shl i32 %tmp1, 21112  store i32 %tmp2, ptr %ptr1113  ret void1114}1115 1116; i641117 1118; The most canonical variant1119define void @c5_i64(i64 %arg, ptr %ptr) nounwind {1120; CHECK-LABEL: c5_i64:1121; CHECK:       // %bb.0:1122; CHECK-NEXT:    ubfx x8, x0, #51, #101123; CHECK-NEXT:    str x8, [x1]1124; CHECK-NEXT:    ret1125  %tmp0 = lshr i64 %arg, 511126  %tmp1 = and i64 %tmp0, 10231127  store i64 %tmp1, ptr %ptr1128  ret void1129}1130 1131; Should be still fine, but the mask is shifted1132define void @c6_i64(i64 %arg, ptr %ptr) nounwind {1133; CHECK-LABEL: c6_i64:1134; CHECK:       // %bb.0:1135; CHECK-NEXT:    ubfx x8, x0, #51, #121136; CHECK-NEXT:    str x8, [x1]1137; CHECK-NEXT:    ret1138  %tmp0 = lshr i64 %arg, 511139  %tmp1 = and i64 %tmp0, 40951140  store i64 %tmp1, ptr %ptr1141  ret void1142}1143 1144; Should be still fine, but the result is shifted left afterwards1145define void @c7_i64(i64 %arg, ptr %ptr) nounwind {1146; CHECK-LABEL: c7_i64:1147; CHECK:       // %bb.0:1148; CHECK-NEXT:    lsr x8, x0, #491149; CHECK-NEXT:    and x8, x8, #0xffc1150; CHECK-NEXT:    str x8, [x1]1151; CHECK-NEXT:    ret1152  %tmp0 = lshr i64 %arg, 511153  %tmp1 = and i64 %tmp0, 10231154  %tmp2 = shl i64 %tmp1, 21155  store i64 %tmp2, ptr %ptr1156  ret void1157}1158