1395 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X86,X86-NOBMI2,X86-BASELINE3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov,+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X86,X86-NOBMI2,X86-BMI14; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov,+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X86,X86-NOBMI2,X86-BMI15; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov,+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=X86,X86-BMI26; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov,+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=X86,X86-BMI27; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-NOBMI28; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-NOBMI29; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-NOBMI210; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-BMI211; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=X64,X64-BMI212 13; Patterns:14; c) x & (-1 >> y)15; d) x << y >> y16; are equivalent, but we prefer the second variant if we have BMI2.17 18; We do not test the variant where y = (32 - z), because that is BMI2's BZHI.19 20; ---------------------------------------------------------------------------- ;21; 8-bit22; ---------------------------------------------------------------------------- ;23 24define i8 @clear_highbits8_c0(i8 %val, i8 %numhighbits) nounwind {25; X86-LABEL: clear_highbits8_c0:26; X86: # %bb.0:27; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx28; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax29; X86-NEXT: shlb %cl, %al30; X86-NEXT: shrb %cl, %al31; X86-NEXT: retl32;33; X64-LABEL: clear_highbits8_c0:34; X64: # %bb.0:35; X64-NEXT: movl %esi, %ecx36; X64-NEXT: movl %edi, %eax37; X64-NEXT: shlb %cl, %al38; X64-NEXT: # kill: def $cl killed $cl killed $ecx39; X64-NEXT: shrb %cl, %al40; X64-NEXT: # kill: def $al killed $al killed $eax41; X64-NEXT: retq42 %mask = lshr i8 -1, %numhighbits43 %masked = and i8 %mask, %val44 ret i8 %masked45}46 47define i8 @clear_highbits8_c2_load(ptr %w, i8 %numhighbits) nounwind {48; X86-LABEL: clear_highbits8_c2_load:49; X86: # %bb.0:50; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx51; X86-NEXT: movl {{[0-9]+}}(%esp), %eax52; X86-NEXT: movzbl (%eax), %eax53; X86-NEXT: shlb %cl, %al54; X86-NEXT: shrb %cl, %al55; X86-NEXT: retl56;57; X64-LABEL: clear_highbits8_c2_load:58; X64: # %bb.0:59; X64-NEXT: movl %esi, %ecx60; X64-NEXT: movzbl (%rdi), %eax61; X64-NEXT: shlb %cl, %al62; X64-NEXT: # kill: def $cl killed $cl killed $ecx63; X64-NEXT: shrb %cl, %al64; X64-NEXT: retq65 %val = load i8, ptr %w66 %mask = lshr i8 -1, %numhighbits67 %masked = and i8 %mask, %val68 ret i8 %masked69}70 71define i8 @clear_highbits8_c4_commutative(i8 %val, i8 %numhighbits) nounwind {72; X86-LABEL: clear_highbits8_c4_commutative:73; X86: # %bb.0:74; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx75; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax76; X86-NEXT: shlb %cl, %al77; X86-NEXT: shrb %cl, %al78; X86-NEXT: retl79;80; X64-LABEL: clear_highbits8_c4_commutative:81; X64: # %bb.0:82; X64-NEXT: movl %esi, %ecx83; X64-NEXT: movl %edi, %eax84; X64-NEXT: shlb %cl, %al85; X64-NEXT: # kill: def $cl killed $cl killed $ecx86; X64-NEXT: shrb %cl, %al87; X64-NEXT: # kill: def $al killed $al killed $eax88; X64-NEXT: retq89 %mask = lshr i8 -1, %numhighbits90 %masked = and i8 %val, %mask ; swapped order91 ret i8 %masked92}93 94; ---------------------------------------------------------------------------- ;95; 16-bit96; ---------------------------------------------------------------------------- ;97 98define i16 @clear_highbits16_c0(i16 %val, i16 %numhighbits) nounwind {99; X86-NOBMI2-LABEL: clear_highbits16_c0:100; X86-NOBMI2: # %bb.0:101; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx102; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax103; X86-NOBMI2-NEXT: shll %cl, %eax104; X86-NOBMI2-NEXT: movzwl %ax, %eax105; X86-NOBMI2-NEXT: shrl %cl, %eax106; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax107; X86-NOBMI2-NEXT: retl108;109; X86-BMI2-LABEL: clear_highbits16_c0:110; X86-BMI2: # %bb.0:111; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax112; X86-BMI2-NEXT: shlxl %eax, {{[0-9]+}}(%esp), %ecx113; X86-BMI2-NEXT: movzwl %cx, %ecx114; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax115; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax116; X86-BMI2-NEXT: retl117;118; X64-NOBMI2-LABEL: clear_highbits16_c0:119; X64-NOBMI2: # %bb.0:120; X64-NOBMI2-NEXT: movl %esi, %ecx121; X64-NOBMI2-NEXT: shll %cl, %edi122; X64-NOBMI2-NEXT: movzwl %di, %eax123; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx124; X64-NOBMI2-NEXT: shrl %cl, %eax125; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax126; X64-NOBMI2-NEXT: retq127;128; X64-BMI2-LABEL: clear_highbits16_c0:129; X64-BMI2: # %bb.0:130; X64-BMI2-NEXT: shlxl %esi, %edi, %eax131; X64-BMI2-NEXT: movzwl %ax, %eax132; X64-BMI2-NEXT: shrxl %esi, %eax, %eax133; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax134; X64-BMI2-NEXT: retq135 %mask = lshr i16 -1, %numhighbits136 %masked = and i16 %mask, %val137 ret i16 %masked138}139 140define i16 @clear_highbits16_c1_indexzext(i16 %val, i8 %numhighbits) nounwind {141; X86-NOBMI2-LABEL: clear_highbits16_c1_indexzext:142; X86-NOBMI2: # %bb.0:143; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx144; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax145; X86-NOBMI2-NEXT: shll %cl, %eax146; X86-NOBMI2-NEXT: movzwl %ax, %eax147; X86-NOBMI2-NEXT: shrl %cl, %eax148; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax149; X86-NOBMI2-NEXT: retl150;151; X86-BMI2-LABEL: clear_highbits16_c1_indexzext:152; X86-BMI2: # %bb.0:153; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax154; X86-BMI2-NEXT: shlxl %eax, {{[0-9]+}}(%esp), %ecx155; X86-BMI2-NEXT: movzwl %cx, %ecx156; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax157; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax158; X86-BMI2-NEXT: retl159;160; X64-NOBMI2-LABEL: clear_highbits16_c1_indexzext:161; X64-NOBMI2: # %bb.0:162; X64-NOBMI2-NEXT: movl %esi, %ecx163; X64-NOBMI2-NEXT: shll %cl, %edi164; X64-NOBMI2-NEXT: movzwl %di, %eax165; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx166; X64-NOBMI2-NEXT: shrl %cl, %eax167; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax168; X64-NOBMI2-NEXT: retq169;170; X64-BMI2-LABEL: clear_highbits16_c1_indexzext:171; X64-BMI2: # %bb.0:172; X64-BMI2-NEXT: shlxl %esi, %edi, %eax173; X64-BMI2-NEXT: movzwl %ax, %eax174; X64-BMI2-NEXT: shrxl %esi, %eax, %eax175; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax176; X64-BMI2-NEXT: retq177 %sh_prom = zext i8 %numhighbits to i16178 %mask = lshr i16 -1, %sh_prom179 %masked = and i16 %mask, %val180 ret i16 %masked181}182 183define i16 @clear_highbits16_c2_load(ptr %w, i16 %numhighbits) nounwind {184; X86-NOBMI2-LABEL: clear_highbits16_c2_load:185; X86-NOBMI2: # %bb.0:186; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx187; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax188; X86-NOBMI2-NEXT: movzwl (%eax), %eax189; X86-NOBMI2-NEXT: shll %cl, %eax190; X86-NOBMI2-NEXT: movzwl %ax, %eax191; X86-NOBMI2-NEXT: shrl %cl, %eax192; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax193; X86-NOBMI2-NEXT: retl194;195; X86-BMI2-LABEL: clear_highbits16_c2_load:196; X86-BMI2: # %bb.0:197; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax198; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx199; X86-BMI2-NEXT: movzwl (%ecx), %ecx200; X86-BMI2-NEXT: shlxl %eax, %ecx, %ecx201; X86-BMI2-NEXT: movzwl %cx, %ecx202; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax203; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax204; X86-BMI2-NEXT: retl205;206; X64-NOBMI2-LABEL: clear_highbits16_c2_load:207; X64-NOBMI2: # %bb.0:208; X64-NOBMI2-NEXT: movl %esi, %ecx209; X64-NOBMI2-NEXT: movzwl (%rdi), %eax210; X64-NOBMI2-NEXT: shll %cl, %eax211; X64-NOBMI2-NEXT: movzwl %ax, %eax212; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx213; X64-NOBMI2-NEXT: shrl %cl, %eax214; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax215; X64-NOBMI2-NEXT: retq216;217; X64-BMI2-LABEL: clear_highbits16_c2_load:218; X64-BMI2: # %bb.0:219; X64-BMI2-NEXT: movzwl (%rdi), %eax220; X64-BMI2-NEXT: shlxl %esi, %eax, %eax221; X64-BMI2-NEXT: movzwl %ax, %eax222; X64-BMI2-NEXT: shrxl %esi, %eax, %eax223; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax224; X64-BMI2-NEXT: retq225 %val = load i16, ptr %w226 %mask = lshr i16 -1, %numhighbits227 %masked = and i16 %mask, %val228 ret i16 %masked229}230 231define i16 @clear_highbits16_c3_load_indexzext(ptr %w, i8 %numhighbits) nounwind {232; X86-NOBMI2-LABEL: clear_highbits16_c3_load_indexzext:233; X86-NOBMI2: # %bb.0:234; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx235; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax236; X86-NOBMI2-NEXT: movzwl (%eax), %eax237; X86-NOBMI2-NEXT: shll %cl, %eax238; X86-NOBMI2-NEXT: movzwl %ax, %eax239; X86-NOBMI2-NEXT: shrl %cl, %eax240; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax241; X86-NOBMI2-NEXT: retl242;243; X86-BMI2-LABEL: clear_highbits16_c3_load_indexzext:244; X86-BMI2: # %bb.0:245; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax246; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx247; X86-BMI2-NEXT: movzwl (%ecx), %ecx248; X86-BMI2-NEXT: shlxl %eax, %ecx, %ecx249; X86-BMI2-NEXT: movzwl %cx, %ecx250; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax251; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax252; X86-BMI2-NEXT: retl253;254; X64-NOBMI2-LABEL: clear_highbits16_c3_load_indexzext:255; X64-NOBMI2: # %bb.0:256; X64-NOBMI2-NEXT: movl %esi, %ecx257; X64-NOBMI2-NEXT: movzwl (%rdi), %eax258; X64-NOBMI2-NEXT: shll %cl, %eax259; X64-NOBMI2-NEXT: movzwl %ax, %eax260; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx261; X64-NOBMI2-NEXT: shrl %cl, %eax262; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax263; X64-NOBMI2-NEXT: retq264;265; X64-BMI2-LABEL: clear_highbits16_c3_load_indexzext:266; X64-BMI2: # %bb.0:267; X64-BMI2-NEXT: movzwl (%rdi), %eax268; X64-BMI2-NEXT: shlxl %esi, %eax, %eax269; X64-BMI2-NEXT: movzwl %ax, %eax270; X64-BMI2-NEXT: shrxl %esi, %eax, %eax271; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax272; X64-BMI2-NEXT: retq273 %val = load i16, ptr %w274 %sh_prom = zext i8 %numhighbits to i16275 %mask = lshr i16 -1, %sh_prom276 %masked = and i16 %mask, %val277 ret i16 %masked278}279 280define i16 @clear_highbits16_c4_commutative(i16 %val, i16 %numhighbits) nounwind {281; X86-NOBMI2-LABEL: clear_highbits16_c4_commutative:282; X86-NOBMI2: # %bb.0:283; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx284; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax285; X86-NOBMI2-NEXT: shll %cl, %eax286; X86-NOBMI2-NEXT: movzwl %ax, %eax287; X86-NOBMI2-NEXT: shrl %cl, %eax288; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax289; X86-NOBMI2-NEXT: retl290;291; X86-BMI2-LABEL: clear_highbits16_c4_commutative:292; X86-BMI2: # %bb.0:293; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax294; X86-BMI2-NEXT: shlxl %eax, {{[0-9]+}}(%esp), %ecx295; X86-BMI2-NEXT: movzwl %cx, %ecx296; X86-BMI2-NEXT: shrxl %eax, %ecx, %eax297; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax298; X86-BMI2-NEXT: retl299;300; X64-NOBMI2-LABEL: clear_highbits16_c4_commutative:301; X64-NOBMI2: # %bb.0:302; X64-NOBMI2-NEXT: movl %esi, %ecx303; X64-NOBMI2-NEXT: shll %cl, %edi304; X64-NOBMI2-NEXT: movzwl %di, %eax305; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx306; X64-NOBMI2-NEXT: shrl %cl, %eax307; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax308; X64-NOBMI2-NEXT: retq309;310; X64-BMI2-LABEL: clear_highbits16_c4_commutative:311; X64-BMI2: # %bb.0:312; X64-BMI2-NEXT: shlxl %esi, %edi, %eax313; X64-BMI2-NEXT: movzwl %ax, %eax314; X64-BMI2-NEXT: shrxl %esi, %eax, %eax315; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax316; X64-BMI2-NEXT: retq317 %mask = lshr i16 -1, %numhighbits318 %masked = and i16 %val, %mask ; swapped order319 ret i16 %masked320}321 322; ---------------------------------------------------------------------------- ;323; 32-bit324; ---------------------------------------------------------------------------- ;325 326define i32 @clear_highbits32_c0(i32 %val, i32 %numhighbits) nounwind {327; X86-NOBMI2-LABEL: clear_highbits32_c0:328; X86-NOBMI2: # %bb.0:329; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx330; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax331; X86-NOBMI2-NEXT: shll %cl, %eax332; X86-NOBMI2-NEXT: shrl %cl, %eax333; X86-NOBMI2-NEXT: retl334;335; X86-BMI2-LABEL: clear_highbits32_c0:336; X86-BMI2: # %bb.0:337; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax338; X86-BMI2-NEXT: movl $32, %ecx339; X86-BMI2-NEXT: subl %eax, %ecx340; X86-BMI2-NEXT: bzhil %ecx, {{[0-9]+}}(%esp), %eax341; X86-BMI2-NEXT: retl342;343; X64-NOBMI2-LABEL: clear_highbits32_c0:344; X64-NOBMI2: # %bb.0:345; X64-NOBMI2-NEXT: movl %esi, %ecx346; X64-NOBMI2-NEXT: movl %edi, %eax347; X64-NOBMI2-NEXT: shll %cl, %eax348; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx349; X64-NOBMI2-NEXT: shrl %cl, %eax350; X64-NOBMI2-NEXT: retq351;352; X64-BMI2-LABEL: clear_highbits32_c0:353; X64-BMI2: # %bb.0:354; X64-BMI2-NEXT: movl $32, %eax355; X64-BMI2-NEXT: subl %esi, %eax356; X64-BMI2-NEXT: bzhil %eax, %edi, %eax357; X64-BMI2-NEXT: retq358 %mask = lshr i32 -1, %numhighbits359 %masked = and i32 %mask, %val360 ret i32 %masked361}362 363define i32 @clear_highbits32_c1_indexzext(i32 %val, i8 %numhighbits) nounwind {364; X86-NOBMI2-LABEL: clear_highbits32_c1_indexzext:365; X86-NOBMI2: # %bb.0:366; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx367; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax368; X86-NOBMI2-NEXT: shll %cl, %eax369; X86-NOBMI2-NEXT: shrl %cl, %eax370; X86-NOBMI2-NEXT: retl371;372; X86-BMI2-LABEL: clear_highbits32_c1_indexzext:373; X86-BMI2: # %bb.0:374; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax375; X86-BMI2-NEXT: movl $32, %ecx376; X86-BMI2-NEXT: subl %eax, %ecx377; X86-BMI2-NEXT: bzhil %ecx, {{[0-9]+}}(%esp), %eax378; X86-BMI2-NEXT: retl379;380; X64-NOBMI2-LABEL: clear_highbits32_c1_indexzext:381; X64-NOBMI2: # %bb.0:382; X64-NOBMI2-NEXT: movl %esi, %ecx383; X64-NOBMI2-NEXT: movl %edi, %eax384; X64-NOBMI2-NEXT: shll %cl, %eax385; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx386; X64-NOBMI2-NEXT: shrl %cl, %eax387; X64-NOBMI2-NEXT: retq388;389; X64-BMI2-LABEL: clear_highbits32_c1_indexzext:390; X64-BMI2: # %bb.0:391; X64-BMI2-NEXT: movl $32, %eax392; X64-BMI2-NEXT: subl %esi, %eax393; X64-BMI2-NEXT: bzhil %eax, %edi, %eax394; X64-BMI2-NEXT: retq395 %sh_prom = zext i8 %numhighbits to i32396 %mask = lshr i32 -1, %sh_prom397 %masked = and i32 %mask, %val398 ret i32 %masked399}400 401define i32 @clear_highbits32_c2_load(ptr %w, i32 %numhighbits) nounwind {402; X86-NOBMI2-LABEL: clear_highbits32_c2_load:403; X86-NOBMI2: # %bb.0:404; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx405; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax406; X86-NOBMI2-NEXT: movl (%eax), %eax407; X86-NOBMI2-NEXT: shll %cl, %eax408; X86-NOBMI2-NEXT: shrl %cl, %eax409; X86-NOBMI2-NEXT: retl410;411; X86-BMI2-LABEL: clear_highbits32_c2_load:412; X86-BMI2: # %bb.0:413; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax414; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx415; X86-BMI2-NEXT: movl $32, %edx416; X86-BMI2-NEXT: subl %ecx, %edx417; X86-BMI2-NEXT: bzhil %edx, (%eax), %eax418; X86-BMI2-NEXT: retl419;420; X64-NOBMI2-LABEL: clear_highbits32_c2_load:421; X64-NOBMI2: # %bb.0:422; X64-NOBMI2-NEXT: movl %esi, %ecx423; X64-NOBMI2-NEXT: movl (%rdi), %eax424; X64-NOBMI2-NEXT: shll %cl, %eax425; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx426; X64-NOBMI2-NEXT: shrl %cl, %eax427; X64-NOBMI2-NEXT: retq428;429; X64-BMI2-LABEL: clear_highbits32_c2_load:430; X64-BMI2: # %bb.0:431; X64-BMI2-NEXT: movl $32, %eax432; X64-BMI2-NEXT: subl %esi, %eax433; X64-BMI2-NEXT: bzhil %eax, (%rdi), %eax434; X64-BMI2-NEXT: retq435 %val = load i32, ptr %w436 %mask = lshr i32 -1, %numhighbits437 %masked = and i32 %mask, %val438 ret i32 %masked439}440 441define i32 @clear_highbits32_c3_load_indexzext(ptr %w, i8 %numhighbits) nounwind {442; X86-NOBMI2-LABEL: clear_highbits32_c3_load_indexzext:443; X86-NOBMI2: # %bb.0:444; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx445; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax446; X86-NOBMI2-NEXT: movl (%eax), %eax447; X86-NOBMI2-NEXT: shll %cl, %eax448; X86-NOBMI2-NEXT: shrl %cl, %eax449; X86-NOBMI2-NEXT: retl450;451; X86-BMI2-LABEL: clear_highbits32_c3_load_indexzext:452; X86-BMI2: # %bb.0:453; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax454; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx455; X86-BMI2-NEXT: movl $32, %edx456; X86-BMI2-NEXT: subl %ecx, %edx457; X86-BMI2-NEXT: bzhil %edx, (%eax), %eax458; X86-BMI2-NEXT: retl459;460; X64-NOBMI2-LABEL: clear_highbits32_c3_load_indexzext:461; X64-NOBMI2: # %bb.0:462; X64-NOBMI2-NEXT: movl %esi, %ecx463; X64-NOBMI2-NEXT: movl (%rdi), %eax464; X64-NOBMI2-NEXT: shll %cl, %eax465; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx466; X64-NOBMI2-NEXT: shrl %cl, %eax467; X64-NOBMI2-NEXT: retq468;469; X64-BMI2-LABEL: clear_highbits32_c3_load_indexzext:470; X64-BMI2: # %bb.0:471; X64-BMI2-NEXT: movl $32, %eax472; X64-BMI2-NEXT: subl %esi, %eax473; X64-BMI2-NEXT: bzhil %eax, (%rdi), %eax474; X64-BMI2-NEXT: retq475 %val = load i32, ptr %w476 %sh_prom = zext i8 %numhighbits to i32477 %mask = lshr i32 -1, %sh_prom478 %masked = and i32 %mask, %val479 ret i32 %masked480}481 482define i32 @clear_highbits32_c4_commutative(i32 %val, i32 %numhighbits) nounwind {483; X86-NOBMI2-LABEL: clear_highbits32_c4_commutative:484; X86-NOBMI2: # %bb.0:485; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx486; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax487; X86-NOBMI2-NEXT: shll %cl, %eax488; X86-NOBMI2-NEXT: shrl %cl, %eax489; X86-NOBMI2-NEXT: retl490;491; X86-BMI2-LABEL: clear_highbits32_c4_commutative:492; X86-BMI2: # %bb.0:493; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax494; X86-BMI2-NEXT: movl $32, %ecx495; X86-BMI2-NEXT: subl %eax, %ecx496; X86-BMI2-NEXT: bzhil %ecx, {{[0-9]+}}(%esp), %eax497; X86-BMI2-NEXT: retl498;499; X64-NOBMI2-LABEL: clear_highbits32_c4_commutative:500; X64-NOBMI2: # %bb.0:501; X64-NOBMI2-NEXT: movl %esi, %ecx502; X64-NOBMI2-NEXT: movl %edi, %eax503; X64-NOBMI2-NEXT: shll %cl, %eax504; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx505; X64-NOBMI2-NEXT: shrl %cl, %eax506; X64-NOBMI2-NEXT: retq507;508; X64-BMI2-LABEL: clear_highbits32_c4_commutative:509; X64-BMI2: # %bb.0:510; X64-BMI2-NEXT: movl $32, %eax511; X64-BMI2-NEXT: subl %esi, %eax512; X64-BMI2-NEXT: bzhil %eax, %edi, %eax513; X64-BMI2-NEXT: retq514 %mask = lshr i32 -1, %numhighbits515 %masked = and i32 %val, %mask ; swapped order516 ret i32 %masked517}518 519; ---------------------------------------------------------------------------- ;520; 64-bit521; ---------------------------------------------------------------------------- ;522 523define i64 @clear_highbits64_c0(i64 %val, i64 %numhighbits) nounwind {524; X86-BASELINE-LABEL: clear_highbits64_c0:525; X86-BASELINE: # %bb.0:526; X86-BASELINE-NEXT: pushl %esi527; X86-BASELINE-NEXT: movzbl {{[0-9]+}}(%esp), %ecx528; X86-BASELINE-NEXT: movl $-1, %eax529; X86-BASELINE-NEXT: movl $-1, %esi530; X86-BASELINE-NEXT: shrl %cl, %esi531; X86-BASELINE-NEXT: xorl %edx, %edx532; X86-BASELINE-NEXT: testb $32, %cl533; X86-BASELINE-NEXT: jne .LBB13_1534; X86-BASELINE-NEXT: # %bb.2:535; X86-BASELINE-NEXT: movl %esi, %edx536; X86-BASELINE-NEXT: jmp .LBB13_3537; X86-BASELINE-NEXT: .LBB13_1:538; X86-BASELINE-NEXT: movl %esi, %eax539; X86-BASELINE-NEXT: .LBB13_3:540; X86-BASELINE-NEXT: andl {{[0-9]+}}(%esp), %eax541; X86-BASELINE-NEXT: andl {{[0-9]+}}(%esp), %edx542; X86-BASELINE-NEXT: popl %esi543; X86-BASELINE-NEXT: retl544;545; X86-BMI1-LABEL: clear_highbits64_c0:546; X86-BMI1: # %bb.0:547; X86-BMI1-NEXT: pushl %esi548; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx549; X86-BMI1-NEXT: movl $-1, %esi550; X86-BMI1-NEXT: movl $-1, %eax551; X86-BMI1-NEXT: shrl %cl, %eax552; X86-BMI1-NEXT: xorl %edx, %edx553; X86-BMI1-NEXT: testb $32, %cl554; X86-BMI1-NEXT: cmovel %eax, %edx555; X86-BMI1-NEXT: cmovel %esi, %eax556; X86-BMI1-NEXT: andl {{[0-9]+}}(%esp), %eax557; X86-BMI1-NEXT: andl {{[0-9]+}}(%esp), %edx558; X86-BMI1-NEXT: popl %esi559; X86-BMI1-NEXT: retl560;561; X86-BMI2-LABEL: clear_highbits64_c0:562; X86-BMI2: # %bb.0:563; X86-BMI2-NEXT: pushl %esi564; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx565; X86-BMI2-NEXT: movl $-1, %eax566; X86-BMI2-NEXT: shrxl %ecx, %eax, %esi567; X86-BMI2-NEXT: xorl %edx, %edx568; X86-BMI2-NEXT: testb $32, %cl569; X86-BMI2-NEXT: cmovel %esi, %edx570; X86-BMI2-NEXT: cmovnel %esi, %eax571; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax572; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx573; X86-BMI2-NEXT: popl %esi574; X86-BMI2-NEXT: retl575;576; X64-NOBMI2-LABEL: clear_highbits64_c0:577; X64-NOBMI2: # %bb.0:578; X64-NOBMI2-NEXT: movq %rsi, %rcx579; X64-NOBMI2-NEXT: movq %rdi, %rax580; X64-NOBMI2-NEXT: shlq %cl, %rax581; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx582; X64-NOBMI2-NEXT: shrq %cl, %rax583; X64-NOBMI2-NEXT: retq584;585; X64-BMI2-LABEL: clear_highbits64_c0:586; X64-BMI2: # %bb.0:587; X64-BMI2-NEXT: movl $64, %eax588; X64-BMI2-NEXT: subl %esi, %eax589; X64-BMI2-NEXT: bzhiq %rax, %rdi, %rax590; X64-BMI2-NEXT: retq591 %mask = lshr i64 -1, %numhighbits592 %masked = and i64 %mask, %val593 ret i64 %masked594}595 596define i64 @clear_highbits64_c1_indexzext(i64 %val, i8 %numhighbits) nounwind {597; X86-BASELINE-LABEL: clear_highbits64_c1_indexzext:598; X86-BASELINE: # %bb.0:599; X86-BASELINE-NEXT: pushl %esi600; X86-BASELINE-NEXT: movzbl {{[0-9]+}}(%esp), %ecx601; X86-BASELINE-NEXT: movl $-1, %eax602; X86-BASELINE-NEXT: movl $-1, %esi603; X86-BASELINE-NEXT: shrl %cl, %esi604; X86-BASELINE-NEXT: xorl %edx, %edx605; X86-BASELINE-NEXT: testb $32, %cl606; X86-BASELINE-NEXT: jne .LBB14_1607; X86-BASELINE-NEXT: # %bb.2:608; X86-BASELINE-NEXT: movl %esi, %edx609; X86-BASELINE-NEXT: jmp .LBB14_3610; X86-BASELINE-NEXT: .LBB14_1:611; X86-BASELINE-NEXT: movl %esi, %eax612; X86-BASELINE-NEXT: .LBB14_3:613; X86-BASELINE-NEXT: andl {{[0-9]+}}(%esp), %eax614; X86-BASELINE-NEXT: andl {{[0-9]+}}(%esp), %edx615; X86-BASELINE-NEXT: popl %esi616; X86-BASELINE-NEXT: retl617;618; X86-BMI1-LABEL: clear_highbits64_c1_indexzext:619; X86-BMI1: # %bb.0:620; X86-BMI1-NEXT: pushl %esi621; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx622; X86-BMI1-NEXT: movl $-1, %esi623; X86-BMI1-NEXT: movl $-1, %eax624; X86-BMI1-NEXT: shrl %cl, %eax625; X86-BMI1-NEXT: xorl %edx, %edx626; X86-BMI1-NEXT: testb $32, %cl627; X86-BMI1-NEXT: cmovel %eax, %edx628; X86-BMI1-NEXT: cmovel %esi, %eax629; X86-BMI1-NEXT: andl {{[0-9]+}}(%esp), %eax630; X86-BMI1-NEXT: andl {{[0-9]+}}(%esp), %edx631; X86-BMI1-NEXT: popl %esi632; X86-BMI1-NEXT: retl633;634; X86-BMI2-LABEL: clear_highbits64_c1_indexzext:635; X86-BMI2: # %bb.0:636; X86-BMI2-NEXT: pushl %esi637; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx638; X86-BMI2-NEXT: movl $-1, %eax639; X86-BMI2-NEXT: shrxl %ecx, %eax, %esi640; X86-BMI2-NEXT: xorl %edx, %edx641; X86-BMI2-NEXT: testb $32, %cl642; X86-BMI2-NEXT: cmovel %esi, %edx643; X86-BMI2-NEXT: cmovnel %esi, %eax644; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax645; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx646; X86-BMI2-NEXT: popl %esi647; X86-BMI2-NEXT: retl648;649; X64-NOBMI2-LABEL: clear_highbits64_c1_indexzext:650; X64-NOBMI2: # %bb.0:651; X64-NOBMI2-NEXT: movl %esi, %ecx652; X64-NOBMI2-NEXT: movq %rdi, %rax653; X64-NOBMI2-NEXT: shlq %cl, %rax654; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx655; X64-NOBMI2-NEXT: shrq %cl, %rax656; X64-NOBMI2-NEXT: retq657;658; X64-BMI2-LABEL: clear_highbits64_c1_indexzext:659; X64-BMI2: # %bb.0:660; X64-BMI2-NEXT: movl $64, %eax661; X64-BMI2-NEXT: subl %esi, %eax662; X64-BMI2-NEXT: bzhiq %rax, %rdi, %rax663; X64-BMI2-NEXT: retq664 %sh_prom = zext i8 %numhighbits to i64665 %mask = lshr i64 -1, %sh_prom666 %masked = and i64 %mask, %val667 ret i64 %masked668}669 670define i64 @clear_highbits64_c2_load(ptr %w, i64 %numhighbits) nounwind {671; X86-BASELINE-LABEL: clear_highbits64_c2_load:672; X86-BASELINE: # %bb.0:673; X86-BASELINE-NEXT: pushl %edi674; X86-BASELINE-NEXT: pushl %esi675; X86-BASELINE-NEXT: movl {{[0-9]+}}(%esp), %esi676; X86-BASELINE-NEXT: movzbl {{[0-9]+}}(%esp), %ecx677; X86-BASELINE-NEXT: movl $-1, %eax678; X86-BASELINE-NEXT: movl $-1, %edi679; X86-BASELINE-NEXT: shrl %cl, %edi680; X86-BASELINE-NEXT: xorl %edx, %edx681; X86-BASELINE-NEXT: testb $32, %cl682; X86-BASELINE-NEXT: jne .LBB15_1683; X86-BASELINE-NEXT: # %bb.2:684; X86-BASELINE-NEXT: movl %edi, %edx685; X86-BASELINE-NEXT: jmp .LBB15_3686; X86-BASELINE-NEXT: .LBB15_1:687; X86-BASELINE-NEXT: movl %edi, %eax688; X86-BASELINE-NEXT: .LBB15_3:689; X86-BASELINE-NEXT: andl (%esi), %eax690; X86-BASELINE-NEXT: andl 4(%esi), %edx691; X86-BASELINE-NEXT: popl %esi692; X86-BASELINE-NEXT: popl %edi693; X86-BASELINE-NEXT: retl694;695; X86-BMI1-LABEL: clear_highbits64_c2_load:696; X86-BMI1: # %bb.0:697; X86-BMI1-NEXT: pushl %edi698; X86-BMI1-NEXT: pushl %esi699; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi700; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx701; X86-BMI1-NEXT: movl $-1, %edi702; X86-BMI1-NEXT: movl $-1, %eax703; X86-BMI1-NEXT: shrl %cl, %eax704; X86-BMI1-NEXT: xorl %edx, %edx705; X86-BMI1-NEXT: testb $32, %cl706; X86-BMI1-NEXT: cmovel %eax, %edx707; X86-BMI1-NEXT: cmovel %edi, %eax708; X86-BMI1-NEXT: andl (%esi), %eax709; X86-BMI1-NEXT: andl 4(%esi), %edx710; X86-BMI1-NEXT: popl %esi711; X86-BMI1-NEXT: popl %edi712; X86-BMI1-NEXT: retl713;714; X86-BMI2-LABEL: clear_highbits64_c2_load:715; X86-BMI2: # %bb.0:716; X86-BMI2-NEXT: pushl %ebx717; X86-BMI2-NEXT: pushl %esi718; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx719; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx720; X86-BMI2-NEXT: movl $-1, %eax721; X86-BMI2-NEXT: shrxl %ebx, %eax, %esi722; X86-BMI2-NEXT: xorl %edx, %edx723; X86-BMI2-NEXT: testb $32, %bl724; X86-BMI2-NEXT: cmovel %esi, %edx725; X86-BMI2-NEXT: cmovnel %esi, %eax726; X86-BMI2-NEXT: andl (%ecx), %eax727; X86-BMI2-NEXT: andl 4(%ecx), %edx728; X86-BMI2-NEXT: popl %esi729; X86-BMI2-NEXT: popl %ebx730; X86-BMI2-NEXT: retl731;732; X64-NOBMI2-LABEL: clear_highbits64_c2_load:733; X64-NOBMI2: # %bb.0:734; X64-NOBMI2-NEXT: movq %rsi, %rcx735; X64-NOBMI2-NEXT: movq (%rdi), %rax736; X64-NOBMI2-NEXT: shlq %cl, %rax737; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx738; X64-NOBMI2-NEXT: shrq %cl, %rax739; X64-NOBMI2-NEXT: retq740;741; X64-BMI2-LABEL: clear_highbits64_c2_load:742; X64-BMI2: # %bb.0:743; X64-BMI2-NEXT: movl $64, %eax744; X64-BMI2-NEXT: subl %esi, %eax745; X64-BMI2-NEXT: bzhiq %rax, (%rdi), %rax746; X64-BMI2-NEXT: retq747 %val = load i64, ptr %w748 %mask = lshr i64 -1, %numhighbits749 %masked = and i64 %mask, %val750 ret i64 %masked751}752 753define i64 @clear_highbits64_c3_load_indexzext(ptr %w, i8 %numhighbits) nounwind {754; X86-BASELINE-LABEL: clear_highbits64_c3_load_indexzext:755; X86-BASELINE: # %bb.0:756; X86-BASELINE-NEXT: pushl %edi757; X86-BASELINE-NEXT: pushl %esi758; X86-BASELINE-NEXT: movl {{[0-9]+}}(%esp), %esi759; X86-BASELINE-NEXT: movzbl {{[0-9]+}}(%esp), %ecx760; X86-BASELINE-NEXT: movl $-1, %eax761; X86-BASELINE-NEXT: movl $-1, %edi762; X86-BASELINE-NEXT: shrl %cl, %edi763; X86-BASELINE-NEXT: xorl %edx, %edx764; X86-BASELINE-NEXT: testb $32, %cl765; X86-BASELINE-NEXT: jne .LBB16_1766; X86-BASELINE-NEXT: # %bb.2:767; X86-BASELINE-NEXT: movl %edi, %edx768; X86-BASELINE-NEXT: jmp .LBB16_3769; X86-BASELINE-NEXT: .LBB16_1:770; X86-BASELINE-NEXT: movl %edi, %eax771; X86-BASELINE-NEXT: .LBB16_3:772; X86-BASELINE-NEXT: andl (%esi), %eax773; X86-BASELINE-NEXT: andl 4(%esi), %edx774; X86-BASELINE-NEXT: popl %esi775; X86-BASELINE-NEXT: popl %edi776; X86-BASELINE-NEXT: retl777;778; X86-BMI1-LABEL: clear_highbits64_c3_load_indexzext:779; X86-BMI1: # %bb.0:780; X86-BMI1-NEXT: pushl %edi781; X86-BMI1-NEXT: pushl %esi782; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi783; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx784; X86-BMI1-NEXT: movl $-1, %edi785; X86-BMI1-NEXT: movl $-1, %eax786; X86-BMI1-NEXT: shrl %cl, %eax787; X86-BMI1-NEXT: xorl %edx, %edx788; X86-BMI1-NEXT: testb $32, %cl789; X86-BMI1-NEXT: cmovel %eax, %edx790; X86-BMI1-NEXT: cmovel %edi, %eax791; X86-BMI1-NEXT: andl (%esi), %eax792; X86-BMI1-NEXT: andl 4(%esi), %edx793; X86-BMI1-NEXT: popl %esi794; X86-BMI1-NEXT: popl %edi795; X86-BMI1-NEXT: retl796;797; X86-BMI2-LABEL: clear_highbits64_c3_load_indexzext:798; X86-BMI2: # %bb.0:799; X86-BMI2-NEXT: pushl %ebx800; X86-BMI2-NEXT: pushl %esi801; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx802; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx803; X86-BMI2-NEXT: movl $-1, %eax804; X86-BMI2-NEXT: shrxl %ebx, %eax, %esi805; X86-BMI2-NEXT: xorl %edx, %edx806; X86-BMI2-NEXT: testb $32, %bl807; X86-BMI2-NEXT: cmovel %esi, %edx808; X86-BMI2-NEXT: cmovnel %esi, %eax809; X86-BMI2-NEXT: andl (%ecx), %eax810; X86-BMI2-NEXT: andl 4(%ecx), %edx811; X86-BMI2-NEXT: popl %esi812; X86-BMI2-NEXT: popl %ebx813; X86-BMI2-NEXT: retl814;815; X64-NOBMI2-LABEL: clear_highbits64_c3_load_indexzext:816; X64-NOBMI2: # %bb.0:817; X64-NOBMI2-NEXT: movl %esi, %ecx818; X64-NOBMI2-NEXT: movq (%rdi), %rax819; X64-NOBMI2-NEXT: shlq %cl, %rax820; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx821; X64-NOBMI2-NEXT: shrq %cl, %rax822; X64-NOBMI2-NEXT: retq823;824; X64-BMI2-LABEL: clear_highbits64_c3_load_indexzext:825; X64-BMI2: # %bb.0:826; X64-BMI2-NEXT: movl $64, %eax827; X64-BMI2-NEXT: subl %esi, %eax828; X64-BMI2-NEXT: bzhiq %rax, (%rdi), %rax829; X64-BMI2-NEXT: retq830 %val = load i64, ptr %w831 %sh_prom = zext i8 %numhighbits to i64832 %mask = lshr i64 -1, %sh_prom833 %masked = and i64 %mask, %val834 ret i64 %masked835}836 837define i64 @clear_highbits64_c4_commutative(i64 %val, i64 %numhighbits) nounwind {838; X86-BASELINE-LABEL: clear_highbits64_c4_commutative:839; X86-BASELINE: # %bb.0:840; X86-BASELINE-NEXT: pushl %esi841; X86-BASELINE-NEXT: movzbl {{[0-9]+}}(%esp), %ecx842; X86-BASELINE-NEXT: movl $-1, %eax843; X86-BASELINE-NEXT: movl $-1, %esi844; X86-BASELINE-NEXT: shrl %cl, %esi845; X86-BASELINE-NEXT: xorl %edx, %edx846; X86-BASELINE-NEXT: testb $32, %cl847; X86-BASELINE-NEXT: jne .LBB17_1848; X86-BASELINE-NEXT: # %bb.2:849; X86-BASELINE-NEXT: movl %esi, %edx850; X86-BASELINE-NEXT: jmp .LBB17_3851; X86-BASELINE-NEXT: .LBB17_1:852; X86-BASELINE-NEXT: movl %esi, %eax853; X86-BASELINE-NEXT: .LBB17_3:854; X86-BASELINE-NEXT: andl {{[0-9]+}}(%esp), %eax855; X86-BASELINE-NEXT: andl {{[0-9]+}}(%esp), %edx856; X86-BASELINE-NEXT: popl %esi857; X86-BASELINE-NEXT: retl858;859; X86-BMI1-LABEL: clear_highbits64_c4_commutative:860; X86-BMI1: # %bb.0:861; X86-BMI1-NEXT: pushl %esi862; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx863; X86-BMI1-NEXT: movl $-1, %esi864; X86-BMI1-NEXT: movl $-1, %eax865; X86-BMI1-NEXT: shrl %cl, %eax866; X86-BMI1-NEXT: xorl %edx, %edx867; X86-BMI1-NEXT: testb $32, %cl868; X86-BMI1-NEXT: cmovel %eax, %edx869; X86-BMI1-NEXT: cmovel %esi, %eax870; X86-BMI1-NEXT: andl {{[0-9]+}}(%esp), %eax871; X86-BMI1-NEXT: andl {{[0-9]+}}(%esp), %edx872; X86-BMI1-NEXT: popl %esi873; X86-BMI1-NEXT: retl874;875; X86-BMI2-LABEL: clear_highbits64_c4_commutative:876; X86-BMI2: # %bb.0:877; X86-BMI2-NEXT: pushl %esi878; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx879; X86-BMI2-NEXT: movl $-1, %eax880; X86-BMI2-NEXT: shrxl %ecx, %eax, %esi881; X86-BMI2-NEXT: xorl %edx, %edx882; X86-BMI2-NEXT: testb $32, %cl883; X86-BMI2-NEXT: cmovel %esi, %edx884; X86-BMI2-NEXT: cmovnel %esi, %eax885; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax886; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx887; X86-BMI2-NEXT: popl %esi888; X86-BMI2-NEXT: retl889;890; X64-NOBMI2-LABEL: clear_highbits64_c4_commutative:891; X64-NOBMI2: # %bb.0:892; X64-NOBMI2-NEXT: movq %rsi, %rcx893; X64-NOBMI2-NEXT: movq %rdi, %rax894; X64-NOBMI2-NEXT: shlq %cl, %rax895; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx896; X64-NOBMI2-NEXT: shrq %cl, %rax897; X64-NOBMI2-NEXT: retq898;899; X64-BMI2-LABEL: clear_highbits64_c4_commutative:900; X64-BMI2: # %bb.0:901; X64-BMI2-NEXT: movl $64, %eax902; X64-BMI2-NEXT: subl %esi, %eax903; X64-BMI2-NEXT: bzhiq %rax, %rdi, %rax904; X64-BMI2-NEXT: retq905 %mask = lshr i64 -1, %numhighbits906 %masked = and i64 %val, %mask ; swapped order907 ret i64 %masked908}909 910; ---------------------------------------------------------------------------- ;911; Multi-use tests912; ---------------------------------------------------------------------------- ;913 914define i32 @oneuse32_c(i32 %val, i32 %numhighbits, ptr %escape) nounwind {915; X86-NOBMI2-LABEL: oneuse32_c:916; X86-NOBMI2: # %bb.0:917; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %edx918; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx919; X86-NOBMI2-NEXT: movl $-1, %eax920; X86-NOBMI2-NEXT: shrl %cl, %eax921; X86-NOBMI2-NEXT: movl %eax, (%edx)922; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %eax923; X86-NOBMI2-NEXT: retl924;925; X86-BMI2-LABEL: oneuse32_c:926; X86-BMI2: # %bb.0:927; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx928; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax929; X86-BMI2-NEXT: movl $-1, %edx930; X86-BMI2-NEXT: shrxl %eax, %edx, %eax931; X86-BMI2-NEXT: movl %eax, (%ecx)932; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax933; X86-BMI2-NEXT: retl934;935; X64-NOBMI2-LABEL: oneuse32_c:936; X64-NOBMI2: # %bb.0:937; X64-NOBMI2-NEXT: movl %esi, %ecx938; X64-NOBMI2-NEXT: movl $-1, %eax939; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx940; X64-NOBMI2-NEXT: shrl %cl, %eax941; X64-NOBMI2-NEXT: movl %eax, (%rdx)942; X64-NOBMI2-NEXT: andl %edi, %eax943; X64-NOBMI2-NEXT: retq944;945; X64-BMI2-LABEL: oneuse32_c:946; X64-BMI2: # %bb.0:947; X64-BMI2-NEXT: movl $-1, %eax948; X64-BMI2-NEXT: shrxl %esi, %eax, %eax949; X64-BMI2-NEXT: movl %eax, (%rdx)950; X64-BMI2-NEXT: andl %edi, %eax951; X64-BMI2-NEXT: retq952 %mask = lshr i32 -1, %numhighbits953 store i32 %mask, ptr %escape954 %masked = and i32 %mask, %val955 ret i32 %masked956}957 958define i64 @oneuse64_c(i64 %val, i64 %numhighbits, ptr %escape) nounwind {959; X86-BASELINE-LABEL: oneuse64_c:960; X86-BASELINE: # %bb.0:961; X86-BASELINE-NEXT: pushl %esi962; X86-BASELINE-NEXT: movl {{[0-9]+}}(%esp), %esi963; X86-BASELINE-NEXT: movzbl {{[0-9]+}}(%esp), %ecx964; X86-BASELINE-NEXT: movl $-1, %eax965; X86-BASELINE-NEXT: movl $-1, %edx966; X86-BASELINE-NEXT: shrl %cl, %edx967; X86-BASELINE-NEXT: testb $32, %cl968; X86-BASELINE-NEXT: je .LBB19_2969; X86-BASELINE-NEXT: # %bb.1:970; X86-BASELINE-NEXT: movl %edx, %eax971; X86-BASELINE-NEXT: xorl %edx, %edx972; X86-BASELINE-NEXT: .LBB19_2:973; X86-BASELINE-NEXT: movl %edx, 4(%esi)974; X86-BASELINE-NEXT: movl %eax, (%esi)975; X86-BASELINE-NEXT: andl {{[0-9]+}}(%esp), %eax976; X86-BASELINE-NEXT: andl {{[0-9]+}}(%esp), %edx977; X86-BASELINE-NEXT: popl %esi978; X86-BASELINE-NEXT: retl979;980; X86-BMI1-LABEL: oneuse64_c:981; X86-BMI1: # %bb.0:982; X86-BMI1-NEXT: pushl %edi983; X86-BMI1-NEXT: pushl %esi984; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi985; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx986; X86-BMI1-NEXT: movl $-1, %eax987; X86-BMI1-NEXT: movl $-1, %edi988; X86-BMI1-NEXT: shrl %cl, %edi989; X86-BMI1-NEXT: xorl %edx, %edx990; X86-BMI1-NEXT: testb $32, %cl991; X86-BMI1-NEXT: cmovnel %edi, %eax992; X86-BMI1-NEXT: cmovel %edi, %edx993; X86-BMI1-NEXT: movl %edx, 4(%esi)994; X86-BMI1-NEXT: movl %eax, (%esi)995; X86-BMI1-NEXT: andl {{[0-9]+}}(%esp), %eax996; X86-BMI1-NEXT: andl {{[0-9]+}}(%esp), %edx997; X86-BMI1-NEXT: popl %esi998; X86-BMI1-NEXT: popl %edi999; X86-BMI1-NEXT: retl1000;1001; X86-BMI2-LABEL: oneuse64_c:1002; X86-BMI2: # %bb.0:1003; X86-BMI2-NEXT: pushl %ebx1004; X86-BMI2-NEXT: pushl %esi1005; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx1006; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx1007; X86-BMI2-NEXT: movl $-1, %eax1008; X86-BMI2-NEXT: shrxl %ebx, %eax, %esi1009; X86-BMI2-NEXT: xorl %edx, %edx1010; X86-BMI2-NEXT: testb $32, %bl1011; X86-BMI2-NEXT: cmovnel %esi, %eax1012; X86-BMI2-NEXT: cmovel %esi, %edx1013; X86-BMI2-NEXT: movl %edx, 4(%ecx)1014; X86-BMI2-NEXT: movl %eax, (%ecx)1015; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax1016; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx1017; X86-BMI2-NEXT: popl %esi1018; X86-BMI2-NEXT: popl %ebx1019; X86-BMI2-NEXT: retl1020;1021; X64-NOBMI2-LABEL: oneuse64_c:1022; X64-NOBMI2: # %bb.0:1023; X64-NOBMI2-NEXT: movq %rsi, %rcx1024; X64-NOBMI2-NEXT: movq $-1, %rax1025; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx1026; X64-NOBMI2-NEXT: shrq %cl, %rax1027; X64-NOBMI2-NEXT: movq %rax, (%rdx)1028; X64-NOBMI2-NEXT: andq %rdi, %rax1029; X64-NOBMI2-NEXT: retq1030;1031; X64-BMI2-LABEL: oneuse64_c:1032; X64-BMI2: # %bb.0:1033; X64-BMI2-NEXT: movq $-1, %rax1034; X64-BMI2-NEXT: shrxq %rsi, %rax, %rax1035; X64-BMI2-NEXT: movq %rax, (%rdx)1036; X64-BMI2-NEXT: andq %rdi, %rax1037; X64-BMI2-NEXT: retq1038 %mask = lshr i64 -1, %numhighbits1039 store i64 %mask, ptr %escape1040 %masked = and i64 %mask, %val1041 ret i64 %masked1042}1043 1044define i32 @oneuse32_d(i32 %val, i32 %numhighbits, ptr %escape) nounwind {1045; X86-NOBMI2-LABEL: oneuse32_d:1046; X86-NOBMI2: # %bb.0:1047; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %edx1048; X86-NOBMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx1049; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax1050; X86-NOBMI2-NEXT: shll %cl, %eax1051; X86-NOBMI2-NEXT: movl %eax, (%edx)1052; X86-NOBMI2-NEXT: shrl %cl, %eax1053; X86-NOBMI2-NEXT: retl1054;1055; X86-BMI2-LABEL: oneuse32_d:1056; X86-BMI2: # %bb.0:1057; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax1058; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx1059; X86-BMI2-NEXT: shlxl %ecx, {{[0-9]+}}(%esp), %edx1060; X86-BMI2-NEXT: movl %edx, (%eax)1061; X86-BMI2-NEXT: shrxl %ecx, %edx, %eax1062; X86-BMI2-NEXT: retl1063;1064; X64-NOBMI2-LABEL: oneuse32_d:1065; X64-NOBMI2: # %bb.0:1066; X64-NOBMI2-NEXT: movl %esi, %ecx1067; X64-NOBMI2-NEXT: movl %edi, %eax1068; X64-NOBMI2-NEXT: shll %cl, %eax1069; X64-NOBMI2-NEXT: movl %eax, (%rdx)1070; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx1071; X64-NOBMI2-NEXT: shrl %cl, %eax1072; X64-NOBMI2-NEXT: retq1073;1074; X64-BMI2-LABEL: oneuse32_d:1075; X64-BMI2: # %bb.0:1076; X64-BMI2-NEXT: shlxl %esi, %edi, %eax1077; X64-BMI2-NEXT: movl %eax, (%rdx)1078; X64-BMI2-NEXT: shrxl %esi, %eax, %eax1079; X64-BMI2-NEXT: retq1080 %sh1 = shl i32 %val, %numhighbits1081 store i32 %sh1, ptr %escape1082 %masked = lshr i32 %sh1, %numhighbits1083 ret i32 %masked1084}1085 1086define i64 @oneusei64_d(i64 %val, i64 %numhighbits, ptr %escape) nounwind {1087; X86-BASELINE-LABEL: oneusei64_d:1088; X86-BASELINE: # %bb.0:1089; X86-BASELINE-NEXT: pushl %ebx1090; X86-BASELINE-NEXT: pushl %edi1091; X86-BASELINE-NEXT: pushl %esi1092; X86-BASELINE-NEXT: movzbl {{[0-9]+}}(%esp), %ecx1093; X86-BASELINE-NEXT: movl {{[0-9]+}}(%esp), %edx1094; X86-BASELINE-NEXT: movl {{[0-9]+}}(%esp), %eax1095; X86-BASELINE-NEXT: movl %edx, %edi1096; X86-BASELINE-NEXT: shll %cl, %edi1097; X86-BASELINE-NEXT: shldl %cl, %edx, %eax1098; X86-BASELINE-NEXT: testb $32, %cl1099; X86-BASELINE-NEXT: movl %edi, %esi1100; X86-BASELINE-NEXT: jne .LBB21_21101; X86-BASELINE-NEXT: # %bb.1:1102; X86-BASELINE-NEXT: movl %eax, %esi1103; X86-BASELINE-NEXT: .LBB21_2:1104; X86-BASELINE-NEXT: movl %esi, %eax1105; X86-BASELINE-NEXT: shrl %cl, %eax1106; X86-BASELINE-NEXT: xorl %ebx, %ebx1107; X86-BASELINE-NEXT: testb $32, %cl1108; X86-BASELINE-NEXT: movl $0, %edx1109; X86-BASELINE-NEXT: jne .LBB21_41110; X86-BASELINE-NEXT: # %bb.3:1111; X86-BASELINE-NEXT: movl %edi, %ebx1112; X86-BASELINE-NEXT: movl %eax, %edx1113; X86-BASELINE-NEXT: .LBB21_4:1114; X86-BASELINE-NEXT: movl %ebx, %edi1115; X86-BASELINE-NEXT: shrdl %cl, %esi, %edi1116; X86-BASELINE-NEXT: testb $32, %cl1117; X86-BASELINE-NEXT: movl {{[0-9]+}}(%esp), %ecx1118; X86-BASELINE-NEXT: movl %ebx, (%ecx)1119; X86-BASELINE-NEXT: movl %esi, 4(%ecx)1120; X86-BASELINE-NEXT: jne .LBB21_61121; X86-BASELINE-NEXT: # %bb.5:1122; X86-BASELINE-NEXT: movl %edi, %eax1123; X86-BASELINE-NEXT: .LBB21_6:1124; X86-BASELINE-NEXT: popl %esi1125; X86-BASELINE-NEXT: popl %edi1126; X86-BASELINE-NEXT: popl %ebx1127; X86-BASELINE-NEXT: retl1128;1129; X86-BMI1-LABEL: oneusei64_d:1130; X86-BMI1: # %bb.0:1131; X86-BMI1-NEXT: pushl %ebx1132; X86-BMI1-NEXT: pushl %edi1133; X86-BMI1-NEXT: pushl %esi1134; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx1135; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edx1136; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi1137; X86-BMI1-NEXT: movl %edx, %eax1138; X86-BMI1-NEXT: shll %cl, %eax1139; X86-BMI1-NEXT: shldl %cl, %edx, %esi1140; X86-BMI1-NEXT: testb $32, %cl1141; X86-BMI1-NEXT: cmovnel %eax, %esi1142; X86-BMI1-NEXT: movl %esi, %edi1143; X86-BMI1-NEXT: shrl %cl, %edi1144; X86-BMI1-NEXT: xorl %edx, %edx1145; X86-BMI1-NEXT: testb $32, %cl1146; X86-BMI1-NEXT: cmovnel %edx, %eax1147; X86-BMI1-NEXT: cmovel %edi, %edx1148; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %ebx1149; X86-BMI1-NEXT: movl %eax, (%ebx)1150; X86-BMI1-NEXT: shrdl %cl, %esi, %eax1151; X86-BMI1-NEXT: testb $32, %cl1152; X86-BMI1-NEXT: movl %esi, 4(%ebx)1153; X86-BMI1-NEXT: cmovnel %edi, %eax1154; X86-BMI1-NEXT: popl %esi1155; X86-BMI1-NEXT: popl %edi1156; X86-BMI1-NEXT: popl %ebx1157; X86-BMI1-NEXT: retl1158;1159; X86-BMI2-LABEL: oneusei64_d:1160; X86-BMI2: # %bb.0:1161; X86-BMI2-NEXT: pushl %ebx1162; X86-BMI2-NEXT: pushl %edi1163; X86-BMI2-NEXT: pushl %esi1164; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx1165; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax1166; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi1167; X86-BMI2-NEXT: shldl %cl, %eax, %esi1168; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax1169; X86-BMI2-NEXT: xorl %edx, %edx1170; X86-BMI2-NEXT: testb $32, %cl1171; X86-BMI2-NEXT: cmovnel %eax, %esi1172; X86-BMI2-NEXT: cmovnel %edx, %eax1173; X86-BMI2-NEXT: shrxl %ecx, %esi, %edi1174; X86-BMI2-NEXT: cmovel %edi, %edx1175; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ebx1176; X86-BMI2-NEXT: movl %eax, (%ebx)1177; X86-BMI2-NEXT: shrdl %cl, %esi, %eax1178; X86-BMI2-NEXT: testb $32, %cl1179; X86-BMI2-NEXT: movl %esi, 4(%ebx)1180; X86-BMI2-NEXT: cmovnel %edi, %eax1181; X86-BMI2-NEXT: popl %esi1182; X86-BMI2-NEXT: popl %edi1183; X86-BMI2-NEXT: popl %ebx1184; X86-BMI2-NEXT: retl1185;1186; X64-NOBMI2-LABEL: oneusei64_d:1187; X64-NOBMI2: # %bb.0:1188; X64-NOBMI2-NEXT: movq %rsi, %rcx1189; X64-NOBMI2-NEXT: movq %rdi, %rax1190; X64-NOBMI2-NEXT: shlq %cl, %rax1191; X64-NOBMI2-NEXT: movq %rax, (%rdx)1192; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx1193; X64-NOBMI2-NEXT: shrq %cl, %rax1194; X64-NOBMI2-NEXT: retq1195;1196; X64-BMI2-LABEL: oneusei64_d:1197; X64-BMI2: # %bb.0:1198; X64-BMI2-NEXT: shlxq %rsi, %rdi, %rax1199; X64-BMI2-NEXT: movq %rax, (%rdx)1200; X64-BMI2-NEXT: shrxq %rsi, %rax, %rax1201; X64-BMI2-NEXT: retq1202 %sh1 = shl i64 %val, %numhighbits1203 store i64 %sh1, ptr %escape1204 %masked = lshr i64 %sh1, %numhighbits1205 ret i64 %masked1206}1207 1208; ---------------------------------------------------------------------------- ;1209; Misc.1210;1211; Variation of pattern1212; c) x & (-1 >> (C - y))1213; but with C != bitwidth(x)1214; ---------------------------------------------------------------------------- ;1215 1216define i32 @clear_highbits32_16(i32 %val, i32 %numlowbits) nounwind {1217; X86-NOBMI2-LABEL: clear_highbits32_16:1218; X86-NOBMI2: # %bb.0:1219; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax1220; X86-NOBMI2-NEXT: movb $16, %cl1221; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl1222; X86-NOBMI2-NEXT: shll %cl, %eax1223; X86-NOBMI2-NEXT: shrl %cl, %eax1224; X86-NOBMI2-NEXT: retl1225;1226; X86-BMI2-LABEL: clear_highbits32_16:1227; X86-BMI2: # %bb.0:1228; X86-BMI2-NEXT: movb $16, %al1229; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al1230; X86-BMI2-NEXT: movl $32, %ecx1231; X86-BMI2-NEXT: subl %eax, %ecx1232; X86-BMI2-NEXT: bzhil %ecx, {{[0-9]+}}(%esp), %eax1233; X86-BMI2-NEXT: retl1234;1235; X64-NOBMI2-LABEL: clear_highbits32_16:1236; X64-NOBMI2: # %bb.0:1237; X64-NOBMI2-NEXT: movl %edi, %eax1238; X64-NOBMI2-NEXT: movb $16, %cl1239; X64-NOBMI2-NEXT: subb %sil, %cl1240; X64-NOBMI2-NEXT: shll %cl, %eax1241; X64-NOBMI2-NEXT: shrl %cl, %eax1242; X64-NOBMI2-NEXT: retq1243;1244; X64-BMI2-LABEL: clear_highbits32_16:1245; X64-BMI2: # %bb.0:1246; X64-BMI2-NEXT: movb $16, %al1247; X64-BMI2-NEXT: subb %sil, %al1248; X64-BMI2-NEXT: movl $32, %ecx1249; X64-BMI2-NEXT: subl %eax, %ecx1250; X64-BMI2-NEXT: bzhil %ecx, %edi, %eax1251; X64-BMI2-NEXT: retq1252 %numhighbits = sub i32 16, %numlowbits1253 %mask = lshr i32 -1, %numhighbits1254 %masked = and i32 %mask, %val1255 ret i32 %masked1256}1257define i32 @clear_highbits32_48(i32 %val, i32 %numlowbits) nounwind {1258; X86-NOBMI2-LABEL: clear_highbits32_48:1259; X86-NOBMI2: # %bb.0:1260; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax1261; X86-NOBMI2-NEXT: movb $48, %cl1262; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl1263; X86-NOBMI2-NEXT: shll %cl, %eax1264; X86-NOBMI2-NEXT: shrl %cl, %eax1265; X86-NOBMI2-NEXT: retl1266;1267; X86-BMI2-LABEL: clear_highbits32_48:1268; X86-BMI2: # %bb.0:1269; X86-BMI2-NEXT: movb $48, %al1270; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al1271; X86-BMI2-NEXT: movl $32, %ecx1272; X86-BMI2-NEXT: subl %eax, %ecx1273; X86-BMI2-NEXT: bzhil %ecx, {{[0-9]+}}(%esp), %eax1274; X86-BMI2-NEXT: retl1275;1276; X64-NOBMI2-LABEL: clear_highbits32_48:1277; X64-NOBMI2: # %bb.0:1278; X64-NOBMI2-NEXT: movl %edi, %eax1279; X64-NOBMI2-NEXT: movb $48, %cl1280; X64-NOBMI2-NEXT: subb %sil, %cl1281; X64-NOBMI2-NEXT: shll %cl, %eax1282; X64-NOBMI2-NEXT: shrl %cl, %eax1283; X64-NOBMI2-NEXT: retq1284;1285; X64-BMI2-LABEL: clear_highbits32_48:1286; X64-BMI2: # %bb.0:1287; X64-BMI2-NEXT: movb $48, %al1288; X64-BMI2-NEXT: subb %sil, %al1289; X64-BMI2-NEXT: movl $32, %ecx1290; X64-BMI2-NEXT: subl %eax, %ecx1291; X64-BMI2-NEXT: bzhil %ecx, %edi, %eax1292; X64-BMI2-NEXT: retq1293 %numhighbits = sub i32 48, %numlowbits1294 %mask = lshr i32 -1, %numhighbits1295 %masked = and i32 %mask, %val1296 ret i32 %masked1297}1298 1299define i32 @clear_highbits32_16_extrause(i32 %val, i32 %numlowbits, ptr %escape) nounwind {1300; X86-NOBMI2-LABEL: clear_highbits32_16_extrause:1301; X86-NOBMI2: # %bb.0:1302; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %edx1303; X86-NOBMI2-NEXT: movb $16, %cl1304; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl1305; X86-NOBMI2-NEXT: movl $-1, %eax1306; X86-NOBMI2-NEXT: shrl %cl, %eax1307; X86-NOBMI2-NEXT: movl %eax, (%edx)1308; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %eax1309; X86-NOBMI2-NEXT: retl1310;1311; X86-BMI2-LABEL: clear_highbits32_16_extrause:1312; X86-BMI2: # %bb.0:1313; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx1314; X86-BMI2-NEXT: movb $16, %al1315; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al1316; X86-BMI2-NEXT: movl $-1, %edx1317; X86-BMI2-NEXT: shrxl %eax, %edx, %eax1318; X86-BMI2-NEXT: movl %eax, (%ecx)1319; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax1320; X86-BMI2-NEXT: retl1321;1322; X64-NOBMI2-LABEL: clear_highbits32_16_extrause:1323; X64-NOBMI2: # %bb.0:1324; X64-NOBMI2-NEXT: movb $16, %cl1325; X64-NOBMI2-NEXT: subb %sil, %cl1326; X64-NOBMI2-NEXT: movl $-1, %eax1327; X64-NOBMI2-NEXT: shrl %cl, %eax1328; X64-NOBMI2-NEXT: movl %eax, (%rdx)1329; X64-NOBMI2-NEXT: andl %edi, %eax1330; X64-NOBMI2-NEXT: retq1331;1332; X64-BMI2-LABEL: clear_highbits32_16_extrause:1333; X64-BMI2: # %bb.0:1334; X64-BMI2-NEXT: movb $16, %al1335; X64-BMI2-NEXT: subb %sil, %al1336; X64-BMI2-NEXT: movl $-1, %ecx1337; X64-BMI2-NEXT: shrxl %eax, %ecx, %eax1338; X64-BMI2-NEXT: movl %eax, (%rdx)1339; X64-BMI2-NEXT: andl %edi, %eax1340; X64-BMI2-NEXT: retq1341 %numhighbits = sub i32 16, %numlowbits1342 %mask = lshr i32 -1, %numhighbits1343 store i32 %mask, ptr %escape1344 %masked = and i32 %mask, %val1345 ret i32 %masked1346}1347define i32 @clear_highbits32_48_extrause(i32 %val, i32 %numlowbits, ptr %escape) nounwind {1348; X86-NOBMI2-LABEL: clear_highbits32_48_extrause:1349; X86-NOBMI2: # %bb.0:1350; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %edx1351; X86-NOBMI2-NEXT: movb $48, %cl1352; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl1353; X86-NOBMI2-NEXT: movl $-1, %eax1354; X86-NOBMI2-NEXT: shrl %cl, %eax1355; X86-NOBMI2-NEXT: movl %eax, (%edx)1356; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %eax1357; X86-NOBMI2-NEXT: retl1358;1359; X86-BMI2-LABEL: clear_highbits32_48_extrause:1360; X86-BMI2: # %bb.0:1361; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx1362; X86-BMI2-NEXT: movb $48, %al1363; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al1364; X86-BMI2-NEXT: movl $-1, %edx1365; X86-BMI2-NEXT: shrxl %eax, %edx, %eax1366; X86-BMI2-NEXT: movl %eax, (%ecx)1367; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax1368; X86-BMI2-NEXT: retl1369;1370; X64-NOBMI2-LABEL: clear_highbits32_48_extrause:1371; X64-NOBMI2: # %bb.0:1372; X64-NOBMI2-NEXT: movb $48, %cl1373; X64-NOBMI2-NEXT: subb %sil, %cl1374; X64-NOBMI2-NEXT: movl $-1, %eax1375; X64-NOBMI2-NEXT: shrl %cl, %eax1376; X64-NOBMI2-NEXT: movl %eax, (%rdx)1377; X64-NOBMI2-NEXT: andl %edi, %eax1378; X64-NOBMI2-NEXT: retq1379;1380; X64-BMI2-LABEL: clear_highbits32_48_extrause:1381; X64-BMI2: # %bb.0:1382; X64-BMI2-NEXT: movb $48, %al1383; X64-BMI2-NEXT: subb %sil, %al1384; X64-BMI2-NEXT: movl $-1, %ecx1385; X64-BMI2-NEXT: shrxl %eax, %ecx, %eax1386; X64-BMI2-NEXT: movl %eax, (%rdx)1387; X64-BMI2-NEXT: andl %edi, %eax1388; X64-BMI2-NEXT: retq1389 %numhighbits = sub i32 48, %numlowbits1390 %mask = lshr i32 -1, %numhighbits1391 store i32 %mask, ptr %escape1392 %masked = and i32 %mask, %val1393 ret i32 %masked1394}1395