1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,NOBMI,X86-NOBMI 3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI1,X86-BMI1,BMI1NOTBM,X86-BMI1NOTBM 4; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI1,X86-BMI1,BMI1TBM,X86-BMI1TBM 5; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI1,X86-BMI1,BMI1BMI2,X86-BMI1BMI2,BMI1TBM,X86-BMI1TBM,BMI1TBMBMI2,X86-BMI1TBMBMI2 6; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI1,X86-BMI1,BMI1BMI2,X86-BMI1BMI2,BMI1NOTBMBMI2,X86-BMI1NOTBMBMI2 7; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI,X64-NOBMI 8; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI1,X64-BMI1,BMI1NOTBM,X64-BMI1NOTBM 9; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI1,X64-BMI1,BMI1TBM,X64-BMI1TBM 10; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI1,X64-BMI1,BMI1BMI2,X64-BMI1BMI2,BMI1TBM,X64-BMI1TBM,BMI1TBMBMI2,X64-BMI1TBMBMI2 11; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI1,X64-BMI1,BMI1BMI2,X64-BMI1BMI2,BMI1NOTBMBMI2,X64-BMI1NOTBMBMI2 12 13; *Please* keep in sync with test/CodeGen/AArch64/extract-lowbits.ll 14 15; https://bugs.llvm.org/show_bug.cgi?id=36419 16; https://bugs.llvm.org/show_bug.cgi?id=37603 17; https://bugs.llvm.org/show_bug.cgi?id=37610 18 19; Patterns: 20; a) x & (1 << nbits) - 1 21; b) x & ~(-1 << nbits) 22; c) x & (-1 >> (32 - y)) 23; d) x << (32 - y) >> (32 - y) 24; are equivalent. 25 26; ---------------------------------------------------------------------------- ; 27; Pattern a. 32-bit 28; ---------------------------------------------------------------------------- ; 29 30define i32 @bzhi32_a0(i32 %val, i32 %numlowbits) nounwind { 31; X86-NOBMI-LABEL: bzhi32_a0: 32; X86-NOBMI: # %bb.0: 33; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 34; X86-NOBMI-NEXT: movl $1, %eax 35; X86-NOBMI-NEXT: shll %cl, %eax 36; X86-NOBMI-NEXT: decl %eax 37; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 38; X86-NOBMI-NEXT: retl 39; 40; X86-BMI1NOTBM-LABEL: bzhi32_a0: 41; X86-BMI1NOTBM: # %bb.0: 42; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %al 43; X86-BMI1NOTBM-NEXT: shll $8, %eax 44; X86-BMI1NOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 45; X86-BMI1NOTBM-NEXT: retl 46; 47; X86-BMI1BMI2-LABEL: bzhi32_a0: 48; X86-BMI1BMI2: # %bb.0: 49; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 50; X86-BMI1BMI2-NEXT: bzhil %eax, {{[0-9]+}}(%esp), %eax 51; X86-BMI1BMI2-NEXT: retl 52; 53; X64-NOBMI-LABEL: bzhi32_a0: 54; X64-NOBMI: # %bb.0: 55; X64-NOBMI-NEXT: movl %esi, %ecx 56; X64-NOBMI-NEXT: movl $1, %eax 57; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 58; X64-NOBMI-NEXT: shll %cl, %eax 59; X64-NOBMI-NEXT: decl %eax 60; X64-NOBMI-NEXT: andl %edi, %eax 61; X64-NOBMI-NEXT: retq 62; 63; X64-BMI1NOTBM-LABEL: bzhi32_a0: 64; X64-BMI1NOTBM: # %bb.0: 65; X64-BMI1NOTBM-NEXT: shll $8, %esi 66; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax 67; X64-BMI1NOTBM-NEXT: retq 68; 69; X64-BMI1BMI2-LABEL: bzhi32_a0: 70; X64-BMI1BMI2: # %bb.0: 71; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax 72; X64-BMI1BMI2-NEXT: retq 73 %onebit = shl i32 1, %numlowbits 74 %mask = add nsw i32 %onebit, -1 75 %masked = and i32 %mask, %val 76 ret i32 %masked 77} 78 79define i32 @bzhi32_a1_indexzext(i32 %val, i8 zeroext %numlowbits) nounwind { 80; X86-NOBMI-LABEL: bzhi32_a1_indexzext: 81; X86-NOBMI: # %bb.0: 82; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 83; X86-NOBMI-NEXT: movl $1, %eax 84; X86-NOBMI-NEXT: shll %cl, %eax 85; X86-NOBMI-NEXT: decl %eax 86; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 87; X86-NOBMI-NEXT: retl 88; 89; X86-BMI1NOTBM-LABEL: bzhi32_a1_indexzext: 90; X86-BMI1NOTBM: # %bb.0: 91; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %al 92; X86-BMI1NOTBM-NEXT: shll $8, %eax 93; X86-BMI1NOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 94; X86-BMI1NOTBM-NEXT: retl 95; 96; X86-BMI1BMI2-LABEL: bzhi32_a1_indexzext: 97; X86-BMI1BMI2: # %bb.0: 98; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 99; X86-BMI1BMI2-NEXT: bzhil %eax, {{[0-9]+}}(%esp), %eax 100; X86-BMI1BMI2-NEXT: retl 101; 102; X64-NOBMI-LABEL: bzhi32_a1_indexzext: 103; X64-NOBMI: # %bb.0: 104; X64-NOBMI-NEXT: movl %esi, %ecx 105; X64-NOBMI-NEXT: movl $1, %eax 106; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 107; X64-NOBMI-NEXT: shll %cl, %eax 108; X64-NOBMI-NEXT: decl %eax 109; X64-NOBMI-NEXT: andl %edi, %eax 110; X64-NOBMI-NEXT: retq 111; 112; X64-BMI1NOTBM-LABEL: bzhi32_a1_indexzext: 113; X64-BMI1NOTBM: # %bb.0: 114; X64-BMI1NOTBM-NEXT: shll $8, %esi 115; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax 116; X64-BMI1NOTBM-NEXT: retq 117; 118; X64-BMI1BMI2-LABEL: bzhi32_a1_indexzext: 119; X64-BMI1BMI2: # %bb.0: 120; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax 121; X64-BMI1BMI2-NEXT: retq 122 %conv = zext i8 %numlowbits to i32 123 %onebit = shl i32 1, %conv 124 %mask = add nsw i32 %onebit, -1 125 %masked = and i32 %mask, %val 126 ret i32 %masked 127} 128 129define i32 @bzhi32_a2_load(i32* %w, i32 %numlowbits) nounwind { 130; X86-NOBMI-LABEL: bzhi32_a2_load: 131; X86-NOBMI: # %bb.0: 132; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 133; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 134; X86-NOBMI-NEXT: movl $1, %eax 135; X86-NOBMI-NEXT: shll %cl, %eax 136; X86-NOBMI-NEXT: decl %eax 137; X86-NOBMI-NEXT: andl (%edx), %eax 138; X86-NOBMI-NEXT: retl 139; 140; X86-BMI1NOTBM-LABEL: bzhi32_a2_load: 141; X86-BMI1NOTBM: # %bb.0: 142; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 143; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 144; X86-BMI1NOTBM-NEXT: shll $8, %ecx 145; X86-BMI1NOTBM-NEXT: bextrl %ecx, (%eax), %eax 146; X86-BMI1NOTBM-NEXT: retl 147; 148; X86-BMI1BMI2-LABEL: bzhi32_a2_load: 149; X86-BMI1BMI2: # %bb.0: 150; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 151; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 152; X86-BMI1BMI2-NEXT: bzhil %ecx, (%eax), %eax 153; X86-BMI1BMI2-NEXT: retl 154; 155; X64-NOBMI-LABEL: bzhi32_a2_load: 156; X64-NOBMI: # %bb.0: 157; X64-NOBMI-NEXT: movl %esi, %ecx 158; X64-NOBMI-NEXT: movl $1, %eax 159; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 160; X64-NOBMI-NEXT: shll %cl, %eax 161; X64-NOBMI-NEXT: decl %eax 162; X64-NOBMI-NEXT: andl (%rdi), %eax 163; X64-NOBMI-NEXT: retq 164; 165; X64-BMI1NOTBM-LABEL: bzhi32_a2_load: 166; X64-BMI1NOTBM: # %bb.0: 167; X64-BMI1NOTBM-NEXT: shll $8, %esi 168; X64-BMI1NOTBM-NEXT: bextrl %esi, (%rdi), %eax 169; X64-BMI1NOTBM-NEXT: retq 170; 171; X64-BMI1BMI2-LABEL: bzhi32_a2_load: 172; X64-BMI1BMI2: # %bb.0: 173; X64-BMI1BMI2-NEXT: bzhil %esi, (%rdi), %eax 174; X64-BMI1BMI2-NEXT: retq 175 %val = load i32, i32* %w 176 %onebit = shl i32 1, %numlowbits 177 %mask = add nsw i32 %onebit, -1 178 %masked = and i32 %mask, %val 179 ret i32 %masked 180} 181 182define i32 @bzhi32_a3_load_indexzext(i32* %w, i8 zeroext %numlowbits) nounwind { 183; X86-NOBMI-LABEL: bzhi32_a3_load_indexzext: 184; X86-NOBMI: # %bb.0: 185; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 186; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 187; X86-NOBMI-NEXT: movl $1, %eax 188; X86-NOBMI-NEXT: shll %cl, %eax 189; X86-NOBMI-NEXT: decl %eax 190; X86-NOBMI-NEXT: andl (%edx), %eax 191; X86-NOBMI-NEXT: retl 192; 193; X86-BMI1NOTBM-LABEL: bzhi32_a3_load_indexzext: 194; X86-BMI1NOTBM: # %bb.0: 195; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 196; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 197; X86-BMI1NOTBM-NEXT: shll $8, %ecx 198; X86-BMI1NOTBM-NEXT: bextrl %ecx, (%eax), %eax 199; X86-BMI1NOTBM-NEXT: retl 200; 201; X86-BMI1BMI2-LABEL: bzhi32_a3_load_indexzext: 202; X86-BMI1BMI2: # %bb.0: 203; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 204; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 205; X86-BMI1BMI2-NEXT: bzhil %ecx, (%eax), %eax 206; X86-BMI1BMI2-NEXT: retl 207; 208; X64-NOBMI-LABEL: bzhi32_a3_load_indexzext: 209; X64-NOBMI: # %bb.0: 210; X64-NOBMI-NEXT: movl %esi, %ecx 211; X64-NOBMI-NEXT: movl $1, %eax 212; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 213; X64-NOBMI-NEXT: shll %cl, %eax 214; X64-NOBMI-NEXT: decl %eax 215; X64-NOBMI-NEXT: andl (%rdi), %eax 216; X64-NOBMI-NEXT: retq 217; 218; X64-BMI1NOTBM-LABEL: bzhi32_a3_load_indexzext: 219; X64-BMI1NOTBM: # %bb.0: 220; X64-BMI1NOTBM-NEXT: shll $8, %esi 221; X64-BMI1NOTBM-NEXT: bextrl %esi, (%rdi), %eax 222; X64-BMI1NOTBM-NEXT: retq 223; 224; X64-BMI1BMI2-LABEL: bzhi32_a3_load_indexzext: 225; X64-BMI1BMI2: # %bb.0: 226; X64-BMI1BMI2-NEXT: bzhil %esi, (%rdi), %eax 227; X64-BMI1BMI2-NEXT: retq 228 %val = load i32, i32* %w 229 %conv = zext i8 %numlowbits to i32 230 %onebit = shl i32 1, %conv 231 %mask = add nsw i32 %onebit, -1 232 %masked = and i32 %mask, %val 233 ret i32 %masked 234} 235 236define i32 @bzhi32_a4_commutative(i32 %val, i32 %numlowbits) nounwind { 237; X86-NOBMI-LABEL: bzhi32_a4_commutative: 238; X86-NOBMI: # %bb.0: 239; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 240; X86-NOBMI-NEXT: movl $1, %eax 241; X86-NOBMI-NEXT: shll %cl, %eax 242; X86-NOBMI-NEXT: decl %eax 243; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 244; X86-NOBMI-NEXT: retl 245; 246; X86-BMI1NOTBM-LABEL: bzhi32_a4_commutative: 247; X86-BMI1NOTBM: # %bb.0: 248; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %al 249; X86-BMI1NOTBM-NEXT: shll $8, %eax 250; X86-BMI1NOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 251; X86-BMI1NOTBM-NEXT: retl 252; 253; X86-BMI1BMI2-LABEL: bzhi32_a4_commutative: 254; X86-BMI1BMI2: # %bb.0: 255; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 256; X86-BMI1BMI2-NEXT: bzhil %eax, {{[0-9]+}}(%esp), %eax 257; X86-BMI1BMI2-NEXT: retl 258; 259; X64-NOBMI-LABEL: bzhi32_a4_commutative: 260; X64-NOBMI: # %bb.0: 261; X64-NOBMI-NEXT: movl %esi, %ecx 262; X64-NOBMI-NEXT: movl $1, %eax 263; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 264; X64-NOBMI-NEXT: shll %cl, %eax 265; X64-NOBMI-NEXT: decl %eax 266; X64-NOBMI-NEXT: andl %edi, %eax 267; X64-NOBMI-NEXT: retq 268; 269; X64-BMI1NOTBM-LABEL: bzhi32_a4_commutative: 270; X64-BMI1NOTBM: # %bb.0: 271; X64-BMI1NOTBM-NEXT: shll $8, %esi 272; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax 273; X64-BMI1NOTBM-NEXT: retq 274; 275; X64-BMI1BMI2-LABEL: bzhi32_a4_commutative: 276; X64-BMI1BMI2: # %bb.0: 277; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax 278; X64-BMI1BMI2-NEXT: retq 279 %onebit = shl i32 1, %numlowbits 280 %mask = add nsw i32 %onebit, -1 281 %masked = and i32 %val, %mask ; swapped order 282 ret i32 %masked 283} 284 285; 64-bit 286 287define i64 @bzhi64_a0(i64 %val, i64 %numlowbits) nounwind { 288; X86-NOBMI-LABEL: bzhi64_a0: 289; X86-NOBMI: # %bb.0: 290; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 291; X86-NOBMI-NEXT: movl $1, %eax 292; X86-NOBMI-NEXT: xorl %edx, %edx 293; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 294; X86-NOBMI-NEXT: shll %cl, %eax 295; X86-NOBMI-NEXT: testb $32, %cl 296; X86-NOBMI-NEXT: je .LBB5_2 297; X86-NOBMI-NEXT: # %bb.1: 298; X86-NOBMI-NEXT: movl %eax, %edx 299; X86-NOBMI-NEXT: xorl %eax, %eax 300; X86-NOBMI-NEXT: .LBB5_2: 301; X86-NOBMI-NEXT: addl $-1, %eax 302; X86-NOBMI-NEXT: adcl $-1, %edx 303; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edx 304; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 305; X86-NOBMI-NEXT: retl 306; 307; X86-BMI1NOTBM-LABEL: bzhi64_a0: 308; X86-BMI1NOTBM: # %bb.0: 309; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 310; X86-BMI1NOTBM-NEXT: movl $1, %eax 311; X86-BMI1NOTBM-NEXT: xorl %edx, %edx 312; X86-BMI1NOTBM-NEXT: shldl %cl, %eax, %edx 313; X86-BMI1NOTBM-NEXT: shll %cl, %eax 314; X86-BMI1NOTBM-NEXT: testb $32, %cl 315; X86-BMI1NOTBM-NEXT: je .LBB5_2 316; X86-BMI1NOTBM-NEXT: # %bb.1: 317; X86-BMI1NOTBM-NEXT: movl %eax, %edx 318; X86-BMI1NOTBM-NEXT: xorl %eax, %eax 319; X86-BMI1NOTBM-NEXT: .LBB5_2: 320; X86-BMI1NOTBM-NEXT: addl $-1, %eax 321; X86-BMI1NOTBM-NEXT: adcl $-1, %edx 322; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %edx 323; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %eax 324; X86-BMI1NOTBM-NEXT: retl 325; 326; X86-BMI1BMI2-LABEL: bzhi64_a0: 327; X86-BMI1BMI2: # %bb.0: 328; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 329; X86-BMI1BMI2-NEXT: movl $1, %eax 330; X86-BMI1BMI2-NEXT: xorl %edx, %edx 331; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %edx 332; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %eax 333; X86-BMI1BMI2-NEXT: testb $32, %cl 334; X86-BMI1BMI2-NEXT: je .LBB5_2 335; X86-BMI1BMI2-NEXT: # %bb.1: 336; X86-BMI1BMI2-NEXT: movl %eax, %edx 337; X86-BMI1BMI2-NEXT: xorl %eax, %eax 338; X86-BMI1BMI2-NEXT: .LBB5_2: 339; X86-BMI1BMI2-NEXT: addl $-1, %eax 340; X86-BMI1BMI2-NEXT: adcl $-1, %edx 341; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 342; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 343; X86-BMI1BMI2-NEXT: retl 344; 345; X64-NOBMI-LABEL: bzhi64_a0: 346; X64-NOBMI: # %bb.0: 347; X64-NOBMI-NEXT: movq %rsi, %rcx 348; X64-NOBMI-NEXT: movl $1, %eax 349; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 350; X64-NOBMI-NEXT: shlq %cl, %rax 351; X64-NOBMI-NEXT: decq %rax 352; X64-NOBMI-NEXT: andq %rdi, %rax 353; X64-NOBMI-NEXT: retq 354; 355; X64-BMI1NOTBM-LABEL: bzhi64_a0: 356; X64-BMI1NOTBM: # %bb.0: 357; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 358; X64-BMI1NOTBM-NEXT: bextrq %rsi, %rdi, %rax 359; X64-BMI1NOTBM-NEXT: retq 360; 361; X64-BMI1BMI2-LABEL: bzhi64_a0: 362; X64-BMI1BMI2: # %bb.0: 363; X64-BMI1BMI2-NEXT: bzhiq %rsi, %rdi, %rax 364; X64-BMI1BMI2-NEXT: retq 365 %onebit = shl i64 1, %numlowbits 366 %mask = add nsw i64 %onebit, -1 367 %masked = and i64 %mask, %val 368 ret i64 %masked 369} 370 371define i64 @bzhi64_a1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind { 372; X86-NOBMI-LABEL: bzhi64_a1_indexzext: 373; X86-NOBMI: # %bb.0: 374; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 375; X86-NOBMI-NEXT: movl $1, %eax 376; X86-NOBMI-NEXT: xorl %edx, %edx 377; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 378; X86-NOBMI-NEXT: shll %cl, %eax 379; X86-NOBMI-NEXT: testb $32, %cl 380; X86-NOBMI-NEXT: je .LBB6_2 381; X86-NOBMI-NEXT: # %bb.1: 382; X86-NOBMI-NEXT: movl %eax, %edx 383; X86-NOBMI-NEXT: xorl %eax, %eax 384; X86-NOBMI-NEXT: .LBB6_2: 385; X86-NOBMI-NEXT: addl $-1, %eax 386; X86-NOBMI-NEXT: adcl $-1, %edx 387; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edx 388; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 389; X86-NOBMI-NEXT: retl 390; 391; X86-BMI1NOTBM-LABEL: bzhi64_a1_indexzext: 392; X86-BMI1NOTBM: # %bb.0: 393; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 394; X86-BMI1NOTBM-NEXT: movl $1, %eax 395; X86-BMI1NOTBM-NEXT: xorl %edx, %edx 396; X86-BMI1NOTBM-NEXT: shldl %cl, %eax, %edx 397; X86-BMI1NOTBM-NEXT: shll %cl, %eax 398; X86-BMI1NOTBM-NEXT: testb $32, %cl 399; X86-BMI1NOTBM-NEXT: je .LBB6_2 400; X86-BMI1NOTBM-NEXT: # %bb.1: 401; X86-BMI1NOTBM-NEXT: movl %eax, %edx 402; X86-BMI1NOTBM-NEXT: xorl %eax, %eax 403; X86-BMI1NOTBM-NEXT: .LBB6_2: 404; X86-BMI1NOTBM-NEXT: addl $-1, %eax 405; X86-BMI1NOTBM-NEXT: adcl $-1, %edx 406; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %edx 407; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %eax 408; X86-BMI1NOTBM-NEXT: retl 409; 410; X86-BMI1BMI2-LABEL: bzhi64_a1_indexzext: 411; X86-BMI1BMI2: # %bb.0: 412; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 413; X86-BMI1BMI2-NEXT: movl $1, %eax 414; X86-BMI1BMI2-NEXT: xorl %edx, %edx 415; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %edx 416; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %eax 417; X86-BMI1BMI2-NEXT: testb $32, %cl 418; X86-BMI1BMI2-NEXT: je .LBB6_2 419; X86-BMI1BMI2-NEXT: # %bb.1: 420; X86-BMI1BMI2-NEXT: movl %eax, %edx 421; X86-BMI1BMI2-NEXT: xorl %eax, %eax 422; X86-BMI1BMI2-NEXT: .LBB6_2: 423; X86-BMI1BMI2-NEXT: addl $-1, %eax 424; X86-BMI1BMI2-NEXT: adcl $-1, %edx 425; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 426; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 427; X86-BMI1BMI2-NEXT: retl 428; 429; X64-NOBMI-LABEL: bzhi64_a1_indexzext: 430; X64-NOBMI: # %bb.0: 431; X64-NOBMI-NEXT: movl %esi, %ecx 432; X64-NOBMI-NEXT: movl $1, %eax 433; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 434; X64-NOBMI-NEXT: shlq %cl, %rax 435; X64-NOBMI-NEXT: decq %rax 436; X64-NOBMI-NEXT: andq %rdi, %rax 437; X64-NOBMI-NEXT: retq 438; 439; X64-BMI1NOTBM-LABEL: bzhi64_a1_indexzext: 440; X64-BMI1NOTBM: # %bb.0: 441; X64-BMI1NOTBM-NEXT: # kill: def $esi killed $esi def $rsi 442; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 443; X64-BMI1NOTBM-NEXT: bextrq %rsi, %rdi, %rax 444; X64-BMI1NOTBM-NEXT: retq 445; 446; X64-BMI1BMI2-LABEL: bzhi64_a1_indexzext: 447; X64-BMI1BMI2: # %bb.0: 448; X64-BMI1BMI2-NEXT: # kill: def $esi killed $esi def $rsi 449; X64-BMI1BMI2-NEXT: bzhiq %rsi, %rdi, %rax 450; X64-BMI1BMI2-NEXT: retq 451 %conv = zext i8 %numlowbits to i64 452 %onebit = shl i64 1, %conv 453 %mask = add nsw i64 %onebit, -1 454 %masked = and i64 %mask, %val 455 ret i64 %masked 456} 457 458define i64 @bzhi64_a2_load(i64* %w, i64 %numlowbits) nounwind { 459; X86-NOBMI-LABEL: bzhi64_a2_load: 460; X86-NOBMI: # %bb.0: 461; X86-NOBMI-NEXT: pushl %esi 462; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 463; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 464; X86-NOBMI-NEXT: movl $1, %eax 465; X86-NOBMI-NEXT: xorl %edx, %edx 466; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 467; X86-NOBMI-NEXT: shll %cl, %eax 468; X86-NOBMI-NEXT: testb $32, %cl 469; X86-NOBMI-NEXT: je .LBB7_2 470; X86-NOBMI-NEXT: # %bb.1: 471; X86-NOBMI-NEXT: movl %eax, %edx 472; X86-NOBMI-NEXT: xorl %eax, %eax 473; X86-NOBMI-NEXT: .LBB7_2: 474; X86-NOBMI-NEXT: addl $-1, %eax 475; X86-NOBMI-NEXT: adcl $-1, %edx 476; X86-NOBMI-NEXT: andl 4(%esi), %edx 477; X86-NOBMI-NEXT: andl (%esi), %eax 478; X86-NOBMI-NEXT: popl %esi 479; X86-NOBMI-NEXT: retl 480; 481; X86-BMI1NOTBM-LABEL: bzhi64_a2_load: 482; X86-BMI1NOTBM: # %bb.0: 483; X86-BMI1NOTBM-NEXT: pushl %esi 484; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %esi 485; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 486; X86-BMI1NOTBM-NEXT: movl $1, %eax 487; X86-BMI1NOTBM-NEXT: xorl %edx, %edx 488; X86-BMI1NOTBM-NEXT: shldl %cl, %eax, %edx 489; X86-BMI1NOTBM-NEXT: shll %cl, %eax 490; X86-BMI1NOTBM-NEXT: testb $32, %cl 491; X86-BMI1NOTBM-NEXT: je .LBB7_2 492; X86-BMI1NOTBM-NEXT: # %bb.1: 493; X86-BMI1NOTBM-NEXT: movl %eax, %edx 494; X86-BMI1NOTBM-NEXT: xorl %eax, %eax 495; X86-BMI1NOTBM-NEXT: .LBB7_2: 496; X86-BMI1NOTBM-NEXT: addl $-1, %eax 497; X86-BMI1NOTBM-NEXT: adcl $-1, %edx 498; X86-BMI1NOTBM-NEXT: andl 4(%esi), %edx 499; X86-BMI1NOTBM-NEXT: andl (%esi), %eax 500; X86-BMI1NOTBM-NEXT: popl %esi 501; X86-BMI1NOTBM-NEXT: retl 502; 503; X86-BMI1BMI2-LABEL: bzhi64_a2_load: 504; X86-BMI1BMI2: # %bb.0: 505; X86-BMI1BMI2-NEXT: pushl %esi 506; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 507; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 508; X86-BMI1BMI2-NEXT: movl $1, %eax 509; X86-BMI1BMI2-NEXT: xorl %edx, %edx 510; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %edx 511; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %eax 512; X86-BMI1BMI2-NEXT: testb $32, %cl 513; X86-BMI1BMI2-NEXT: je .LBB7_2 514; X86-BMI1BMI2-NEXT: # %bb.1: 515; X86-BMI1BMI2-NEXT: movl %eax, %edx 516; X86-BMI1BMI2-NEXT: xorl %eax, %eax 517; X86-BMI1BMI2-NEXT: .LBB7_2: 518; X86-BMI1BMI2-NEXT: addl $-1, %eax 519; X86-BMI1BMI2-NEXT: adcl $-1, %edx 520; X86-BMI1BMI2-NEXT: andl 4(%esi), %edx 521; X86-BMI1BMI2-NEXT: andl (%esi), %eax 522; X86-BMI1BMI2-NEXT: popl %esi 523; X86-BMI1BMI2-NEXT: retl 524; 525; X64-NOBMI-LABEL: bzhi64_a2_load: 526; X64-NOBMI: # %bb.0: 527; X64-NOBMI-NEXT: movq %rsi, %rcx 528; X64-NOBMI-NEXT: movl $1, %eax 529; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 530; X64-NOBMI-NEXT: shlq %cl, %rax 531; X64-NOBMI-NEXT: decq %rax 532; X64-NOBMI-NEXT: andq (%rdi), %rax 533; X64-NOBMI-NEXT: retq 534; 535; X64-BMI1NOTBM-LABEL: bzhi64_a2_load: 536; X64-BMI1NOTBM: # %bb.0: 537; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 538; X64-BMI1NOTBM-NEXT: bextrq %rsi, (%rdi), %rax 539; X64-BMI1NOTBM-NEXT: retq 540; 541; X64-BMI1BMI2-LABEL: bzhi64_a2_load: 542; X64-BMI1BMI2: # %bb.0: 543; X64-BMI1BMI2-NEXT: bzhiq %rsi, (%rdi), %rax 544; X64-BMI1BMI2-NEXT: retq 545 %val = load i64, i64* %w 546 %onebit = shl i64 1, %numlowbits 547 %mask = add nsw i64 %onebit, -1 548 %masked = and i64 %mask, %val 549 ret i64 %masked 550} 551 552define i64 @bzhi64_a3_load_indexzext(i64* %w, i8 zeroext %numlowbits) nounwind { 553; X86-NOBMI-LABEL: bzhi64_a3_load_indexzext: 554; X86-NOBMI: # %bb.0: 555; X86-NOBMI-NEXT: pushl %esi 556; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 557; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 558; X86-NOBMI-NEXT: movl $1, %eax 559; X86-NOBMI-NEXT: xorl %edx, %edx 560; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 561; X86-NOBMI-NEXT: shll %cl, %eax 562; X86-NOBMI-NEXT: testb $32, %cl 563; X86-NOBMI-NEXT: je .LBB8_2 564; X86-NOBMI-NEXT: # %bb.1: 565; X86-NOBMI-NEXT: movl %eax, %edx 566; X86-NOBMI-NEXT: xorl %eax, %eax 567; X86-NOBMI-NEXT: .LBB8_2: 568; X86-NOBMI-NEXT: addl $-1, %eax 569; X86-NOBMI-NEXT: adcl $-1, %edx 570; X86-NOBMI-NEXT: andl 4(%esi), %edx 571; X86-NOBMI-NEXT: andl (%esi), %eax 572; X86-NOBMI-NEXT: popl %esi 573; X86-NOBMI-NEXT: retl 574; 575; X86-BMI1NOTBM-LABEL: bzhi64_a3_load_indexzext: 576; X86-BMI1NOTBM: # %bb.0: 577; X86-BMI1NOTBM-NEXT: pushl %esi 578; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %esi 579; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 580; X86-BMI1NOTBM-NEXT: movl $1, %eax 581; X86-BMI1NOTBM-NEXT: xorl %edx, %edx 582; X86-BMI1NOTBM-NEXT: shldl %cl, %eax, %edx 583; X86-BMI1NOTBM-NEXT: shll %cl, %eax 584; X86-BMI1NOTBM-NEXT: testb $32, %cl 585; X86-BMI1NOTBM-NEXT: je .LBB8_2 586; X86-BMI1NOTBM-NEXT: # %bb.1: 587; X86-BMI1NOTBM-NEXT: movl %eax, %edx 588; X86-BMI1NOTBM-NEXT: xorl %eax, %eax 589; X86-BMI1NOTBM-NEXT: .LBB8_2: 590; X86-BMI1NOTBM-NEXT: addl $-1, %eax 591; X86-BMI1NOTBM-NEXT: adcl $-1, %edx 592; X86-BMI1NOTBM-NEXT: andl 4(%esi), %edx 593; X86-BMI1NOTBM-NEXT: andl (%esi), %eax 594; X86-BMI1NOTBM-NEXT: popl %esi 595; X86-BMI1NOTBM-NEXT: retl 596; 597; X86-BMI1BMI2-LABEL: bzhi64_a3_load_indexzext: 598; X86-BMI1BMI2: # %bb.0: 599; X86-BMI1BMI2-NEXT: pushl %esi 600; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 601; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 602; X86-BMI1BMI2-NEXT: movl $1, %eax 603; X86-BMI1BMI2-NEXT: xorl %edx, %edx 604; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %edx 605; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %eax 606; X86-BMI1BMI2-NEXT: testb $32, %cl 607; X86-BMI1BMI2-NEXT: je .LBB8_2 608; X86-BMI1BMI2-NEXT: # %bb.1: 609; X86-BMI1BMI2-NEXT: movl %eax, %edx 610; X86-BMI1BMI2-NEXT: xorl %eax, %eax 611; X86-BMI1BMI2-NEXT: .LBB8_2: 612; X86-BMI1BMI2-NEXT: addl $-1, %eax 613; X86-BMI1BMI2-NEXT: adcl $-1, %edx 614; X86-BMI1BMI2-NEXT: andl 4(%esi), %edx 615; X86-BMI1BMI2-NEXT: andl (%esi), %eax 616; X86-BMI1BMI2-NEXT: popl %esi 617; X86-BMI1BMI2-NEXT: retl 618; 619; X64-NOBMI-LABEL: bzhi64_a3_load_indexzext: 620; X64-NOBMI: # %bb.0: 621; X64-NOBMI-NEXT: movl %esi, %ecx 622; X64-NOBMI-NEXT: movl $1, %eax 623; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 624; X64-NOBMI-NEXT: shlq %cl, %rax 625; X64-NOBMI-NEXT: decq %rax 626; X64-NOBMI-NEXT: andq (%rdi), %rax 627; X64-NOBMI-NEXT: retq 628; 629; X64-BMI1NOTBM-LABEL: bzhi64_a3_load_indexzext: 630; X64-BMI1NOTBM: # %bb.0: 631; X64-BMI1NOTBM-NEXT: # kill: def $esi killed $esi def $rsi 632; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 633; X64-BMI1NOTBM-NEXT: bextrq %rsi, (%rdi), %rax 634; X64-BMI1NOTBM-NEXT: retq 635; 636; X64-BMI1BMI2-LABEL: bzhi64_a3_load_indexzext: 637; X64-BMI1BMI2: # %bb.0: 638; X64-BMI1BMI2-NEXT: # kill: def $esi killed $esi def $rsi 639; X64-BMI1BMI2-NEXT: bzhiq %rsi, (%rdi), %rax 640; X64-BMI1BMI2-NEXT: retq 641 %val = load i64, i64* %w 642 %conv = zext i8 %numlowbits to i64 643 %onebit = shl i64 1, %conv 644 %mask = add nsw i64 %onebit, -1 645 %masked = and i64 %mask, %val 646 ret i64 %masked 647} 648 649define i64 @bzhi64_a4_commutative(i64 %val, i64 %numlowbits) nounwind { 650; X86-NOBMI-LABEL: bzhi64_a4_commutative: 651; X86-NOBMI: # %bb.0: 652; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 653; X86-NOBMI-NEXT: movl $1, %eax 654; X86-NOBMI-NEXT: xorl %edx, %edx 655; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 656; X86-NOBMI-NEXT: shll %cl, %eax 657; X86-NOBMI-NEXT: testb $32, %cl 658; X86-NOBMI-NEXT: je .LBB9_2 659; X86-NOBMI-NEXT: # %bb.1: 660; X86-NOBMI-NEXT: movl %eax, %edx 661; X86-NOBMI-NEXT: xorl %eax, %eax 662; X86-NOBMI-NEXT: .LBB9_2: 663; X86-NOBMI-NEXT: addl $-1, %eax 664; X86-NOBMI-NEXT: adcl $-1, %edx 665; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edx 666; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 667; X86-NOBMI-NEXT: retl 668; 669; X86-BMI1NOTBM-LABEL: bzhi64_a4_commutative: 670; X86-BMI1NOTBM: # %bb.0: 671; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 672; X86-BMI1NOTBM-NEXT: movl $1, %eax 673; X86-BMI1NOTBM-NEXT: xorl %edx, %edx 674; X86-BMI1NOTBM-NEXT: shldl %cl, %eax, %edx 675; X86-BMI1NOTBM-NEXT: shll %cl, %eax 676; X86-BMI1NOTBM-NEXT: testb $32, %cl 677; X86-BMI1NOTBM-NEXT: je .LBB9_2 678; X86-BMI1NOTBM-NEXT: # %bb.1: 679; X86-BMI1NOTBM-NEXT: movl %eax, %edx 680; X86-BMI1NOTBM-NEXT: xorl %eax, %eax 681; X86-BMI1NOTBM-NEXT: .LBB9_2: 682; X86-BMI1NOTBM-NEXT: addl $-1, %eax 683; X86-BMI1NOTBM-NEXT: adcl $-1, %edx 684; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %edx 685; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %eax 686; X86-BMI1NOTBM-NEXT: retl 687; 688; X86-BMI1BMI2-LABEL: bzhi64_a4_commutative: 689; X86-BMI1BMI2: # %bb.0: 690; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 691; X86-BMI1BMI2-NEXT: movl $1, %eax 692; X86-BMI1BMI2-NEXT: xorl %edx, %edx 693; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %edx 694; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %eax 695; X86-BMI1BMI2-NEXT: testb $32, %cl 696; X86-BMI1BMI2-NEXT: je .LBB9_2 697; X86-BMI1BMI2-NEXT: # %bb.1: 698; X86-BMI1BMI2-NEXT: movl %eax, %edx 699; X86-BMI1BMI2-NEXT: xorl %eax, %eax 700; X86-BMI1BMI2-NEXT: .LBB9_2: 701; X86-BMI1BMI2-NEXT: addl $-1, %eax 702; X86-BMI1BMI2-NEXT: adcl $-1, %edx 703; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 704; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 705; X86-BMI1BMI2-NEXT: retl 706; 707; X64-NOBMI-LABEL: bzhi64_a4_commutative: 708; X64-NOBMI: # %bb.0: 709; X64-NOBMI-NEXT: movq %rsi, %rcx 710; X64-NOBMI-NEXT: movl $1, %eax 711; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 712; X64-NOBMI-NEXT: shlq %cl, %rax 713; X64-NOBMI-NEXT: decq %rax 714; X64-NOBMI-NEXT: andq %rdi, %rax 715; X64-NOBMI-NEXT: retq 716; 717; X64-BMI1NOTBM-LABEL: bzhi64_a4_commutative: 718; X64-BMI1NOTBM: # %bb.0: 719; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 720; X64-BMI1NOTBM-NEXT: bextrq %rsi, %rdi, %rax 721; X64-BMI1NOTBM-NEXT: retq 722; 723; X64-BMI1BMI2-LABEL: bzhi64_a4_commutative: 724; X64-BMI1BMI2: # %bb.0: 725; X64-BMI1BMI2-NEXT: bzhiq %rsi, %rdi, %rax 726; X64-BMI1BMI2-NEXT: retq 727 %onebit = shl i64 1, %numlowbits 728 %mask = add nsw i64 %onebit, -1 729 %masked = and i64 %val, %mask ; swapped order 730 ret i64 %masked 731} 732 733; ---------------------------------------------------------------------------- ; 734; Pattern b. 32-bit 735; ---------------------------------------------------------------------------- ; 736 737define i32 @bzhi32_b0(i32 %val, i32 %numlowbits) nounwind { 738; X86-NOBMI-LABEL: bzhi32_b0: 739; X86-NOBMI: # %bb.0: 740; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 741; X86-NOBMI-NEXT: movl $-1, %eax 742; X86-NOBMI-NEXT: shll %cl, %eax 743; X86-NOBMI-NEXT: notl %eax 744; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 745; X86-NOBMI-NEXT: retl 746; 747; X86-BMI1NOTBM-LABEL: bzhi32_b0: 748; X86-BMI1NOTBM: # %bb.0: 749; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %al 750; X86-BMI1NOTBM-NEXT: shll $8, %eax 751; X86-BMI1NOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 752; X86-BMI1NOTBM-NEXT: retl 753; 754; X86-BMI1BMI2-LABEL: bzhi32_b0: 755; X86-BMI1BMI2: # %bb.0: 756; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 757; X86-BMI1BMI2-NEXT: bzhil %eax, {{[0-9]+}}(%esp), %eax 758; X86-BMI1BMI2-NEXT: retl 759; 760; X64-NOBMI-LABEL: bzhi32_b0: 761; X64-NOBMI: # %bb.0: 762; X64-NOBMI-NEXT: movl %esi, %ecx 763; X64-NOBMI-NEXT: movl $-1, %eax 764; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 765; X64-NOBMI-NEXT: shll %cl, %eax 766; X64-NOBMI-NEXT: notl %eax 767; X64-NOBMI-NEXT: andl %edi, %eax 768; X64-NOBMI-NEXT: retq 769; 770; X64-BMI1NOTBM-LABEL: bzhi32_b0: 771; X64-BMI1NOTBM: # %bb.0: 772; X64-BMI1NOTBM-NEXT: shll $8, %esi 773; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax 774; X64-BMI1NOTBM-NEXT: retq 775; 776; X64-BMI1BMI2-LABEL: bzhi32_b0: 777; X64-BMI1BMI2: # %bb.0: 778; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax 779; X64-BMI1BMI2-NEXT: retq 780 %notmask = shl i32 -1, %numlowbits 781 %mask = xor i32 %notmask, -1 782 %masked = and i32 %mask, %val 783 ret i32 %masked 784} 785 786define i32 @bzhi32_b1_indexzext(i32 %val, i8 zeroext %numlowbits) nounwind { 787; X86-NOBMI-LABEL: bzhi32_b1_indexzext: 788; X86-NOBMI: # %bb.0: 789; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 790; X86-NOBMI-NEXT: movl $-1, %eax 791; X86-NOBMI-NEXT: shll %cl, %eax 792; X86-NOBMI-NEXT: notl %eax 793; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 794; X86-NOBMI-NEXT: retl 795; 796; X86-BMI1NOTBM-LABEL: bzhi32_b1_indexzext: 797; X86-BMI1NOTBM: # %bb.0: 798; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %al 799; X86-BMI1NOTBM-NEXT: shll $8, %eax 800; X86-BMI1NOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 801; X86-BMI1NOTBM-NEXT: retl 802; 803; X86-BMI1BMI2-LABEL: bzhi32_b1_indexzext: 804; X86-BMI1BMI2: # %bb.0: 805; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 806; X86-BMI1BMI2-NEXT: bzhil %eax, {{[0-9]+}}(%esp), %eax 807; X86-BMI1BMI2-NEXT: retl 808; 809; X64-NOBMI-LABEL: bzhi32_b1_indexzext: 810; X64-NOBMI: # %bb.0: 811; X64-NOBMI-NEXT: movl %esi, %ecx 812; X64-NOBMI-NEXT: movl $-1, %eax 813; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 814; X64-NOBMI-NEXT: shll %cl, %eax 815; X64-NOBMI-NEXT: notl %eax 816; X64-NOBMI-NEXT: andl %edi, %eax 817; X64-NOBMI-NEXT: retq 818; 819; X64-BMI1NOTBM-LABEL: bzhi32_b1_indexzext: 820; X64-BMI1NOTBM: # %bb.0: 821; X64-BMI1NOTBM-NEXT: shll $8, %esi 822; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax 823; X64-BMI1NOTBM-NEXT: retq 824; 825; X64-BMI1BMI2-LABEL: bzhi32_b1_indexzext: 826; X64-BMI1BMI2: # %bb.0: 827; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax 828; X64-BMI1BMI2-NEXT: retq 829 %conv = zext i8 %numlowbits to i32 830 %notmask = shl i32 -1, %conv 831 %mask = xor i32 %notmask, -1 832 %masked = and i32 %mask, %val 833 ret i32 %masked 834} 835 836define i32 @bzhi32_b2_load(i32* %w, i32 %numlowbits) nounwind { 837; X86-NOBMI-LABEL: bzhi32_b2_load: 838; X86-NOBMI: # %bb.0: 839; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 840; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 841; X86-NOBMI-NEXT: movl $-1, %eax 842; X86-NOBMI-NEXT: shll %cl, %eax 843; X86-NOBMI-NEXT: notl %eax 844; X86-NOBMI-NEXT: andl (%edx), %eax 845; X86-NOBMI-NEXT: retl 846; 847; X86-BMI1NOTBM-LABEL: bzhi32_b2_load: 848; X86-BMI1NOTBM: # %bb.0: 849; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 850; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 851; X86-BMI1NOTBM-NEXT: shll $8, %ecx 852; X86-BMI1NOTBM-NEXT: bextrl %ecx, (%eax), %eax 853; X86-BMI1NOTBM-NEXT: retl 854; 855; X86-BMI1BMI2-LABEL: bzhi32_b2_load: 856; X86-BMI1BMI2: # %bb.0: 857; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 858; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 859; X86-BMI1BMI2-NEXT: bzhil %ecx, (%eax), %eax 860; X86-BMI1BMI2-NEXT: retl 861; 862; X64-NOBMI-LABEL: bzhi32_b2_load: 863; X64-NOBMI: # %bb.0: 864; X64-NOBMI-NEXT: movl %esi, %ecx 865; X64-NOBMI-NEXT: movl $-1, %eax 866; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 867; X64-NOBMI-NEXT: shll %cl, %eax 868; X64-NOBMI-NEXT: notl %eax 869; X64-NOBMI-NEXT: andl (%rdi), %eax 870; X64-NOBMI-NEXT: retq 871; 872; X64-BMI1NOTBM-LABEL: bzhi32_b2_load: 873; X64-BMI1NOTBM: # %bb.0: 874; X64-BMI1NOTBM-NEXT: shll $8, %esi 875; X64-BMI1NOTBM-NEXT: bextrl %esi, (%rdi), %eax 876; X64-BMI1NOTBM-NEXT: retq 877; 878; X64-BMI1BMI2-LABEL: bzhi32_b2_load: 879; X64-BMI1BMI2: # %bb.0: 880; X64-BMI1BMI2-NEXT: bzhil %esi, (%rdi), %eax 881; X64-BMI1BMI2-NEXT: retq 882 %val = load i32, i32* %w 883 %notmask = shl i32 -1, %numlowbits 884 %mask = xor i32 %notmask, -1 885 %masked = and i32 %mask, %val 886 ret i32 %masked 887} 888 889define i32 @bzhi32_b3_load_indexzext(i32* %w, i8 zeroext %numlowbits) nounwind { 890; X86-NOBMI-LABEL: bzhi32_b3_load_indexzext: 891; X86-NOBMI: # %bb.0: 892; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 893; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 894; X86-NOBMI-NEXT: movl $-1, %eax 895; X86-NOBMI-NEXT: shll %cl, %eax 896; X86-NOBMI-NEXT: notl %eax 897; X86-NOBMI-NEXT: andl (%edx), %eax 898; X86-NOBMI-NEXT: retl 899; 900; X86-BMI1NOTBM-LABEL: bzhi32_b3_load_indexzext: 901; X86-BMI1NOTBM: # %bb.0: 902; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 903; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 904; X86-BMI1NOTBM-NEXT: shll $8, %ecx 905; X86-BMI1NOTBM-NEXT: bextrl %ecx, (%eax), %eax 906; X86-BMI1NOTBM-NEXT: retl 907; 908; X86-BMI1BMI2-LABEL: bzhi32_b3_load_indexzext: 909; X86-BMI1BMI2: # %bb.0: 910; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 911; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 912; X86-BMI1BMI2-NEXT: bzhil %ecx, (%eax), %eax 913; X86-BMI1BMI2-NEXT: retl 914; 915; X64-NOBMI-LABEL: bzhi32_b3_load_indexzext: 916; X64-NOBMI: # %bb.0: 917; X64-NOBMI-NEXT: movl %esi, %ecx 918; X64-NOBMI-NEXT: movl $-1, %eax 919; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 920; X64-NOBMI-NEXT: shll %cl, %eax 921; X64-NOBMI-NEXT: notl %eax 922; X64-NOBMI-NEXT: andl (%rdi), %eax 923; X64-NOBMI-NEXT: retq 924; 925; X64-BMI1NOTBM-LABEL: bzhi32_b3_load_indexzext: 926; X64-BMI1NOTBM: # %bb.0: 927; X64-BMI1NOTBM-NEXT: shll $8, %esi 928; X64-BMI1NOTBM-NEXT: bextrl %esi, (%rdi), %eax 929; X64-BMI1NOTBM-NEXT: retq 930; 931; X64-BMI1BMI2-LABEL: bzhi32_b3_load_indexzext: 932; X64-BMI1BMI2: # %bb.0: 933; X64-BMI1BMI2-NEXT: bzhil %esi, (%rdi), %eax 934; X64-BMI1BMI2-NEXT: retq 935 %val = load i32, i32* %w 936 %conv = zext i8 %numlowbits to i32 937 %notmask = shl i32 -1, %conv 938 %mask = xor i32 %notmask, -1 939 %masked = and i32 %mask, %val 940 ret i32 %masked 941} 942 943define i32 @bzhi32_b4_commutative(i32 %val, i32 %numlowbits) nounwind { 944; X86-NOBMI-LABEL: bzhi32_b4_commutative: 945; X86-NOBMI: # %bb.0: 946; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 947; X86-NOBMI-NEXT: movl $-1, %eax 948; X86-NOBMI-NEXT: shll %cl, %eax 949; X86-NOBMI-NEXT: notl %eax 950; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 951; X86-NOBMI-NEXT: retl 952; 953; X86-BMI1NOTBM-LABEL: bzhi32_b4_commutative: 954; X86-BMI1NOTBM: # %bb.0: 955; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %al 956; X86-BMI1NOTBM-NEXT: shll $8, %eax 957; X86-BMI1NOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 958; X86-BMI1NOTBM-NEXT: retl 959; 960; X86-BMI1BMI2-LABEL: bzhi32_b4_commutative: 961; X86-BMI1BMI2: # %bb.0: 962; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 963; X86-BMI1BMI2-NEXT: bzhil %eax, {{[0-9]+}}(%esp), %eax 964; X86-BMI1BMI2-NEXT: retl 965; 966; X64-NOBMI-LABEL: bzhi32_b4_commutative: 967; X64-NOBMI: # %bb.0: 968; X64-NOBMI-NEXT: movl %esi, %ecx 969; X64-NOBMI-NEXT: movl $-1, %eax 970; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 971; X64-NOBMI-NEXT: shll %cl, %eax 972; X64-NOBMI-NEXT: notl %eax 973; X64-NOBMI-NEXT: andl %edi, %eax 974; X64-NOBMI-NEXT: retq 975; 976; X64-BMI1NOTBM-LABEL: bzhi32_b4_commutative: 977; X64-BMI1NOTBM: # %bb.0: 978; X64-BMI1NOTBM-NEXT: shll $8, %esi 979; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax 980; X64-BMI1NOTBM-NEXT: retq 981; 982; X64-BMI1BMI2-LABEL: bzhi32_b4_commutative: 983; X64-BMI1BMI2: # %bb.0: 984; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax 985; X64-BMI1BMI2-NEXT: retq 986 %notmask = shl i32 -1, %numlowbits 987 %mask = xor i32 %notmask, -1 988 %masked = and i32 %val, %mask ; swapped order 989 ret i32 %masked 990} 991 992; 64-bit 993 994define i64 @bzhi64_b0(i64 %val, i64 %numlowbits) nounwind { 995; X86-NOBMI-LABEL: bzhi64_b0: 996; X86-NOBMI: # %bb.0: 997; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 998; X86-NOBMI-NEXT: movl $-1, %edx 999; X86-NOBMI-NEXT: movl $-1, %eax 1000; X86-NOBMI-NEXT: shll %cl, %eax 1001; X86-NOBMI-NEXT: shldl %cl, %edx, %edx 1002; X86-NOBMI-NEXT: testb $32, %cl 1003; X86-NOBMI-NEXT: je .LBB15_2 1004; X86-NOBMI-NEXT: # %bb.1: 1005; X86-NOBMI-NEXT: movl %eax, %edx 1006; X86-NOBMI-NEXT: xorl %eax, %eax 1007; X86-NOBMI-NEXT: .LBB15_2: 1008; X86-NOBMI-NEXT: notl %edx 1009; X86-NOBMI-NEXT: notl %eax 1010; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edx 1011; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 1012; X86-NOBMI-NEXT: retl 1013; 1014; X86-BMI1NOTBM-LABEL: bzhi64_b0: 1015; X86-BMI1NOTBM: # %bb.0: 1016; X86-BMI1NOTBM-NEXT: pushl %esi 1017; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 1018; X86-BMI1NOTBM-NEXT: movl $-1, %eax 1019; X86-BMI1NOTBM-NEXT: movl $-1, %esi 1020; X86-BMI1NOTBM-NEXT: shll %cl, %esi 1021; X86-BMI1NOTBM-NEXT: shldl %cl, %eax, %eax 1022; X86-BMI1NOTBM-NEXT: testb $32, %cl 1023; X86-BMI1NOTBM-NEXT: je .LBB15_2 1024; X86-BMI1NOTBM-NEXT: # %bb.1: 1025; X86-BMI1NOTBM-NEXT: movl %esi, %eax 1026; X86-BMI1NOTBM-NEXT: xorl %esi, %esi 1027; X86-BMI1NOTBM-NEXT: .LBB15_2: 1028; X86-BMI1NOTBM-NEXT: andnl {{[0-9]+}}(%esp), %eax, %edx 1029; X86-BMI1NOTBM-NEXT: andnl {{[0-9]+}}(%esp), %esi, %eax 1030; X86-BMI1NOTBM-NEXT: popl %esi 1031; X86-BMI1NOTBM-NEXT: retl 1032; 1033; X86-BMI1BMI2-LABEL: bzhi64_b0: 1034; X86-BMI1BMI2: # %bb.0: 1035; X86-BMI1BMI2-NEXT: pushl %esi 1036; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1037; X86-BMI1BMI2-NEXT: movl $-1, %eax 1038; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %esi 1039; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %eax 1040; X86-BMI1BMI2-NEXT: testb $32, %cl 1041; X86-BMI1BMI2-NEXT: je .LBB15_2 1042; X86-BMI1BMI2-NEXT: # %bb.1: 1043; X86-BMI1BMI2-NEXT: movl %esi, %eax 1044; X86-BMI1BMI2-NEXT: xorl %esi, %esi 1045; X86-BMI1BMI2-NEXT: .LBB15_2: 1046; X86-BMI1BMI2-NEXT: andnl {{[0-9]+}}(%esp), %eax, %edx 1047; X86-BMI1BMI2-NEXT: andnl {{[0-9]+}}(%esp), %esi, %eax 1048; X86-BMI1BMI2-NEXT: popl %esi 1049; X86-BMI1BMI2-NEXT: retl 1050; 1051; X64-NOBMI-LABEL: bzhi64_b0: 1052; X64-NOBMI: # %bb.0: 1053; X64-NOBMI-NEXT: movq %rsi, %rcx 1054; X64-NOBMI-NEXT: movq $-1, %rax 1055; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 1056; X64-NOBMI-NEXT: shlq %cl, %rax 1057; X64-NOBMI-NEXT: notq %rax 1058; X64-NOBMI-NEXT: andq %rdi, %rax 1059; X64-NOBMI-NEXT: retq 1060; 1061; X64-BMI1NOTBM-LABEL: bzhi64_b0: 1062; X64-BMI1NOTBM: # %bb.0: 1063; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 1064; X64-BMI1NOTBM-NEXT: bextrq %rsi, %rdi, %rax 1065; X64-BMI1NOTBM-NEXT: retq 1066; 1067; X64-BMI1BMI2-LABEL: bzhi64_b0: 1068; X64-BMI1BMI2: # %bb.0: 1069; X64-BMI1BMI2-NEXT: bzhiq %rsi, %rdi, %rax 1070; X64-BMI1BMI2-NEXT: retq 1071 %notmask = shl i64 -1, %numlowbits 1072 %mask = xor i64 %notmask, -1 1073 %masked = and i64 %mask, %val 1074 ret i64 %masked 1075} 1076 1077define i64 @bzhi64_b1_indexzext(i64 %val, i8 zeroext %numlowbits) nounwind { 1078; X86-NOBMI-LABEL: bzhi64_b1_indexzext: 1079; X86-NOBMI: # %bb.0: 1080; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 1081; X86-NOBMI-NEXT: movl $-1, %edx 1082; X86-NOBMI-NEXT: movl $-1, %eax 1083; X86-NOBMI-NEXT: shll %cl, %eax 1084; X86-NOBMI-NEXT: shldl %cl, %edx, %edx 1085; X86-NOBMI-NEXT: testb $32, %cl 1086; X86-NOBMI-NEXT: je .LBB16_2 1087; X86-NOBMI-NEXT: # %bb.1: 1088; X86-NOBMI-NEXT: movl %eax, %edx 1089; X86-NOBMI-NEXT: xorl %eax, %eax 1090; X86-NOBMI-NEXT: .LBB16_2: 1091; X86-NOBMI-NEXT: notl %edx 1092; X86-NOBMI-NEXT: notl %eax 1093; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edx 1094; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 1095; X86-NOBMI-NEXT: retl 1096; 1097; X86-BMI1NOTBM-LABEL: bzhi64_b1_indexzext: 1098; X86-BMI1NOTBM: # %bb.0: 1099; X86-BMI1NOTBM-NEXT: pushl %esi 1100; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 1101; X86-BMI1NOTBM-NEXT: movl $-1, %eax 1102; X86-BMI1NOTBM-NEXT: movl $-1, %esi 1103; X86-BMI1NOTBM-NEXT: shll %cl, %esi 1104; X86-BMI1NOTBM-NEXT: shldl %cl, %eax, %eax 1105; X86-BMI1NOTBM-NEXT: testb $32, %cl 1106; X86-BMI1NOTBM-NEXT: je .LBB16_2 1107; X86-BMI1NOTBM-NEXT: # %bb.1: 1108; X86-BMI1NOTBM-NEXT: movl %esi, %eax 1109; X86-BMI1NOTBM-NEXT: xorl %esi, %esi 1110; X86-BMI1NOTBM-NEXT: .LBB16_2: 1111; X86-BMI1NOTBM-NEXT: andnl {{[0-9]+}}(%esp), %eax, %edx 1112; X86-BMI1NOTBM-NEXT: andnl {{[0-9]+}}(%esp), %esi, %eax 1113; X86-BMI1NOTBM-NEXT: popl %esi 1114; X86-BMI1NOTBM-NEXT: retl 1115; 1116; X86-BMI1BMI2-LABEL: bzhi64_b1_indexzext: 1117; X86-BMI1BMI2: # %bb.0: 1118; X86-BMI1BMI2-NEXT: pushl %esi 1119; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1120; X86-BMI1BMI2-NEXT: movl $-1, %eax 1121; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %esi 1122; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %eax 1123; X86-BMI1BMI2-NEXT: testb $32, %cl 1124; X86-BMI1BMI2-NEXT: je .LBB16_2 1125; X86-BMI1BMI2-NEXT: # %bb.1: 1126; X86-BMI1BMI2-NEXT: movl %esi, %eax 1127; X86-BMI1BMI2-NEXT: xorl %esi, %esi 1128; X86-BMI1BMI2-NEXT: .LBB16_2: 1129; X86-BMI1BMI2-NEXT: andnl {{[0-9]+}}(%esp), %eax, %edx 1130; X86-BMI1BMI2-NEXT: andnl {{[0-9]+}}(%esp), %esi, %eax 1131; X86-BMI1BMI2-NEXT: popl %esi 1132; X86-BMI1BMI2-NEXT: retl 1133; 1134; X64-NOBMI-LABEL: bzhi64_b1_indexzext: 1135; X64-NOBMI: # %bb.0: 1136; X64-NOBMI-NEXT: movl %esi, %ecx 1137; X64-NOBMI-NEXT: movq $-1, %rax 1138; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1139; X64-NOBMI-NEXT: shlq %cl, %rax 1140; X64-NOBMI-NEXT: notq %rax 1141; X64-NOBMI-NEXT: andq %rdi, %rax 1142; X64-NOBMI-NEXT: retq 1143; 1144; X64-BMI1NOTBM-LABEL: bzhi64_b1_indexzext: 1145; X64-BMI1NOTBM: # %bb.0: 1146; X64-BMI1NOTBM-NEXT: # kill: def $esi killed $esi def $rsi 1147; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 1148; X64-BMI1NOTBM-NEXT: bextrq %rsi, %rdi, %rax 1149; X64-BMI1NOTBM-NEXT: retq 1150; 1151; X64-BMI1BMI2-LABEL: bzhi64_b1_indexzext: 1152; X64-BMI1BMI2: # %bb.0: 1153; X64-BMI1BMI2-NEXT: # kill: def $esi killed $esi def $rsi 1154; X64-BMI1BMI2-NEXT: bzhiq %rsi, %rdi, %rax 1155; X64-BMI1BMI2-NEXT: retq 1156 %conv = zext i8 %numlowbits to i64 1157 %notmask = shl i64 -1, %conv 1158 %mask = xor i64 %notmask, -1 1159 %masked = and i64 %mask, %val 1160 ret i64 %masked 1161} 1162 1163define i64 @bzhi64_b2_load(i64* %w, i64 %numlowbits) nounwind { 1164; X86-NOBMI-LABEL: bzhi64_b2_load: 1165; X86-NOBMI: # %bb.0: 1166; X86-NOBMI-NEXT: pushl %esi 1167; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 1168; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 1169; X86-NOBMI-NEXT: movl $-1, %edx 1170; X86-NOBMI-NEXT: movl $-1, %eax 1171; X86-NOBMI-NEXT: shll %cl, %eax 1172; X86-NOBMI-NEXT: shldl %cl, %edx, %edx 1173; X86-NOBMI-NEXT: testb $32, %cl 1174; X86-NOBMI-NEXT: je .LBB17_2 1175; X86-NOBMI-NEXT: # %bb.1: 1176; X86-NOBMI-NEXT: movl %eax, %edx 1177; X86-NOBMI-NEXT: xorl %eax, %eax 1178; X86-NOBMI-NEXT: .LBB17_2: 1179; X86-NOBMI-NEXT: notl %edx 1180; X86-NOBMI-NEXT: notl %eax 1181; X86-NOBMI-NEXT: andl 4(%esi), %edx 1182; X86-NOBMI-NEXT: andl (%esi), %eax 1183; X86-NOBMI-NEXT: popl %esi 1184; X86-NOBMI-NEXT: retl 1185; 1186; X86-BMI1NOTBM-LABEL: bzhi64_b2_load: 1187; X86-BMI1NOTBM: # %bb.0: 1188; X86-BMI1NOTBM-NEXT: pushl %esi 1189; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 1190; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 1191; X86-BMI1NOTBM-NEXT: movl $-1, %edx 1192; X86-BMI1NOTBM-NEXT: movl $-1, %esi 1193; X86-BMI1NOTBM-NEXT: shll %cl, %esi 1194; X86-BMI1NOTBM-NEXT: shldl %cl, %edx, %edx 1195; X86-BMI1NOTBM-NEXT: testb $32, %cl 1196; X86-BMI1NOTBM-NEXT: je .LBB17_2 1197; X86-BMI1NOTBM-NEXT: # %bb.1: 1198; X86-BMI1NOTBM-NEXT: movl %esi, %edx 1199; X86-BMI1NOTBM-NEXT: xorl %esi, %esi 1200; X86-BMI1NOTBM-NEXT: .LBB17_2: 1201; X86-BMI1NOTBM-NEXT: andnl 4(%eax), %edx, %edx 1202; X86-BMI1NOTBM-NEXT: andnl (%eax), %esi, %eax 1203; X86-BMI1NOTBM-NEXT: popl %esi 1204; X86-BMI1NOTBM-NEXT: retl 1205; 1206; X86-BMI1BMI2-LABEL: bzhi64_b2_load: 1207; X86-BMI1BMI2: # %bb.0: 1208; X86-BMI1BMI2-NEXT: pushl %esi 1209; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1210; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1211; X86-BMI1BMI2-NEXT: movl $-1, %edx 1212; X86-BMI1BMI2-NEXT: shlxl %ecx, %edx, %esi 1213; X86-BMI1BMI2-NEXT: shldl %cl, %edx, %edx 1214; X86-BMI1BMI2-NEXT: testb $32, %cl 1215; X86-BMI1BMI2-NEXT: je .LBB17_2 1216; X86-BMI1BMI2-NEXT: # %bb.1: 1217; X86-BMI1BMI2-NEXT: movl %esi, %edx 1218; X86-BMI1BMI2-NEXT: xorl %esi, %esi 1219; X86-BMI1BMI2-NEXT: .LBB17_2: 1220; X86-BMI1BMI2-NEXT: andnl 4(%eax), %edx, %edx 1221; X86-BMI1BMI2-NEXT: andnl (%eax), %esi, %eax 1222; X86-BMI1BMI2-NEXT: popl %esi 1223; X86-BMI1BMI2-NEXT: retl 1224; 1225; X64-NOBMI-LABEL: bzhi64_b2_load: 1226; X64-NOBMI: # %bb.0: 1227; X64-NOBMI-NEXT: movq %rsi, %rcx 1228; X64-NOBMI-NEXT: movq $-1, %rax 1229; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 1230; X64-NOBMI-NEXT: shlq %cl, %rax 1231; X64-NOBMI-NEXT: notq %rax 1232; X64-NOBMI-NEXT: andq (%rdi), %rax 1233; X64-NOBMI-NEXT: retq 1234; 1235; X64-BMI1NOTBM-LABEL: bzhi64_b2_load: 1236; X64-BMI1NOTBM: # %bb.0: 1237; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 1238; X64-BMI1NOTBM-NEXT: bextrq %rsi, (%rdi), %rax 1239; X64-BMI1NOTBM-NEXT: retq 1240; 1241; X64-BMI1BMI2-LABEL: bzhi64_b2_load: 1242; X64-BMI1BMI2: # %bb.0: 1243; X64-BMI1BMI2-NEXT: bzhiq %rsi, (%rdi), %rax 1244; X64-BMI1BMI2-NEXT: retq 1245 %val = load i64, i64* %w 1246 %notmask = shl i64 -1, %numlowbits 1247 %mask = xor i64 %notmask, -1 1248 %masked = and i64 %mask, %val 1249 ret i64 %masked 1250} 1251 1252define i64 @bzhi64_b3_load_indexzext(i64* %w, i8 zeroext %numlowbits) nounwind { 1253; X86-NOBMI-LABEL: bzhi64_b3_load_indexzext: 1254; X86-NOBMI: # %bb.0: 1255; X86-NOBMI-NEXT: pushl %esi 1256; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 1257; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 1258; X86-NOBMI-NEXT: movl $-1, %edx 1259; X86-NOBMI-NEXT: movl $-1, %eax 1260; X86-NOBMI-NEXT: shll %cl, %eax 1261; X86-NOBMI-NEXT: shldl %cl, %edx, %edx 1262; X86-NOBMI-NEXT: testb $32, %cl 1263; X86-NOBMI-NEXT: je .LBB18_2 1264; X86-NOBMI-NEXT: # %bb.1: 1265; X86-NOBMI-NEXT: movl %eax, %edx 1266; X86-NOBMI-NEXT: xorl %eax, %eax 1267; X86-NOBMI-NEXT: .LBB18_2: 1268; X86-NOBMI-NEXT: notl %edx 1269; X86-NOBMI-NEXT: notl %eax 1270; X86-NOBMI-NEXT: andl 4(%esi), %edx 1271; X86-NOBMI-NEXT: andl (%esi), %eax 1272; X86-NOBMI-NEXT: popl %esi 1273; X86-NOBMI-NEXT: retl 1274; 1275; X86-BMI1NOTBM-LABEL: bzhi64_b3_load_indexzext: 1276; X86-BMI1NOTBM: # %bb.0: 1277; X86-BMI1NOTBM-NEXT: pushl %esi 1278; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 1279; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 1280; X86-BMI1NOTBM-NEXT: movl $-1, %edx 1281; X86-BMI1NOTBM-NEXT: movl $-1, %esi 1282; X86-BMI1NOTBM-NEXT: shll %cl, %esi 1283; X86-BMI1NOTBM-NEXT: shldl %cl, %edx, %edx 1284; X86-BMI1NOTBM-NEXT: testb $32, %cl 1285; X86-BMI1NOTBM-NEXT: je .LBB18_2 1286; X86-BMI1NOTBM-NEXT: # %bb.1: 1287; X86-BMI1NOTBM-NEXT: movl %esi, %edx 1288; X86-BMI1NOTBM-NEXT: xorl %esi, %esi 1289; X86-BMI1NOTBM-NEXT: .LBB18_2: 1290; X86-BMI1NOTBM-NEXT: andnl 4(%eax), %edx, %edx 1291; X86-BMI1NOTBM-NEXT: andnl (%eax), %esi, %eax 1292; X86-BMI1NOTBM-NEXT: popl %esi 1293; X86-BMI1NOTBM-NEXT: retl 1294; 1295; X86-BMI1BMI2-LABEL: bzhi64_b3_load_indexzext: 1296; X86-BMI1BMI2: # %bb.0: 1297; X86-BMI1BMI2-NEXT: pushl %esi 1298; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1299; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1300; X86-BMI1BMI2-NEXT: movl $-1, %edx 1301; X86-BMI1BMI2-NEXT: shlxl %ecx, %edx, %esi 1302; X86-BMI1BMI2-NEXT: shldl %cl, %edx, %edx 1303; X86-BMI1BMI2-NEXT: testb $32, %cl 1304; X86-BMI1BMI2-NEXT: je .LBB18_2 1305; X86-BMI1BMI2-NEXT: # %bb.1: 1306; X86-BMI1BMI2-NEXT: movl %esi, %edx 1307; X86-BMI1BMI2-NEXT: xorl %esi, %esi 1308; X86-BMI1BMI2-NEXT: .LBB18_2: 1309; X86-BMI1BMI2-NEXT: andnl 4(%eax), %edx, %edx 1310; X86-BMI1BMI2-NEXT: andnl (%eax), %esi, %eax 1311; X86-BMI1BMI2-NEXT: popl %esi 1312; X86-BMI1BMI2-NEXT: retl 1313; 1314; X64-NOBMI-LABEL: bzhi64_b3_load_indexzext: 1315; X64-NOBMI: # %bb.0: 1316; X64-NOBMI-NEXT: movl %esi, %ecx 1317; X64-NOBMI-NEXT: movq $-1, %rax 1318; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1319; X64-NOBMI-NEXT: shlq %cl, %rax 1320; X64-NOBMI-NEXT: notq %rax 1321; X64-NOBMI-NEXT: andq (%rdi), %rax 1322; X64-NOBMI-NEXT: retq 1323; 1324; X64-BMI1NOTBM-LABEL: bzhi64_b3_load_indexzext: 1325; X64-BMI1NOTBM: # %bb.0: 1326; X64-BMI1NOTBM-NEXT: # kill: def $esi killed $esi def $rsi 1327; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 1328; X64-BMI1NOTBM-NEXT: bextrq %rsi, (%rdi), %rax 1329; X64-BMI1NOTBM-NEXT: retq 1330; 1331; X64-BMI1BMI2-LABEL: bzhi64_b3_load_indexzext: 1332; X64-BMI1BMI2: # %bb.0: 1333; X64-BMI1BMI2-NEXT: # kill: def $esi killed $esi def $rsi 1334; X64-BMI1BMI2-NEXT: bzhiq %rsi, (%rdi), %rax 1335; X64-BMI1BMI2-NEXT: retq 1336 %val = load i64, i64* %w 1337 %conv = zext i8 %numlowbits to i64 1338 %notmask = shl i64 -1, %conv 1339 %mask = xor i64 %notmask, -1 1340 %masked = and i64 %mask, %val 1341 ret i64 %masked 1342} 1343 1344define i64 @bzhi64_b4_commutative(i64 %val, i64 %numlowbits) nounwind { 1345; X86-NOBMI-LABEL: bzhi64_b4_commutative: 1346; X86-NOBMI: # %bb.0: 1347; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 1348; X86-NOBMI-NEXT: movl $-1, %edx 1349; X86-NOBMI-NEXT: movl $-1, %eax 1350; X86-NOBMI-NEXT: shll %cl, %eax 1351; X86-NOBMI-NEXT: shldl %cl, %edx, %edx 1352; X86-NOBMI-NEXT: testb $32, %cl 1353; X86-NOBMI-NEXT: je .LBB19_2 1354; X86-NOBMI-NEXT: # %bb.1: 1355; X86-NOBMI-NEXT: movl %eax, %edx 1356; X86-NOBMI-NEXT: xorl %eax, %eax 1357; X86-NOBMI-NEXT: .LBB19_2: 1358; X86-NOBMI-NEXT: notl %edx 1359; X86-NOBMI-NEXT: notl %eax 1360; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edx 1361; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax 1362; X86-NOBMI-NEXT: retl 1363; 1364; X86-BMI1NOTBM-LABEL: bzhi64_b4_commutative: 1365; X86-BMI1NOTBM: # %bb.0: 1366; X86-BMI1NOTBM-NEXT: pushl %esi 1367; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 1368; X86-BMI1NOTBM-NEXT: movl $-1, %eax 1369; X86-BMI1NOTBM-NEXT: movl $-1, %esi 1370; X86-BMI1NOTBM-NEXT: shll %cl, %esi 1371; X86-BMI1NOTBM-NEXT: shldl %cl, %eax, %eax 1372; X86-BMI1NOTBM-NEXT: testb $32, %cl 1373; X86-BMI1NOTBM-NEXT: je .LBB19_2 1374; X86-BMI1NOTBM-NEXT: # %bb.1: 1375; X86-BMI1NOTBM-NEXT: movl %esi, %eax 1376; X86-BMI1NOTBM-NEXT: xorl %esi, %esi 1377; X86-BMI1NOTBM-NEXT: .LBB19_2: 1378; X86-BMI1NOTBM-NEXT: andnl {{[0-9]+}}(%esp), %eax, %edx 1379; X86-BMI1NOTBM-NEXT: andnl {{[0-9]+}}(%esp), %esi, %eax 1380; X86-BMI1NOTBM-NEXT: popl %esi 1381; X86-BMI1NOTBM-NEXT: retl 1382; 1383; X86-BMI1BMI2-LABEL: bzhi64_b4_commutative: 1384; X86-BMI1BMI2: # %bb.0: 1385; X86-BMI1BMI2-NEXT: pushl %esi 1386; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1387; X86-BMI1BMI2-NEXT: movl $-1, %eax 1388; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %esi 1389; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %eax 1390; X86-BMI1BMI2-NEXT: testb $32, %cl 1391; X86-BMI1BMI2-NEXT: je .LBB19_2 1392; X86-BMI1BMI2-NEXT: # %bb.1: 1393; X86-BMI1BMI2-NEXT: movl %esi, %eax 1394; X86-BMI1BMI2-NEXT: xorl %esi, %esi 1395; X86-BMI1BMI2-NEXT: .LBB19_2: 1396; X86-BMI1BMI2-NEXT: andnl {{[0-9]+}}(%esp), %eax, %edx 1397; X86-BMI1BMI2-NEXT: andnl {{[0-9]+}}(%esp), %esi, %eax 1398; X86-BMI1BMI2-NEXT: popl %esi 1399; X86-BMI1BMI2-NEXT: retl 1400; 1401; X64-NOBMI-LABEL: bzhi64_b4_commutative: 1402; X64-NOBMI: # %bb.0: 1403; X64-NOBMI-NEXT: movq %rsi, %rcx 1404; X64-NOBMI-NEXT: movq $-1, %rax 1405; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 1406; X64-NOBMI-NEXT: shlq %cl, %rax 1407; X64-NOBMI-NEXT: notq %rax 1408; X64-NOBMI-NEXT: andq %rdi, %rax 1409; X64-NOBMI-NEXT: retq 1410; 1411; X64-BMI1NOTBM-LABEL: bzhi64_b4_commutative: 1412; X64-BMI1NOTBM: # %bb.0: 1413; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 1414; X64-BMI1NOTBM-NEXT: bextrq %rsi, %rdi, %rax 1415; X64-BMI1NOTBM-NEXT: retq 1416; 1417; X64-BMI1BMI2-LABEL: bzhi64_b4_commutative: 1418; X64-BMI1BMI2: # %bb.0: 1419; X64-BMI1BMI2-NEXT: bzhiq %rsi, %rdi, %rax 1420; X64-BMI1BMI2-NEXT: retq 1421 %notmask = shl i64 -1, %numlowbits 1422 %mask = xor i64 %notmask, -1 1423 %masked = and i64 %val, %mask ; swapped order 1424 ret i64 %masked 1425} 1426 1427; ---------------------------------------------------------------------------- ; 1428; Pattern c. 32-bit 1429; ---------------------------------------------------------------------------- ; 1430 1431declare void @use32(i32) 1432 1433define i32 @bzhi32_c0(i32 %val, i32 %numlowbits) nounwind { 1434; X86-NOBMI-LABEL: bzhi32_c0: 1435; X86-NOBMI: # %bb.0: 1436; X86-NOBMI-NEXT: pushl %esi 1437; X86-NOBMI-NEXT: subl $8, %esp 1438; X86-NOBMI-NEXT: xorl %ecx, %ecx 1439; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 1440; X86-NOBMI-NEXT: movl $-1, %esi 1441; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1442; X86-NOBMI-NEXT: shrl %cl, %esi 1443; X86-NOBMI-NEXT: movl %esi, (%esp) 1444; X86-NOBMI-NEXT: calll use32 1445; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %esi 1446; X86-NOBMI-NEXT: movl %esi, %eax 1447; X86-NOBMI-NEXT: addl $8, %esp 1448; X86-NOBMI-NEXT: popl %esi 1449; X86-NOBMI-NEXT: retl 1450; 1451; X86-BMI1NOTBM-LABEL: bzhi32_c0: 1452; X86-BMI1NOTBM: # %bb.0: 1453; X86-BMI1NOTBM-NEXT: pushl %esi 1454; X86-BMI1NOTBM-NEXT: subl $8, %esp 1455; X86-BMI1NOTBM-NEXT: xorl %ecx, %ecx 1456; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 1457; X86-BMI1NOTBM-NEXT: movl $-1, %esi 1458; X86-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1459; X86-BMI1NOTBM-NEXT: shrl %cl, %esi 1460; X86-BMI1NOTBM-NEXT: movl %esi, (%esp) 1461; X86-BMI1NOTBM-NEXT: calll use32 1462; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %esi 1463; X86-BMI1NOTBM-NEXT: movl %esi, %eax 1464; X86-BMI1NOTBM-NEXT: addl $8, %esp 1465; X86-BMI1NOTBM-NEXT: popl %esi 1466; X86-BMI1NOTBM-NEXT: retl 1467; 1468; X86-BMI1BMI2-LABEL: bzhi32_c0: 1469; X86-BMI1BMI2: # %bb.0: 1470; X86-BMI1BMI2-NEXT: pushl %ebx 1471; X86-BMI1BMI2-NEXT: subl $8, %esp 1472; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %bl 1473; X86-BMI1BMI2-NEXT: movl %ebx, %eax 1474; X86-BMI1BMI2-NEXT: negb %al 1475; X86-BMI1BMI2-NEXT: movl $-1, %ecx 1476; X86-BMI1BMI2-NEXT: shrxl %eax, %ecx, %eax 1477; X86-BMI1BMI2-NEXT: movl %eax, (%esp) 1478; X86-BMI1BMI2-NEXT: calll use32 1479; X86-BMI1BMI2-NEXT: bzhil %ebx, {{[0-9]+}}(%esp), %eax 1480; X86-BMI1BMI2-NEXT: addl $8, %esp 1481; X86-BMI1BMI2-NEXT: popl %ebx 1482; X86-BMI1BMI2-NEXT: retl 1483; 1484; X64-NOBMI-LABEL: bzhi32_c0: 1485; X64-NOBMI: # %bb.0: 1486; X64-NOBMI-NEXT: pushq %rbp 1487; X64-NOBMI-NEXT: pushq %rbx 1488; X64-NOBMI-NEXT: pushq %rax 1489; X64-NOBMI-NEXT: movl %esi, %ecx 1490; X64-NOBMI-NEXT: movl %edi, %ebx 1491; X64-NOBMI-NEXT: negb %cl 1492; X64-NOBMI-NEXT: movl $-1, %ebp 1493; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1494; X64-NOBMI-NEXT: shrl %cl, %ebp 1495; X64-NOBMI-NEXT: movl %ebp, %edi 1496; X64-NOBMI-NEXT: callq use32 1497; X64-NOBMI-NEXT: andl %ebx, %ebp 1498; X64-NOBMI-NEXT: movl %ebp, %eax 1499; X64-NOBMI-NEXT: addq $8, %rsp 1500; X64-NOBMI-NEXT: popq %rbx 1501; X64-NOBMI-NEXT: popq %rbp 1502; X64-NOBMI-NEXT: retq 1503; 1504; X64-BMI1NOTBM-LABEL: bzhi32_c0: 1505; X64-BMI1NOTBM: # %bb.0: 1506; X64-BMI1NOTBM-NEXT: pushq %rbp 1507; X64-BMI1NOTBM-NEXT: pushq %rbx 1508; X64-BMI1NOTBM-NEXT: pushq %rax 1509; X64-BMI1NOTBM-NEXT: movl %esi, %ecx 1510; X64-BMI1NOTBM-NEXT: movl %edi, %ebx 1511; X64-BMI1NOTBM-NEXT: negb %cl 1512; X64-BMI1NOTBM-NEXT: movl $-1, %ebp 1513; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1514; X64-BMI1NOTBM-NEXT: shrl %cl, %ebp 1515; X64-BMI1NOTBM-NEXT: movl %ebp, %edi 1516; X64-BMI1NOTBM-NEXT: callq use32 1517; X64-BMI1NOTBM-NEXT: andl %ebx, %ebp 1518; X64-BMI1NOTBM-NEXT: movl %ebp, %eax 1519; X64-BMI1NOTBM-NEXT: addq $8, %rsp 1520; X64-BMI1NOTBM-NEXT: popq %rbx 1521; X64-BMI1NOTBM-NEXT: popq %rbp 1522; X64-BMI1NOTBM-NEXT: retq 1523; 1524; X64-BMI1BMI2-LABEL: bzhi32_c0: 1525; X64-BMI1BMI2: # %bb.0: 1526; X64-BMI1BMI2-NEXT: pushq %rbp 1527; X64-BMI1BMI2-NEXT: pushq %rbx 1528; X64-BMI1BMI2-NEXT: pushq %rax 1529; X64-BMI1BMI2-NEXT: movl %esi, %ebx 1530; X64-BMI1BMI2-NEXT: movl %edi, %ebp 1531; X64-BMI1BMI2-NEXT: movl %ebx, %eax 1532; X64-BMI1BMI2-NEXT: negb %al 1533; X64-BMI1BMI2-NEXT: movl $-1, %ecx 1534; X64-BMI1BMI2-NEXT: shrxl %eax, %ecx, %edi 1535; X64-BMI1BMI2-NEXT: callq use32 1536; X64-BMI1BMI2-NEXT: bzhil %ebx, %ebp, %eax 1537; X64-BMI1BMI2-NEXT: addq $8, %rsp 1538; X64-BMI1BMI2-NEXT: popq %rbx 1539; X64-BMI1BMI2-NEXT: popq %rbp 1540; X64-BMI1BMI2-NEXT: retq 1541 %numhighbits = sub i32 32, %numlowbits 1542 %mask = lshr i32 -1, %numhighbits 1543 call void @use32(i32 %mask) 1544 %masked = and i32 %mask, %val 1545 ret i32 %masked 1546} 1547 1548define i32 @bzhi32_c1_indexzext(i32 %val, i8 %numlowbits) nounwind { 1549; X86-NOBMI-LABEL: bzhi32_c1_indexzext: 1550; X86-NOBMI: # %bb.0: 1551; X86-NOBMI-NEXT: pushl %esi 1552; X86-NOBMI-NEXT: subl $8, %esp 1553; X86-NOBMI-NEXT: xorl %ecx, %ecx 1554; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 1555; X86-NOBMI-NEXT: movl $-1, %esi 1556; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1557; X86-NOBMI-NEXT: shrl %cl, %esi 1558; X86-NOBMI-NEXT: movl %esi, (%esp) 1559; X86-NOBMI-NEXT: calll use32 1560; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %esi 1561; X86-NOBMI-NEXT: movl %esi, %eax 1562; X86-NOBMI-NEXT: addl $8, %esp 1563; X86-NOBMI-NEXT: popl %esi 1564; X86-NOBMI-NEXT: retl 1565; 1566; X86-BMI1NOTBM-LABEL: bzhi32_c1_indexzext: 1567; X86-BMI1NOTBM: # %bb.0: 1568; X86-BMI1NOTBM-NEXT: pushl %esi 1569; X86-BMI1NOTBM-NEXT: subl $8, %esp 1570; X86-BMI1NOTBM-NEXT: xorl %ecx, %ecx 1571; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 1572; X86-BMI1NOTBM-NEXT: movl $-1, %esi 1573; X86-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1574; X86-BMI1NOTBM-NEXT: shrl %cl, %esi 1575; X86-BMI1NOTBM-NEXT: movl %esi, (%esp) 1576; X86-BMI1NOTBM-NEXT: calll use32 1577; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %esi 1578; X86-BMI1NOTBM-NEXT: movl %esi, %eax 1579; X86-BMI1NOTBM-NEXT: addl $8, %esp 1580; X86-BMI1NOTBM-NEXT: popl %esi 1581; X86-BMI1NOTBM-NEXT: retl 1582; 1583; X86-BMI1BMI2-LABEL: bzhi32_c1_indexzext: 1584; X86-BMI1BMI2: # %bb.0: 1585; X86-BMI1BMI2-NEXT: pushl %ebx 1586; X86-BMI1BMI2-NEXT: subl $8, %esp 1587; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %bl 1588; X86-BMI1BMI2-NEXT: movl %ebx, %eax 1589; X86-BMI1BMI2-NEXT: negb %al 1590; X86-BMI1BMI2-NEXT: movl $-1, %ecx 1591; X86-BMI1BMI2-NEXT: shrxl %eax, %ecx, %eax 1592; X86-BMI1BMI2-NEXT: movl %eax, (%esp) 1593; X86-BMI1BMI2-NEXT: calll use32 1594; X86-BMI1BMI2-NEXT: bzhil %ebx, {{[0-9]+}}(%esp), %eax 1595; X86-BMI1BMI2-NEXT: addl $8, %esp 1596; X86-BMI1BMI2-NEXT: popl %ebx 1597; X86-BMI1BMI2-NEXT: retl 1598; 1599; X64-NOBMI-LABEL: bzhi32_c1_indexzext: 1600; X64-NOBMI: # %bb.0: 1601; X64-NOBMI-NEXT: pushq %rbp 1602; X64-NOBMI-NEXT: pushq %rbx 1603; X64-NOBMI-NEXT: pushq %rax 1604; X64-NOBMI-NEXT: movl %esi, %ecx 1605; X64-NOBMI-NEXT: movl %edi, %ebx 1606; X64-NOBMI-NEXT: negb %cl 1607; X64-NOBMI-NEXT: movl $-1, %ebp 1608; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1609; X64-NOBMI-NEXT: shrl %cl, %ebp 1610; X64-NOBMI-NEXT: movl %ebp, %edi 1611; X64-NOBMI-NEXT: callq use32 1612; X64-NOBMI-NEXT: andl %ebx, %ebp 1613; X64-NOBMI-NEXT: movl %ebp, %eax 1614; X64-NOBMI-NEXT: addq $8, %rsp 1615; X64-NOBMI-NEXT: popq %rbx 1616; X64-NOBMI-NEXT: popq %rbp 1617; X64-NOBMI-NEXT: retq 1618; 1619; X64-BMI1NOTBM-LABEL: bzhi32_c1_indexzext: 1620; X64-BMI1NOTBM: # %bb.0: 1621; X64-BMI1NOTBM-NEXT: pushq %rbp 1622; X64-BMI1NOTBM-NEXT: pushq %rbx 1623; X64-BMI1NOTBM-NEXT: pushq %rax 1624; X64-BMI1NOTBM-NEXT: movl %esi, %ecx 1625; X64-BMI1NOTBM-NEXT: movl %edi, %ebx 1626; X64-BMI1NOTBM-NEXT: negb %cl 1627; X64-BMI1NOTBM-NEXT: movl $-1, %ebp 1628; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1629; X64-BMI1NOTBM-NEXT: shrl %cl, %ebp 1630; X64-BMI1NOTBM-NEXT: movl %ebp, %edi 1631; X64-BMI1NOTBM-NEXT: callq use32 1632; X64-BMI1NOTBM-NEXT: andl %ebx, %ebp 1633; X64-BMI1NOTBM-NEXT: movl %ebp, %eax 1634; X64-BMI1NOTBM-NEXT: addq $8, %rsp 1635; X64-BMI1NOTBM-NEXT: popq %rbx 1636; X64-BMI1NOTBM-NEXT: popq %rbp 1637; X64-BMI1NOTBM-NEXT: retq 1638; 1639; X64-BMI1BMI2-LABEL: bzhi32_c1_indexzext: 1640; X64-BMI1BMI2: # %bb.0: 1641; X64-BMI1BMI2-NEXT: pushq %rbp 1642; X64-BMI1BMI2-NEXT: pushq %rbx 1643; X64-BMI1BMI2-NEXT: pushq %rax 1644; X64-BMI1BMI2-NEXT: movl %esi, %ebx 1645; X64-BMI1BMI2-NEXT: movl %edi, %ebp 1646; X64-BMI1BMI2-NEXT: movl %ebx, %eax 1647; X64-BMI1BMI2-NEXT: negb %al 1648; X64-BMI1BMI2-NEXT: movl $-1, %ecx 1649; X64-BMI1BMI2-NEXT: shrxl %eax, %ecx, %edi 1650; X64-BMI1BMI2-NEXT: callq use32 1651; X64-BMI1BMI2-NEXT: bzhil %ebx, %ebp, %eax 1652; X64-BMI1BMI2-NEXT: addq $8, %rsp 1653; X64-BMI1BMI2-NEXT: popq %rbx 1654; X64-BMI1BMI2-NEXT: popq %rbp 1655; X64-BMI1BMI2-NEXT: retq 1656 %numhighbits = sub i8 32, %numlowbits 1657 %sh_prom = zext i8 %numhighbits to i32 1658 %mask = lshr i32 -1, %sh_prom 1659 call void @use32(i32 %mask) 1660 %masked = and i32 %mask, %val 1661 ret i32 %masked 1662} 1663 1664define i32 @bzhi32_c2_load(i32* %w, i32 %numlowbits) nounwind { 1665; X86-NOBMI-LABEL: bzhi32_c2_load: 1666; X86-NOBMI: # %bb.0: 1667; X86-NOBMI-NEXT: pushl %esi 1668; X86-NOBMI-NEXT: subl $8, %esp 1669; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 1670; X86-NOBMI-NEXT: xorl %ecx, %ecx 1671; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 1672; X86-NOBMI-NEXT: movl $-1, %edx 1673; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1674; X86-NOBMI-NEXT: shrl %cl, %edx 1675; X86-NOBMI-NEXT: movl (%eax), %esi 1676; X86-NOBMI-NEXT: andl %edx, %esi 1677; X86-NOBMI-NEXT: movl %edx, (%esp) 1678; X86-NOBMI-NEXT: calll use32 1679; X86-NOBMI-NEXT: movl %esi, %eax 1680; X86-NOBMI-NEXT: addl $8, %esp 1681; X86-NOBMI-NEXT: popl %esi 1682; X86-NOBMI-NEXT: retl 1683; 1684; X86-BMI1NOTBM-LABEL: bzhi32_c2_load: 1685; X86-BMI1NOTBM: # %bb.0: 1686; X86-BMI1NOTBM-NEXT: pushl %esi 1687; X86-BMI1NOTBM-NEXT: subl $8, %esp 1688; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 1689; X86-BMI1NOTBM-NEXT: xorl %ecx, %ecx 1690; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 1691; X86-BMI1NOTBM-NEXT: movl $-1, %edx 1692; X86-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1693; X86-BMI1NOTBM-NEXT: shrl %cl, %edx 1694; X86-BMI1NOTBM-NEXT: movl (%eax), %esi 1695; X86-BMI1NOTBM-NEXT: andl %edx, %esi 1696; X86-BMI1NOTBM-NEXT: movl %edx, (%esp) 1697; X86-BMI1NOTBM-NEXT: calll use32 1698; X86-BMI1NOTBM-NEXT: movl %esi, %eax 1699; X86-BMI1NOTBM-NEXT: addl $8, %esp 1700; X86-BMI1NOTBM-NEXT: popl %esi 1701; X86-BMI1NOTBM-NEXT: retl 1702; 1703; X86-BMI1BMI2-LABEL: bzhi32_c2_load: 1704; X86-BMI1BMI2: # %bb.0: 1705; X86-BMI1BMI2-NEXT: pushl %esi 1706; X86-BMI1BMI2-NEXT: subl $8, %esp 1707; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1708; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1709; X86-BMI1BMI2-NEXT: bzhil %ecx, (%eax), %esi 1710; X86-BMI1BMI2-NEXT: # kill: def $cl killed $cl killed $ecx def $ecx 1711; X86-BMI1BMI2-NEXT: negb %cl 1712; X86-BMI1BMI2-NEXT: movl $-1, %eax 1713; X86-BMI1BMI2-NEXT: shrxl %ecx, %eax, %eax 1714; X86-BMI1BMI2-NEXT: movl %eax, (%esp) 1715; X86-BMI1BMI2-NEXT: calll use32 1716; X86-BMI1BMI2-NEXT: movl %esi, %eax 1717; X86-BMI1BMI2-NEXT: addl $8, %esp 1718; X86-BMI1BMI2-NEXT: popl %esi 1719; X86-BMI1BMI2-NEXT: retl 1720; 1721; X64-NOBMI-LABEL: bzhi32_c2_load: 1722; X64-NOBMI: # %bb.0: 1723; X64-NOBMI-NEXT: pushq %rbx 1724; X64-NOBMI-NEXT: movl %esi, %ecx 1725; X64-NOBMI-NEXT: negb %cl 1726; X64-NOBMI-NEXT: movl $-1, %eax 1727; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1728; X64-NOBMI-NEXT: shrl %cl, %eax 1729; X64-NOBMI-NEXT: movl (%rdi), %ebx 1730; X64-NOBMI-NEXT: andl %eax, %ebx 1731; X64-NOBMI-NEXT: movl %eax, %edi 1732; X64-NOBMI-NEXT: callq use32 1733; X64-NOBMI-NEXT: movl %ebx, %eax 1734; X64-NOBMI-NEXT: popq %rbx 1735; X64-NOBMI-NEXT: retq 1736; 1737; X64-BMI1NOTBM-LABEL: bzhi32_c2_load: 1738; X64-BMI1NOTBM: # %bb.0: 1739; X64-BMI1NOTBM-NEXT: pushq %rbx 1740; X64-BMI1NOTBM-NEXT: movl %esi, %ecx 1741; X64-BMI1NOTBM-NEXT: negb %cl 1742; X64-BMI1NOTBM-NEXT: movl $-1, %eax 1743; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1744; X64-BMI1NOTBM-NEXT: shrl %cl, %eax 1745; X64-BMI1NOTBM-NEXT: movl (%rdi), %ebx 1746; X64-BMI1NOTBM-NEXT: andl %eax, %ebx 1747; X64-BMI1NOTBM-NEXT: movl %eax, %edi 1748; X64-BMI1NOTBM-NEXT: callq use32 1749; X64-BMI1NOTBM-NEXT: movl %ebx, %eax 1750; X64-BMI1NOTBM-NEXT: popq %rbx 1751; X64-BMI1NOTBM-NEXT: retq 1752; 1753; X64-BMI1BMI2-LABEL: bzhi32_c2_load: 1754; X64-BMI1BMI2: # %bb.0: 1755; X64-BMI1BMI2-NEXT: pushq %rbx 1756; X64-BMI1BMI2-NEXT: bzhil %esi, (%rdi), %ebx 1757; X64-BMI1BMI2-NEXT: # kill: def $sil killed $sil killed $esi def $esi 1758; X64-BMI1BMI2-NEXT: negb %sil 1759; X64-BMI1BMI2-NEXT: movl $-1, %eax 1760; X64-BMI1BMI2-NEXT: shrxl %esi, %eax, %edi 1761; X64-BMI1BMI2-NEXT: callq use32 1762; X64-BMI1BMI2-NEXT: movl %ebx, %eax 1763; X64-BMI1BMI2-NEXT: popq %rbx 1764; X64-BMI1BMI2-NEXT: retq 1765 %val = load i32, i32* %w 1766 %numhighbits = sub i32 32, %numlowbits 1767 %mask = lshr i32 -1, %numhighbits 1768 call void @use32(i32 %mask) 1769 %masked = and i32 %mask, %val 1770 ret i32 %masked 1771} 1772 1773define i32 @bzhi32_c3_load_indexzext(i32* %w, i8 %numlowbits) nounwind { 1774; X86-NOBMI-LABEL: bzhi32_c3_load_indexzext: 1775; X86-NOBMI: # %bb.0: 1776; X86-NOBMI-NEXT: pushl %esi 1777; X86-NOBMI-NEXT: subl $8, %esp 1778; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 1779; X86-NOBMI-NEXT: xorl %ecx, %ecx 1780; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 1781; X86-NOBMI-NEXT: movl $-1, %edx 1782; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1783; X86-NOBMI-NEXT: shrl %cl, %edx 1784; X86-NOBMI-NEXT: movl (%eax), %esi 1785; X86-NOBMI-NEXT: andl %edx, %esi 1786; X86-NOBMI-NEXT: movl %edx, (%esp) 1787; X86-NOBMI-NEXT: calll use32 1788; X86-NOBMI-NEXT: movl %esi, %eax 1789; X86-NOBMI-NEXT: addl $8, %esp 1790; X86-NOBMI-NEXT: popl %esi 1791; X86-NOBMI-NEXT: retl 1792; 1793; X86-BMI1NOTBM-LABEL: bzhi32_c3_load_indexzext: 1794; X86-BMI1NOTBM: # %bb.0: 1795; X86-BMI1NOTBM-NEXT: pushl %esi 1796; X86-BMI1NOTBM-NEXT: subl $8, %esp 1797; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 1798; X86-BMI1NOTBM-NEXT: xorl %ecx, %ecx 1799; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 1800; X86-BMI1NOTBM-NEXT: movl $-1, %edx 1801; X86-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1802; X86-BMI1NOTBM-NEXT: shrl %cl, %edx 1803; X86-BMI1NOTBM-NEXT: movl (%eax), %esi 1804; X86-BMI1NOTBM-NEXT: andl %edx, %esi 1805; X86-BMI1NOTBM-NEXT: movl %edx, (%esp) 1806; X86-BMI1NOTBM-NEXT: calll use32 1807; X86-BMI1NOTBM-NEXT: movl %esi, %eax 1808; X86-BMI1NOTBM-NEXT: addl $8, %esp 1809; X86-BMI1NOTBM-NEXT: popl %esi 1810; X86-BMI1NOTBM-NEXT: retl 1811; 1812; X86-BMI1BMI2-LABEL: bzhi32_c3_load_indexzext: 1813; X86-BMI1BMI2: # %bb.0: 1814; X86-BMI1BMI2-NEXT: pushl %esi 1815; X86-BMI1BMI2-NEXT: subl $8, %esp 1816; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1817; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1818; X86-BMI1BMI2-NEXT: bzhil %ecx, (%eax), %esi 1819; X86-BMI1BMI2-NEXT: # kill: def $cl killed $cl killed $ecx def $ecx 1820; X86-BMI1BMI2-NEXT: negb %cl 1821; X86-BMI1BMI2-NEXT: movl $-1, %eax 1822; X86-BMI1BMI2-NEXT: shrxl %ecx, %eax, %eax 1823; X86-BMI1BMI2-NEXT: movl %eax, (%esp) 1824; X86-BMI1BMI2-NEXT: calll use32 1825; X86-BMI1BMI2-NEXT: movl %esi, %eax 1826; X86-BMI1BMI2-NEXT: addl $8, %esp 1827; X86-BMI1BMI2-NEXT: popl %esi 1828; X86-BMI1BMI2-NEXT: retl 1829; 1830; X64-NOBMI-LABEL: bzhi32_c3_load_indexzext: 1831; X64-NOBMI: # %bb.0: 1832; X64-NOBMI-NEXT: pushq %rbx 1833; X64-NOBMI-NEXT: movl %esi, %ecx 1834; X64-NOBMI-NEXT: negb %cl 1835; X64-NOBMI-NEXT: movl $-1, %eax 1836; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1837; X64-NOBMI-NEXT: shrl %cl, %eax 1838; X64-NOBMI-NEXT: movl (%rdi), %ebx 1839; X64-NOBMI-NEXT: andl %eax, %ebx 1840; X64-NOBMI-NEXT: movl %eax, %edi 1841; X64-NOBMI-NEXT: callq use32 1842; X64-NOBMI-NEXT: movl %ebx, %eax 1843; X64-NOBMI-NEXT: popq %rbx 1844; X64-NOBMI-NEXT: retq 1845; 1846; X64-BMI1NOTBM-LABEL: bzhi32_c3_load_indexzext: 1847; X64-BMI1NOTBM: # %bb.0: 1848; X64-BMI1NOTBM-NEXT: pushq %rbx 1849; X64-BMI1NOTBM-NEXT: movl %esi, %ecx 1850; X64-BMI1NOTBM-NEXT: negb %cl 1851; X64-BMI1NOTBM-NEXT: movl $-1, %eax 1852; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1853; X64-BMI1NOTBM-NEXT: shrl %cl, %eax 1854; X64-BMI1NOTBM-NEXT: movl (%rdi), %ebx 1855; X64-BMI1NOTBM-NEXT: andl %eax, %ebx 1856; X64-BMI1NOTBM-NEXT: movl %eax, %edi 1857; X64-BMI1NOTBM-NEXT: callq use32 1858; X64-BMI1NOTBM-NEXT: movl %ebx, %eax 1859; X64-BMI1NOTBM-NEXT: popq %rbx 1860; X64-BMI1NOTBM-NEXT: retq 1861; 1862; X64-BMI1BMI2-LABEL: bzhi32_c3_load_indexzext: 1863; X64-BMI1BMI2: # %bb.0: 1864; X64-BMI1BMI2-NEXT: pushq %rbx 1865; X64-BMI1BMI2-NEXT: bzhil %esi, (%rdi), %ebx 1866; X64-BMI1BMI2-NEXT: # kill: def $sil killed $sil killed $esi def $esi 1867; X64-BMI1BMI2-NEXT: negb %sil 1868; X64-BMI1BMI2-NEXT: movl $-1, %eax 1869; X64-BMI1BMI2-NEXT: shrxl %esi, %eax, %edi 1870; X64-BMI1BMI2-NEXT: callq use32 1871; X64-BMI1BMI2-NEXT: movl %ebx, %eax 1872; X64-BMI1BMI2-NEXT: popq %rbx 1873; X64-BMI1BMI2-NEXT: retq 1874 %val = load i32, i32* %w 1875 %numhighbits = sub i8 32, %numlowbits 1876 %sh_prom = zext i8 %numhighbits to i32 1877 %mask = lshr i32 -1, %sh_prom 1878 call void @use32(i32 %mask) 1879 %masked = and i32 %mask, %val 1880 ret i32 %masked 1881} 1882 1883define i32 @bzhi32_c4_commutative(i32 %val, i32 %numlowbits) nounwind { 1884; X86-NOBMI-LABEL: bzhi32_c4_commutative: 1885; X86-NOBMI: # %bb.0: 1886; X86-NOBMI-NEXT: pushl %esi 1887; X86-NOBMI-NEXT: subl $8, %esp 1888; X86-NOBMI-NEXT: xorl %ecx, %ecx 1889; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 1890; X86-NOBMI-NEXT: movl $-1, %esi 1891; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1892; X86-NOBMI-NEXT: shrl %cl, %esi 1893; X86-NOBMI-NEXT: movl %esi, (%esp) 1894; X86-NOBMI-NEXT: calll use32 1895; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %esi 1896; X86-NOBMI-NEXT: movl %esi, %eax 1897; X86-NOBMI-NEXT: addl $8, %esp 1898; X86-NOBMI-NEXT: popl %esi 1899; X86-NOBMI-NEXT: retl 1900; 1901; X86-BMI1NOTBM-LABEL: bzhi32_c4_commutative: 1902; X86-BMI1NOTBM: # %bb.0: 1903; X86-BMI1NOTBM-NEXT: pushl %esi 1904; X86-BMI1NOTBM-NEXT: subl $8, %esp 1905; X86-BMI1NOTBM-NEXT: xorl %ecx, %ecx 1906; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 1907; X86-BMI1NOTBM-NEXT: movl $-1, %esi 1908; X86-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1909; X86-BMI1NOTBM-NEXT: shrl %cl, %esi 1910; X86-BMI1NOTBM-NEXT: movl %esi, (%esp) 1911; X86-BMI1NOTBM-NEXT: calll use32 1912; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %esi 1913; X86-BMI1NOTBM-NEXT: movl %esi, %eax 1914; X86-BMI1NOTBM-NEXT: addl $8, %esp 1915; X86-BMI1NOTBM-NEXT: popl %esi 1916; X86-BMI1NOTBM-NEXT: retl 1917; 1918; X86-BMI1BMI2-LABEL: bzhi32_c4_commutative: 1919; X86-BMI1BMI2: # %bb.0: 1920; X86-BMI1BMI2-NEXT: pushl %ebx 1921; X86-BMI1BMI2-NEXT: subl $8, %esp 1922; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %bl 1923; X86-BMI1BMI2-NEXT: movl %ebx, %eax 1924; X86-BMI1BMI2-NEXT: negb %al 1925; X86-BMI1BMI2-NEXT: movl $-1, %ecx 1926; X86-BMI1BMI2-NEXT: shrxl %eax, %ecx, %eax 1927; X86-BMI1BMI2-NEXT: movl %eax, (%esp) 1928; X86-BMI1BMI2-NEXT: calll use32 1929; X86-BMI1BMI2-NEXT: bzhil %ebx, {{[0-9]+}}(%esp), %eax 1930; X86-BMI1BMI2-NEXT: addl $8, %esp 1931; X86-BMI1BMI2-NEXT: popl %ebx 1932; X86-BMI1BMI2-NEXT: retl 1933; 1934; X64-NOBMI-LABEL: bzhi32_c4_commutative: 1935; X64-NOBMI: # %bb.0: 1936; X64-NOBMI-NEXT: pushq %rbp 1937; X64-NOBMI-NEXT: pushq %rbx 1938; X64-NOBMI-NEXT: pushq %rax 1939; X64-NOBMI-NEXT: movl %esi, %ecx 1940; X64-NOBMI-NEXT: movl %edi, %ebx 1941; X64-NOBMI-NEXT: negb %cl 1942; X64-NOBMI-NEXT: movl $-1, %ebp 1943; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1944; X64-NOBMI-NEXT: shrl %cl, %ebp 1945; X64-NOBMI-NEXT: movl %ebp, %edi 1946; X64-NOBMI-NEXT: callq use32 1947; X64-NOBMI-NEXT: andl %ebx, %ebp 1948; X64-NOBMI-NEXT: movl %ebp, %eax 1949; X64-NOBMI-NEXT: addq $8, %rsp 1950; X64-NOBMI-NEXT: popq %rbx 1951; X64-NOBMI-NEXT: popq %rbp 1952; X64-NOBMI-NEXT: retq 1953; 1954; X64-BMI1NOTBM-LABEL: bzhi32_c4_commutative: 1955; X64-BMI1NOTBM: # %bb.0: 1956; X64-BMI1NOTBM-NEXT: pushq %rbp 1957; X64-BMI1NOTBM-NEXT: pushq %rbx 1958; X64-BMI1NOTBM-NEXT: pushq %rax 1959; X64-BMI1NOTBM-NEXT: movl %esi, %ecx 1960; X64-BMI1NOTBM-NEXT: movl %edi, %ebx 1961; X64-BMI1NOTBM-NEXT: negb %cl 1962; X64-BMI1NOTBM-NEXT: movl $-1, %ebp 1963; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 1964; X64-BMI1NOTBM-NEXT: shrl %cl, %ebp 1965; X64-BMI1NOTBM-NEXT: movl %ebp, %edi 1966; X64-BMI1NOTBM-NEXT: callq use32 1967; X64-BMI1NOTBM-NEXT: andl %ebx, %ebp 1968; X64-BMI1NOTBM-NEXT: movl %ebp, %eax 1969; X64-BMI1NOTBM-NEXT: addq $8, %rsp 1970; X64-BMI1NOTBM-NEXT: popq %rbx 1971; X64-BMI1NOTBM-NEXT: popq %rbp 1972; X64-BMI1NOTBM-NEXT: retq 1973; 1974; X64-BMI1BMI2-LABEL: bzhi32_c4_commutative: 1975; X64-BMI1BMI2: # %bb.0: 1976; X64-BMI1BMI2-NEXT: pushq %rbp 1977; X64-BMI1BMI2-NEXT: pushq %rbx 1978; X64-BMI1BMI2-NEXT: pushq %rax 1979; X64-BMI1BMI2-NEXT: movl %esi, %ebx 1980; X64-BMI1BMI2-NEXT: movl %edi, %ebp 1981; X64-BMI1BMI2-NEXT: movl %ebx, %eax 1982; X64-BMI1BMI2-NEXT: negb %al 1983; X64-BMI1BMI2-NEXT: movl $-1, %ecx 1984; X64-BMI1BMI2-NEXT: shrxl %eax, %ecx, %edi 1985; X64-BMI1BMI2-NEXT: callq use32 1986; X64-BMI1BMI2-NEXT: bzhil %ebx, %ebp, %eax 1987; X64-BMI1BMI2-NEXT: addq $8, %rsp 1988; X64-BMI1BMI2-NEXT: popq %rbx 1989; X64-BMI1BMI2-NEXT: popq %rbp 1990; X64-BMI1BMI2-NEXT: retq 1991 %numhighbits = sub i32 32, %numlowbits 1992 %mask = lshr i32 -1, %numhighbits 1993 call void @use32(i32 %mask) 1994 %masked = and i32 %val, %mask ; swapped order 1995 ret i32 %masked 1996} 1997 1998; 64-bit 1999 2000declare void @use64(i64) 2001 2002define i64 @bzhi64_c0(i64 %val, i64 %numlowbits) nounwind { 2003; X86-NOBMI-LABEL: bzhi64_c0: 2004; X86-NOBMI: # %bb.0: 2005; X86-NOBMI-NEXT: pushl %edi 2006; X86-NOBMI-NEXT: pushl %esi 2007; X86-NOBMI-NEXT: pushl %eax 2008; X86-NOBMI-NEXT: movb $64, %cl 2009; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 2010; X86-NOBMI-NEXT: movl $-1, %esi 2011; X86-NOBMI-NEXT: movl $-1, %edi 2012; X86-NOBMI-NEXT: shrl %cl, %edi 2013; X86-NOBMI-NEXT: shrdl %cl, %esi, %esi 2014; X86-NOBMI-NEXT: testb $32, %cl 2015; X86-NOBMI-NEXT: je .LBB25_2 2016; X86-NOBMI-NEXT: # %bb.1: 2017; X86-NOBMI-NEXT: movl %edi, %esi 2018; X86-NOBMI-NEXT: xorl %edi, %edi 2019; X86-NOBMI-NEXT: .LBB25_2: 2020; X86-NOBMI-NEXT: subl $8, %esp 2021; X86-NOBMI-NEXT: pushl %edi 2022; X86-NOBMI-NEXT: pushl %esi 2023; X86-NOBMI-NEXT: calll use64 2024; X86-NOBMI-NEXT: addl $16, %esp 2025; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %esi 2026; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edi 2027; X86-NOBMI-NEXT: movl %esi, %eax 2028; X86-NOBMI-NEXT: movl %edi, %edx 2029; X86-NOBMI-NEXT: addl $4, %esp 2030; X86-NOBMI-NEXT: popl %esi 2031; X86-NOBMI-NEXT: popl %edi 2032; X86-NOBMI-NEXT: retl 2033; 2034; X86-BMI1NOTBM-LABEL: bzhi64_c0: 2035; X86-BMI1NOTBM: # %bb.0: 2036; X86-BMI1NOTBM-NEXT: pushl %edi 2037; X86-BMI1NOTBM-NEXT: pushl %esi 2038; X86-BMI1NOTBM-NEXT: pushl %eax 2039; X86-BMI1NOTBM-NEXT: movb $64, %cl 2040; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 2041; X86-BMI1NOTBM-NEXT: movl $-1, %esi 2042; X86-BMI1NOTBM-NEXT: movl $-1, %edi 2043; X86-BMI1NOTBM-NEXT: shrl %cl, %edi 2044; X86-BMI1NOTBM-NEXT: shrdl %cl, %esi, %esi 2045; X86-BMI1NOTBM-NEXT: testb $32, %cl 2046; X86-BMI1NOTBM-NEXT: je .LBB25_2 2047; X86-BMI1NOTBM-NEXT: # %bb.1: 2048; X86-BMI1NOTBM-NEXT: movl %edi, %esi 2049; X86-BMI1NOTBM-NEXT: xorl %edi, %edi 2050; X86-BMI1NOTBM-NEXT: .LBB25_2: 2051; X86-BMI1NOTBM-NEXT: subl $8, %esp 2052; X86-BMI1NOTBM-NEXT: pushl %edi 2053; X86-BMI1NOTBM-NEXT: pushl %esi 2054; X86-BMI1NOTBM-NEXT: calll use64 2055; X86-BMI1NOTBM-NEXT: addl $16, %esp 2056; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %esi 2057; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %edi 2058; X86-BMI1NOTBM-NEXT: movl %esi, %eax 2059; X86-BMI1NOTBM-NEXT: movl %edi, %edx 2060; X86-BMI1NOTBM-NEXT: addl $4, %esp 2061; X86-BMI1NOTBM-NEXT: popl %esi 2062; X86-BMI1NOTBM-NEXT: popl %edi 2063; X86-BMI1NOTBM-NEXT: retl 2064; 2065; X86-BMI1BMI2-LABEL: bzhi64_c0: 2066; X86-BMI1BMI2: # %bb.0: 2067; X86-BMI1BMI2-NEXT: pushl %edi 2068; X86-BMI1BMI2-NEXT: pushl %esi 2069; X86-BMI1BMI2-NEXT: pushl %eax 2070; X86-BMI1BMI2-NEXT: movb $64, %cl 2071; X86-BMI1BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 2072; X86-BMI1BMI2-NEXT: movl $-1, %esi 2073; X86-BMI1BMI2-NEXT: shrxl %ecx, %esi, %edi 2074; X86-BMI1BMI2-NEXT: shrdl %cl, %esi, %esi 2075; X86-BMI1BMI2-NEXT: testb $32, %cl 2076; X86-BMI1BMI2-NEXT: je .LBB25_2 2077; X86-BMI1BMI2-NEXT: # %bb.1: 2078; X86-BMI1BMI2-NEXT: movl %edi, %esi 2079; X86-BMI1BMI2-NEXT: xorl %edi, %edi 2080; X86-BMI1BMI2-NEXT: .LBB25_2: 2081; X86-BMI1BMI2-NEXT: subl $8, %esp 2082; X86-BMI1BMI2-NEXT: pushl %edi 2083; X86-BMI1BMI2-NEXT: pushl %esi 2084; X86-BMI1BMI2-NEXT: calll use64 2085; X86-BMI1BMI2-NEXT: addl $16, %esp 2086; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %esi 2087; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %edi 2088; X86-BMI1BMI2-NEXT: movl %esi, %eax 2089; X86-BMI1BMI2-NEXT: movl %edi, %edx 2090; X86-BMI1BMI2-NEXT: addl $4, %esp 2091; X86-BMI1BMI2-NEXT: popl %esi 2092; X86-BMI1BMI2-NEXT: popl %edi 2093; X86-BMI1BMI2-NEXT: retl 2094; 2095; X64-NOBMI-LABEL: bzhi64_c0: 2096; X64-NOBMI: # %bb.0: 2097; X64-NOBMI-NEXT: pushq %r14 2098; X64-NOBMI-NEXT: pushq %rbx 2099; X64-NOBMI-NEXT: pushq %rax 2100; X64-NOBMI-NEXT: movq %rsi, %rcx 2101; X64-NOBMI-NEXT: movq %rdi, %r14 2102; X64-NOBMI-NEXT: negb %cl 2103; X64-NOBMI-NEXT: movq $-1, %rbx 2104; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 2105; X64-NOBMI-NEXT: shrq %cl, %rbx 2106; X64-NOBMI-NEXT: movq %rbx, %rdi 2107; X64-NOBMI-NEXT: callq use64 2108; X64-NOBMI-NEXT: andq %r14, %rbx 2109; X64-NOBMI-NEXT: movq %rbx, %rax 2110; X64-NOBMI-NEXT: addq $8, %rsp 2111; X64-NOBMI-NEXT: popq %rbx 2112; X64-NOBMI-NEXT: popq %r14 2113; X64-NOBMI-NEXT: retq 2114; 2115; X64-BMI1NOTBM-LABEL: bzhi64_c0: 2116; X64-BMI1NOTBM: # %bb.0: 2117; X64-BMI1NOTBM-NEXT: pushq %r14 2118; X64-BMI1NOTBM-NEXT: pushq %rbx 2119; X64-BMI1NOTBM-NEXT: pushq %rax 2120; X64-BMI1NOTBM-NEXT: movq %rsi, %rcx 2121; X64-BMI1NOTBM-NEXT: movq %rdi, %r14 2122; X64-BMI1NOTBM-NEXT: negb %cl 2123; X64-BMI1NOTBM-NEXT: movq $-1, %rbx 2124; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $rcx 2125; X64-BMI1NOTBM-NEXT: shrq %cl, %rbx 2126; X64-BMI1NOTBM-NEXT: movq %rbx, %rdi 2127; X64-BMI1NOTBM-NEXT: callq use64 2128; X64-BMI1NOTBM-NEXT: andq %r14, %rbx 2129; X64-BMI1NOTBM-NEXT: movq %rbx, %rax 2130; X64-BMI1NOTBM-NEXT: addq $8, %rsp 2131; X64-BMI1NOTBM-NEXT: popq %rbx 2132; X64-BMI1NOTBM-NEXT: popq %r14 2133; X64-BMI1NOTBM-NEXT: retq 2134; 2135; X64-BMI1BMI2-LABEL: bzhi64_c0: 2136; X64-BMI1BMI2: # %bb.0: 2137; X64-BMI1BMI2-NEXT: pushq %r14 2138; X64-BMI1BMI2-NEXT: pushq %rbx 2139; X64-BMI1BMI2-NEXT: pushq %rax 2140; X64-BMI1BMI2-NEXT: movq %rsi, %rbx 2141; X64-BMI1BMI2-NEXT: movq %rdi, %r14 2142; X64-BMI1BMI2-NEXT: movl %ebx, %eax 2143; X64-BMI1BMI2-NEXT: negb %al 2144; X64-BMI1BMI2-NEXT: movq $-1, %rcx 2145; X64-BMI1BMI2-NEXT: shrxq %rax, %rcx, %rdi 2146; X64-BMI1BMI2-NEXT: callq use64 2147; X64-BMI1BMI2-NEXT: bzhiq %rbx, %r14, %rax 2148; X64-BMI1BMI2-NEXT: addq $8, %rsp 2149; X64-BMI1BMI2-NEXT: popq %rbx 2150; X64-BMI1BMI2-NEXT: popq %r14 2151; X64-BMI1BMI2-NEXT: retq 2152 %numhighbits = sub i64 64, %numlowbits 2153 %mask = lshr i64 -1, %numhighbits 2154 call void @use64(i64 %mask) 2155 %masked = and i64 %mask, %val 2156 ret i64 %masked 2157} 2158 2159define i64 @bzhi64_c1_indexzext(i64 %val, i8 %numlowbits) nounwind { 2160; X86-NOBMI-LABEL: bzhi64_c1_indexzext: 2161; X86-NOBMI: # %bb.0: 2162; X86-NOBMI-NEXT: pushl %edi 2163; X86-NOBMI-NEXT: pushl %esi 2164; X86-NOBMI-NEXT: pushl %eax 2165; X86-NOBMI-NEXT: movb $64, %cl 2166; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 2167; X86-NOBMI-NEXT: movl $-1, %esi 2168; X86-NOBMI-NEXT: movl $-1, %edi 2169; X86-NOBMI-NEXT: shrl %cl, %edi 2170; X86-NOBMI-NEXT: shrdl %cl, %esi, %esi 2171; X86-NOBMI-NEXT: testb $32, %cl 2172; X86-NOBMI-NEXT: je .LBB26_2 2173; X86-NOBMI-NEXT: # %bb.1: 2174; X86-NOBMI-NEXT: movl %edi, %esi 2175; X86-NOBMI-NEXT: xorl %edi, %edi 2176; X86-NOBMI-NEXT: .LBB26_2: 2177; X86-NOBMI-NEXT: subl $8, %esp 2178; X86-NOBMI-NEXT: pushl %edi 2179; X86-NOBMI-NEXT: pushl %esi 2180; X86-NOBMI-NEXT: calll use64 2181; X86-NOBMI-NEXT: addl $16, %esp 2182; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %esi 2183; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edi 2184; X86-NOBMI-NEXT: movl %esi, %eax 2185; X86-NOBMI-NEXT: movl %edi, %edx 2186; X86-NOBMI-NEXT: addl $4, %esp 2187; X86-NOBMI-NEXT: popl %esi 2188; X86-NOBMI-NEXT: popl %edi 2189; X86-NOBMI-NEXT: retl 2190; 2191; X86-BMI1NOTBM-LABEL: bzhi64_c1_indexzext: 2192; X86-BMI1NOTBM: # %bb.0: 2193; X86-BMI1NOTBM-NEXT: pushl %edi 2194; X86-BMI1NOTBM-NEXT: pushl %esi 2195; X86-BMI1NOTBM-NEXT: pushl %eax 2196; X86-BMI1NOTBM-NEXT: movb $64, %cl 2197; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 2198; X86-BMI1NOTBM-NEXT: movl $-1, %esi 2199; X86-BMI1NOTBM-NEXT: movl $-1, %edi 2200; X86-BMI1NOTBM-NEXT: shrl %cl, %edi 2201; X86-BMI1NOTBM-NEXT: shrdl %cl, %esi, %esi 2202; X86-BMI1NOTBM-NEXT: testb $32, %cl 2203; X86-BMI1NOTBM-NEXT: je .LBB26_2 2204; X86-BMI1NOTBM-NEXT: # %bb.1: 2205; X86-BMI1NOTBM-NEXT: movl %edi, %esi 2206; X86-BMI1NOTBM-NEXT: xorl %edi, %edi 2207; X86-BMI1NOTBM-NEXT: .LBB26_2: 2208; X86-BMI1NOTBM-NEXT: subl $8, %esp 2209; X86-BMI1NOTBM-NEXT: pushl %edi 2210; X86-BMI1NOTBM-NEXT: pushl %esi 2211; X86-BMI1NOTBM-NEXT: calll use64 2212; X86-BMI1NOTBM-NEXT: addl $16, %esp 2213; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %esi 2214; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %edi 2215; X86-BMI1NOTBM-NEXT: movl %esi, %eax 2216; X86-BMI1NOTBM-NEXT: movl %edi, %edx 2217; X86-BMI1NOTBM-NEXT: addl $4, %esp 2218; X86-BMI1NOTBM-NEXT: popl %esi 2219; X86-BMI1NOTBM-NEXT: popl %edi 2220; X86-BMI1NOTBM-NEXT: retl 2221; 2222; X86-BMI1BMI2-LABEL: bzhi64_c1_indexzext: 2223; X86-BMI1BMI2: # %bb.0: 2224; X86-BMI1BMI2-NEXT: pushl %edi 2225; X86-BMI1BMI2-NEXT: pushl %esi 2226; X86-BMI1BMI2-NEXT: pushl %eax 2227; X86-BMI1BMI2-NEXT: movb $64, %cl 2228; X86-BMI1BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 2229; X86-BMI1BMI2-NEXT: movl $-1, %esi 2230; X86-BMI1BMI2-NEXT: shrxl %ecx, %esi, %edi 2231; X86-BMI1BMI2-NEXT: shrdl %cl, %esi, %esi 2232; X86-BMI1BMI2-NEXT: testb $32, %cl 2233; X86-BMI1BMI2-NEXT: je .LBB26_2 2234; X86-BMI1BMI2-NEXT: # %bb.1: 2235; X86-BMI1BMI2-NEXT: movl %edi, %esi 2236; X86-BMI1BMI2-NEXT: xorl %edi, %edi 2237; X86-BMI1BMI2-NEXT: .LBB26_2: 2238; X86-BMI1BMI2-NEXT: subl $8, %esp 2239; X86-BMI1BMI2-NEXT: pushl %edi 2240; X86-BMI1BMI2-NEXT: pushl %esi 2241; X86-BMI1BMI2-NEXT: calll use64 2242; X86-BMI1BMI2-NEXT: addl $16, %esp 2243; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %esi 2244; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %edi 2245; X86-BMI1BMI2-NEXT: movl %esi, %eax 2246; X86-BMI1BMI2-NEXT: movl %edi, %edx 2247; X86-BMI1BMI2-NEXT: addl $4, %esp 2248; X86-BMI1BMI2-NEXT: popl %esi 2249; X86-BMI1BMI2-NEXT: popl %edi 2250; X86-BMI1BMI2-NEXT: retl 2251; 2252; X64-NOBMI-LABEL: bzhi64_c1_indexzext: 2253; X64-NOBMI: # %bb.0: 2254; X64-NOBMI-NEXT: pushq %r14 2255; X64-NOBMI-NEXT: pushq %rbx 2256; X64-NOBMI-NEXT: pushq %rax 2257; X64-NOBMI-NEXT: movl %esi, %ecx 2258; X64-NOBMI-NEXT: movq %rdi, %r14 2259; X64-NOBMI-NEXT: negb %cl 2260; X64-NOBMI-NEXT: movq $-1, %rbx 2261; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2262; X64-NOBMI-NEXT: shrq %cl, %rbx 2263; X64-NOBMI-NEXT: movq %rbx, %rdi 2264; X64-NOBMI-NEXT: callq use64 2265; X64-NOBMI-NEXT: andq %r14, %rbx 2266; X64-NOBMI-NEXT: movq %rbx, %rax 2267; X64-NOBMI-NEXT: addq $8, %rsp 2268; X64-NOBMI-NEXT: popq %rbx 2269; X64-NOBMI-NEXT: popq %r14 2270; X64-NOBMI-NEXT: retq 2271; 2272; X64-BMI1NOTBM-LABEL: bzhi64_c1_indexzext: 2273; X64-BMI1NOTBM: # %bb.0: 2274; X64-BMI1NOTBM-NEXT: pushq %r14 2275; X64-BMI1NOTBM-NEXT: pushq %rbx 2276; X64-BMI1NOTBM-NEXT: pushq %rax 2277; X64-BMI1NOTBM-NEXT: movl %esi, %ecx 2278; X64-BMI1NOTBM-NEXT: movq %rdi, %r14 2279; X64-BMI1NOTBM-NEXT: negb %cl 2280; X64-BMI1NOTBM-NEXT: movq $-1, %rbx 2281; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 2282; X64-BMI1NOTBM-NEXT: shrq %cl, %rbx 2283; X64-BMI1NOTBM-NEXT: movq %rbx, %rdi 2284; X64-BMI1NOTBM-NEXT: callq use64 2285; X64-BMI1NOTBM-NEXT: andq %r14, %rbx 2286; X64-BMI1NOTBM-NEXT: movq %rbx, %rax 2287; X64-BMI1NOTBM-NEXT: addq $8, %rsp 2288; X64-BMI1NOTBM-NEXT: popq %rbx 2289; X64-BMI1NOTBM-NEXT: popq %r14 2290; X64-BMI1NOTBM-NEXT: retq 2291; 2292; X64-BMI1BMI2-LABEL: bzhi64_c1_indexzext: 2293; X64-BMI1BMI2: # %bb.0: 2294; X64-BMI1BMI2-NEXT: pushq %r14 2295; X64-BMI1BMI2-NEXT: pushq %rbx 2296; X64-BMI1BMI2-NEXT: pushq %rax 2297; X64-BMI1BMI2-NEXT: movl %esi, %ebx 2298; X64-BMI1BMI2-NEXT: movq %rdi, %r14 2299; X64-BMI1BMI2-NEXT: movl %ebx, %eax 2300; X64-BMI1BMI2-NEXT: negb %al 2301; X64-BMI1BMI2-NEXT: movq $-1, %rcx 2302; X64-BMI1BMI2-NEXT: shrxq %rax, %rcx, %rdi 2303; X64-BMI1BMI2-NEXT: callq use64 2304; X64-BMI1BMI2-NEXT: bzhiq %rbx, %r14, %rax 2305; X64-BMI1BMI2-NEXT: addq $8, %rsp 2306; X64-BMI1BMI2-NEXT: popq %rbx 2307; X64-BMI1BMI2-NEXT: popq %r14 2308; X64-BMI1BMI2-NEXT: retq 2309 %numhighbits = sub i8 64, %numlowbits 2310 %sh_prom = zext i8 %numhighbits to i64 2311 %mask = lshr i64 -1, %sh_prom 2312 call void @use64(i64 %mask) 2313 %masked = and i64 %mask, %val 2314 ret i64 %masked 2315} 2316 2317define i64 @bzhi64_c2_load(i64* %w, i64 %numlowbits) nounwind { 2318; X86-NOBMI-LABEL: bzhi64_c2_load: 2319; X86-NOBMI: # %bb.0: 2320; X86-NOBMI-NEXT: pushl %ebx 2321; X86-NOBMI-NEXT: pushl %edi 2322; X86-NOBMI-NEXT: pushl %esi 2323; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 2324; X86-NOBMI-NEXT: movb $64, %cl 2325; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 2326; X86-NOBMI-NEXT: movl $-1, %eax 2327; X86-NOBMI-NEXT: movl $-1, %ebx 2328; X86-NOBMI-NEXT: shrl %cl, %ebx 2329; X86-NOBMI-NEXT: shrdl %cl, %eax, %eax 2330; X86-NOBMI-NEXT: testb $32, %cl 2331; X86-NOBMI-NEXT: je .LBB27_2 2332; X86-NOBMI-NEXT: # %bb.1: 2333; X86-NOBMI-NEXT: movl %ebx, %eax 2334; X86-NOBMI-NEXT: xorl %ebx, %ebx 2335; X86-NOBMI-NEXT: .LBB27_2: 2336; X86-NOBMI-NEXT: movl (%edx), %esi 2337; X86-NOBMI-NEXT: andl %eax, %esi 2338; X86-NOBMI-NEXT: movl 4(%edx), %edi 2339; X86-NOBMI-NEXT: andl %ebx, %edi 2340; X86-NOBMI-NEXT: subl $8, %esp 2341; X86-NOBMI-NEXT: pushl %ebx 2342; X86-NOBMI-NEXT: pushl %eax 2343; X86-NOBMI-NEXT: calll use64 2344; X86-NOBMI-NEXT: addl $16, %esp 2345; X86-NOBMI-NEXT: movl %esi, %eax 2346; X86-NOBMI-NEXT: movl %edi, %edx 2347; X86-NOBMI-NEXT: popl %esi 2348; X86-NOBMI-NEXT: popl %edi 2349; X86-NOBMI-NEXT: popl %ebx 2350; X86-NOBMI-NEXT: retl 2351; 2352; X86-BMI1NOTBM-LABEL: bzhi64_c2_load: 2353; X86-BMI1NOTBM: # %bb.0: 2354; X86-BMI1NOTBM-NEXT: pushl %ebx 2355; X86-BMI1NOTBM-NEXT: pushl %edi 2356; X86-BMI1NOTBM-NEXT: pushl %esi 2357; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %edx 2358; X86-BMI1NOTBM-NEXT: movb $64, %cl 2359; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 2360; X86-BMI1NOTBM-NEXT: movl $-1, %eax 2361; X86-BMI1NOTBM-NEXT: movl $-1, %ebx 2362; X86-BMI1NOTBM-NEXT: shrl %cl, %ebx 2363; X86-BMI1NOTBM-NEXT: shrdl %cl, %eax, %eax 2364; X86-BMI1NOTBM-NEXT: testb $32, %cl 2365; X86-BMI1NOTBM-NEXT: je .LBB27_2 2366; X86-BMI1NOTBM-NEXT: # %bb.1: 2367; X86-BMI1NOTBM-NEXT: movl %ebx, %eax 2368; X86-BMI1NOTBM-NEXT: xorl %ebx, %ebx 2369; X86-BMI1NOTBM-NEXT: .LBB27_2: 2370; X86-BMI1NOTBM-NEXT: movl (%edx), %esi 2371; X86-BMI1NOTBM-NEXT: andl %eax, %esi 2372; X86-BMI1NOTBM-NEXT: movl 4(%edx), %edi 2373; X86-BMI1NOTBM-NEXT: andl %ebx, %edi 2374; X86-BMI1NOTBM-NEXT: subl $8, %esp 2375; X86-BMI1NOTBM-NEXT: pushl %ebx 2376; X86-BMI1NOTBM-NEXT: pushl %eax 2377; X86-BMI1NOTBM-NEXT: calll use64 2378; X86-BMI1NOTBM-NEXT: addl $16, %esp 2379; X86-BMI1NOTBM-NEXT: movl %esi, %eax 2380; X86-BMI1NOTBM-NEXT: movl %edi, %edx 2381; X86-BMI1NOTBM-NEXT: popl %esi 2382; X86-BMI1NOTBM-NEXT: popl %edi 2383; X86-BMI1NOTBM-NEXT: popl %ebx 2384; X86-BMI1NOTBM-NEXT: retl 2385; 2386; X86-BMI1BMI2-LABEL: bzhi64_c2_load: 2387; X86-BMI1BMI2: # %bb.0: 2388; X86-BMI1BMI2-NEXT: pushl %ebx 2389; X86-BMI1BMI2-NEXT: pushl %edi 2390; X86-BMI1BMI2-NEXT: pushl %esi 2391; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 2392; X86-BMI1BMI2-NEXT: movb $64, %cl 2393; X86-BMI1BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 2394; X86-BMI1BMI2-NEXT: movl $-1, %eax 2395; X86-BMI1BMI2-NEXT: shrxl %ecx, %eax, %ebx 2396; X86-BMI1BMI2-NEXT: shrdl %cl, %eax, %eax 2397; X86-BMI1BMI2-NEXT: testb $32, %cl 2398; X86-BMI1BMI2-NEXT: je .LBB27_2 2399; X86-BMI1BMI2-NEXT: # %bb.1: 2400; X86-BMI1BMI2-NEXT: movl %ebx, %eax 2401; X86-BMI1BMI2-NEXT: xorl %ebx, %ebx 2402; X86-BMI1BMI2-NEXT: .LBB27_2: 2403; X86-BMI1BMI2-NEXT: movl (%edx), %esi 2404; X86-BMI1BMI2-NEXT: andl %eax, %esi 2405; X86-BMI1BMI2-NEXT: movl 4(%edx), %edi 2406; X86-BMI1BMI2-NEXT: andl %ebx, %edi 2407; X86-BMI1BMI2-NEXT: subl $8, %esp 2408; X86-BMI1BMI2-NEXT: pushl %ebx 2409; X86-BMI1BMI2-NEXT: pushl %eax 2410; X86-BMI1BMI2-NEXT: calll use64 2411; X86-BMI1BMI2-NEXT: addl $16, %esp 2412; X86-BMI1BMI2-NEXT: movl %esi, %eax 2413; X86-BMI1BMI2-NEXT: movl %edi, %edx 2414; X86-BMI1BMI2-NEXT: popl %esi 2415; X86-BMI1BMI2-NEXT: popl %edi 2416; X86-BMI1BMI2-NEXT: popl %ebx 2417; X86-BMI1BMI2-NEXT: retl 2418; 2419; X64-NOBMI-LABEL: bzhi64_c2_load: 2420; X64-NOBMI: # %bb.0: 2421; X64-NOBMI-NEXT: pushq %rbx 2422; X64-NOBMI-NEXT: movq %rsi, %rcx 2423; X64-NOBMI-NEXT: negb %cl 2424; X64-NOBMI-NEXT: movq $-1, %rax 2425; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 2426; X64-NOBMI-NEXT: shrq %cl, %rax 2427; X64-NOBMI-NEXT: movq (%rdi), %rbx 2428; X64-NOBMI-NEXT: andq %rax, %rbx 2429; X64-NOBMI-NEXT: movq %rax, %rdi 2430; X64-NOBMI-NEXT: callq use64 2431; X64-NOBMI-NEXT: movq %rbx, %rax 2432; X64-NOBMI-NEXT: popq %rbx 2433; X64-NOBMI-NEXT: retq 2434; 2435; X64-BMI1NOTBM-LABEL: bzhi64_c2_load: 2436; X64-BMI1NOTBM: # %bb.0: 2437; X64-BMI1NOTBM-NEXT: pushq %rbx 2438; X64-BMI1NOTBM-NEXT: movq %rsi, %rcx 2439; X64-BMI1NOTBM-NEXT: negb %cl 2440; X64-BMI1NOTBM-NEXT: movq $-1, %rax 2441; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $rcx 2442; X64-BMI1NOTBM-NEXT: shrq %cl, %rax 2443; X64-BMI1NOTBM-NEXT: movq (%rdi), %rbx 2444; X64-BMI1NOTBM-NEXT: andq %rax, %rbx 2445; X64-BMI1NOTBM-NEXT: movq %rax, %rdi 2446; X64-BMI1NOTBM-NEXT: callq use64 2447; X64-BMI1NOTBM-NEXT: movq %rbx, %rax 2448; X64-BMI1NOTBM-NEXT: popq %rbx 2449; X64-BMI1NOTBM-NEXT: retq 2450; 2451; X64-BMI1BMI2-LABEL: bzhi64_c2_load: 2452; X64-BMI1BMI2: # %bb.0: 2453; X64-BMI1BMI2-NEXT: pushq %rbx 2454; X64-BMI1BMI2-NEXT: bzhiq %rsi, (%rdi), %rbx 2455; X64-BMI1BMI2-NEXT: # kill: def $sil killed $sil killed $rsi def $rsi 2456; X64-BMI1BMI2-NEXT: negb %sil 2457; X64-BMI1BMI2-NEXT: movq $-1, %rax 2458; X64-BMI1BMI2-NEXT: shrxq %rsi, %rax, %rdi 2459; X64-BMI1BMI2-NEXT: callq use64 2460; X64-BMI1BMI2-NEXT: movq %rbx, %rax 2461; X64-BMI1BMI2-NEXT: popq %rbx 2462; X64-BMI1BMI2-NEXT: retq 2463 %val = load i64, i64* %w 2464 %numhighbits = sub i64 64, %numlowbits 2465 %mask = lshr i64 -1, %numhighbits 2466 call void @use64(i64 %mask) 2467 %masked = and i64 %mask, %val 2468 ret i64 %masked 2469} 2470 2471define i64 @bzhi64_c3_load_indexzext(i64* %w, i8 %numlowbits) nounwind { 2472; X86-NOBMI-LABEL: bzhi64_c3_load_indexzext: 2473; X86-NOBMI: # %bb.0: 2474; X86-NOBMI-NEXT: pushl %ebx 2475; X86-NOBMI-NEXT: pushl %edi 2476; X86-NOBMI-NEXT: pushl %esi 2477; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 2478; X86-NOBMI-NEXT: movb $64, %cl 2479; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 2480; X86-NOBMI-NEXT: movl $-1, %eax 2481; X86-NOBMI-NEXT: movl $-1, %ebx 2482; X86-NOBMI-NEXT: shrl %cl, %ebx 2483; X86-NOBMI-NEXT: shrdl %cl, %eax, %eax 2484; X86-NOBMI-NEXT: testb $32, %cl 2485; X86-NOBMI-NEXT: je .LBB28_2 2486; X86-NOBMI-NEXT: # %bb.1: 2487; X86-NOBMI-NEXT: movl %ebx, %eax 2488; X86-NOBMI-NEXT: xorl %ebx, %ebx 2489; X86-NOBMI-NEXT: .LBB28_2: 2490; X86-NOBMI-NEXT: movl (%edx), %esi 2491; X86-NOBMI-NEXT: andl %eax, %esi 2492; X86-NOBMI-NEXT: movl 4(%edx), %edi 2493; X86-NOBMI-NEXT: andl %ebx, %edi 2494; X86-NOBMI-NEXT: subl $8, %esp 2495; X86-NOBMI-NEXT: pushl %ebx 2496; X86-NOBMI-NEXT: pushl %eax 2497; X86-NOBMI-NEXT: calll use64 2498; X86-NOBMI-NEXT: addl $16, %esp 2499; X86-NOBMI-NEXT: movl %esi, %eax 2500; X86-NOBMI-NEXT: movl %edi, %edx 2501; X86-NOBMI-NEXT: popl %esi 2502; X86-NOBMI-NEXT: popl %edi 2503; X86-NOBMI-NEXT: popl %ebx 2504; X86-NOBMI-NEXT: retl 2505; 2506; X86-BMI1NOTBM-LABEL: bzhi64_c3_load_indexzext: 2507; X86-BMI1NOTBM: # %bb.0: 2508; X86-BMI1NOTBM-NEXT: pushl %ebx 2509; X86-BMI1NOTBM-NEXT: pushl %edi 2510; X86-BMI1NOTBM-NEXT: pushl %esi 2511; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %edx 2512; X86-BMI1NOTBM-NEXT: movb $64, %cl 2513; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 2514; X86-BMI1NOTBM-NEXT: movl $-1, %eax 2515; X86-BMI1NOTBM-NEXT: movl $-1, %ebx 2516; X86-BMI1NOTBM-NEXT: shrl %cl, %ebx 2517; X86-BMI1NOTBM-NEXT: shrdl %cl, %eax, %eax 2518; X86-BMI1NOTBM-NEXT: testb $32, %cl 2519; X86-BMI1NOTBM-NEXT: je .LBB28_2 2520; X86-BMI1NOTBM-NEXT: # %bb.1: 2521; X86-BMI1NOTBM-NEXT: movl %ebx, %eax 2522; X86-BMI1NOTBM-NEXT: xorl %ebx, %ebx 2523; X86-BMI1NOTBM-NEXT: .LBB28_2: 2524; X86-BMI1NOTBM-NEXT: movl (%edx), %esi 2525; X86-BMI1NOTBM-NEXT: andl %eax, %esi 2526; X86-BMI1NOTBM-NEXT: movl 4(%edx), %edi 2527; X86-BMI1NOTBM-NEXT: andl %ebx, %edi 2528; X86-BMI1NOTBM-NEXT: subl $8, %esp 2529; X86-BMI1NOTBM-NEXT: pushl %ebx 2530; X86-BMI1NOTBM-NEXT: pushl %eax 2531; X86-BMI1NOTBM-NEXT: calll use64 2532; X86-BMI1NOTBM-NEXT: addl $16, %esp 2533; X86-BMI1NOTBM-NEXT: movl %esi, %eax 2534; X86-BMI1NOTBM-NEXT: movl %edi, %edx 2535; X86-BMI1NOTBM-NEXT: popl %esi 2536; X86-BMI1NOTBM-NEXT: popl %edi 2537; X86-BMI1NOTBM-NEXT: popl %ebx 2538; X86-BMI1NOTBM-NEXT: retl 2539; 2540; X86-BMI1BMI2-LABEL: bzhi64_c3_load_indexzext: 2541; X86-BMI1BMI2: # %bb.0: 2542; X86-BMI1BMI2-NEXT: pushl %ebx 2543; X86-BMI1BMI2-NEXT: pushl %edi 2544; X86-BMI1BMI2-NEXT: pushl %esi 2545; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 2546; X86-BMI1BMI2-NEXT: movb $64, %cl 2547; X86-BMI1BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 2548; X86-BMI1BMI2-NEXT: movl $-1, %eax 2549; X86-BMI1BMI2-NEXT: shrxl %ecx, %eax, %ebx 2550; X86-BMI1BMI2-NEXT: shrdl %cl, %eax, %eax 2551; X86-BMI1BMI2-NEXT: testb $32, %cl 2552; X86-BMI1BMI2-NEXT: je .LBB28_2 2553; X86-BMI1BMI2-NEXT: # %bb.1: 2554; X86-BMI1BMI2-NEXT: movl %ebx, %eax 2555; X86-BMI1BMI2-NEXT: xorl %ebx, %ebx 2556; X86-BMI1BMI2-NEXT: .LBB28_2: 2557; X86-BMI1BMI2-NEXT: movl (%edx), %esi 2558; X86-BMI1BMI2-NEXT: andl %eax, %esi 2559; X86-BMI1BMI2-NEXT: movl 4(%edx), %edi 2560; X86-BMI1BMI2-NEXT: andl %ebx, %edi 2561; X86-BMI1BMI2-NEXT: subl $8, %esp 2562; X86-BMI1BMI2-NEXT: pushl %ebx 2563; X86-BMI1BMI2-NEXT: pushl %eax 2564; X86-BMI1BMI2-NEXT: calll use64 2565; X86-BMI1BMI2-NEXT: addl $16, %esp 2566; X86-BMI1BMI2-NEXT: movl %esi, %eax 2567; X86-BMI1BMI2-NEXT: movl %edi, %edx 2568; X86-BMI1BMI2-NEXT: popl %esi 2569; X86-BMI1BMI2-NEXT: popl %edi 2570; X86-BMI1BMI2-NEXT: popl %ebx 2571; X86-BMI1BMI2-NEXT: retl 2572; 2573; X64-NOBMI-LABEL: bzhi64_c3_load_indexzext: 2574; X64-NOBMI: # %bb.0: 2575; X64-NOBMI-NEXT: pushq %rbx 2576; X64-NOBMI-NEXT: movl %esi, %ecx 2577; X64-NOBMI-NEXT: negb %cl 2578; X64-NOBMI-NEXT: movq $-1, %rax 2579; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2580; X64-NOBMI-NEXT: shrq %cl, %rax 2581; X64-NOBMI-NEXT: movq (%rdi), %rbx 2582; X64-NOBMI-NEXT: andq %rax, %rbx 2583; X64-NOBMI-NEXT: movq %rax, %rdi 2584; X64-NOBMI-NEXT: callq use64 2585; X64-NOBMI-NEXT: movq %rbx, %rax 2586; X64-NOBMI-NEXT: popq %rbx 2587; X64-NOBMI-NEXT: retq 2588; 2589; X64-BMI1NOTBM-LABEL: bzhi64_c3_load_indexzext: 2590; X64-BMI1NOTBM: # %bb.0: 2591; X64-BMI1NOTBM-NEXT: pushq %rbx 2592; X64-BMI1NOTBM-NEXT: movl %esi, %ecx 2593; X64-BMI1NOTBM-NEXT: negb %cl 2594; X64-BMI1NOTBM-NEXT: movq $-1, %rax 2595; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $ecx 2596; X64-BMI1NOTBM-NEXT: shrq %cl, %rax 2597; X64-BMI1NOTBM-NEXT: movq (%rdi), %rbx 2598; X64-BMI1NOTBM-NEXT: andq %rax, %rbx 2599; X64-BMI1NOTBM-NEXT: movq %rax, %rdi 2600; X64-BMI1NOTBM-NEXT: callq use64 2601; X64-BMI1NOTBM-NEXT: movq %rbx, %rax 2602; X64-BMI1NOTBM-NEXT: popq %rbx 2603; X64-BMI1NOTBM-NEXT: retq 2604; 2605; X64-BMI1BMI2-LABEL: bzhi64_c3_load_indexzext: 2606; X64-BMI1BMI2: # %bb.0: 2607; X64-BMI1BMI2-NEXT: pushq %rbx 2608; X64-BMI1BMI2-NEXT: # kill: def $esi killed $esi def $rsi 2609; X64-BMI1BMI2-NEXT: bzhiq %rsi, (%rdi), %rbx 2610; X64-BMI1BMI2-NEXT: # kill: def $sil killed $sil killed $rsi def $rsi 2611; X64-BMI1BMI2-NEXT: negb %sil 2612; X64-BMI1BMI2-NEXT: movq $-1, %rax 2613; X64-BMI1BMI2-NEXT: shrxq %rsi, %rax, %rdi 2614; X64-BMI1BMI2-NEXT: callq use64 2615; X64-BMI1BMI2-NEXT: movq %rbx, %rax 2616; X64-BMI1BMI2-NEXT: popq %rbx 2617; X64-BMI1BMI2-NEXT: retq 2618 %val = load i64, i64* %w 2619 %numhighbits = sub i8 64, %numlowbits 2620 %sh_prom = zext i8 %numhighbits to i64 2621 %mask = lshr i64 -1, %sh_prom 2622 call void @use64(i64 %mask) 2623 %masked = and i64 %mask, %val 2624 ret i64 %masked 2625} 2626 2627define i64 @bzhi64_c4_commutative(i64 %val, i64 %numlowbits) nounwind { 2628; X86-NOBMI-LABEL: bzhi64_c4_commutative: 2629; X86-NOBMI: # %bb.0: 2630; X86-NOBMI-NEXT: pushl %edi 2631; X86-NOBMI-NEXT: pushl %esi 2632; X86-NOBMI-NEXT: pushl %eax 2633; X86-NOBMI-NEXT: movb $64, %cl 2634; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 2635; X86-NOBMI-NEXT: movl $-1, %esi 2636; X86-NOBMI-NEXT: movl $-1, %edi 2637; X86-NOBMI-NEXT: shrl %cl, %edi 2638; X86-NOBMI-NEXT: shrdl %cl, %esi, %esi 2639; X86-NOBMI-NEXT: testb $32, %cl 2640; X86-NOBMI-NEXT: je .LBB29_2 2641; X86-NOBMI-NEXT: # %bb.1: 2642; X86-NOBMI-NEXT: movl %edi, %esi 2643; X86-NOBMI-NEXT: xorl %edi, %edi 2644; X86-NOBMI-NEXT: .LBB29_2: 2645; X86-NOBMI-NEXT: subl $8, %esp 2646; X86-NOBMI-NEXT: pushl %edi 2647; X86-NOBMI-NEXT: pushl %esi 2648; X86-NOBMI-NEXT: calll use64 2649; X86-NOBMI-NEXT: addl $16, %esp 2650; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %esi 2651; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edi 2652; X86-NOBMI-NEXT: movl %esi, %eax 2653; X86-NOBMI-NEXT: movl %edi, %edx 2654; X86-NOBMI-NEXT: addl $4, %esp 2655; X86-NOBMI-NEXT: popl %esi 2656; X86-NOBMI-NEXT: popl %edi 2657; X86-NOBMI-NEXT: retl 2658; 2659; X86-BMI1NOTBM-LABEL: bzhi64_c4_commutative: 2660; X86-BMI1NOTBM: # %bb.0: 2661; X86-BMI1NOTBM-NEXT: pushl %edi 2662; X86-BMI1NOTBM-NEXT: pushl %esi 2663; X86-BMI1NOTBM-NEXT: pushl %eax 2664; X86-BMI1NOTBM-NEXT: movb $64, %cl 2665; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 2666; X86-BMI1NOTBM-NEXT: movl $-1, %esi 2667; X86-BMI1NOTBM-NEXT: movl $-1, %edi 2668; X86-BMI1NOTBM-NEXT: shrl %cl, %edi 2669; X86-BMI1NOTBM-NEXT: shrdl %cl, %esi, %esi 2670; X86-BMI1NOTBM-NEXT: testb $32, %cl 2671; X86-BMI1NOTBM-NEXT: je .LBB29_2 2672; X86-BMI1NOTBM-NEXT: # %bb.1: 2673; X86-BMI1NOTBM-NEXT: movl %edi, %esi 2674; X86-BMI1NOTBM-NEXT: xorl %edi, %edi 2675; X86-BMI1NOTBM-NEXT: .LBB29_2: 2676; X86-BMI1NOTBM-NEXT: subl $8, %esp 2677; X86-BMI1NOTBM-NEXT: pushl %edi 2678; X86-BMI1NOTBM-NEXT: pushl %esi 2679; X86-BMI1NOTBM-NEXT: calll use64 2680; X86-BMI1NOTBM-NEXT: addl $16, %esp 2681; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %esi 2682; X86-BMI1NOTBM-NEXT: andl {{[0-9]+}}(%esp), %edi 2683; X86-BMI1NOTBM-NEXT: movl %esi, %eax 2684; X86-BMI1NOTBM-NEXT: movl %edi, %edx 2685; X86-BMI1NOTBM-NEXT: addl $4, %esp 2686; X86-BMI1NOTBM-NEXT: popl %esi 2687; X86-BMI1NOTBM-NEXT: popl %edi 2688; X86-BMI1NOTBM-NEXT: retl 2689; 2690; X86-BMI1BMI2-LABEL: bzhi64_c4_commutative: 2691; X86-BMI1BMI2: # %bb.0: 2692; X86-BMI1BMI2-NEXT: pushl %edi 2693; X86-BMI1BMI2-NEXT: pushl %esi 2694; X86-BMI1BMI2-NEXT: pushl %eax 2695; X86-BMI1BMI2-NEXT: movb $64, %cl 2696; X86-BMI1BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 2697; X86-BMI1BMI2-NEXT: movl $-1, %esi 2698; X86-BMI1BMI2-NEXT: shrxl %ecx, %esi, %edi 2699; X86-BMI1BMI2-NEXT: shrdl %cl, %esi, %esi 2700; X86-BMI1BMI2-NEXT: testb $32, %cl 2701; X86-BMI1BMI2-NEXT: je .LBB29_2 2702; X86-BMI1BMI2-NEXT: # %bb.1: 2703; X86-BMI1BMI2-NEXT: movl %edi, %esi 2704; X86-BMI1BMI2-NEXT: xorl %edi, %edi 2705; X86-BMI1BMI2-NEXT: .LBB29_2: 2706; X86-BMI1BMI2-NEXT: subl $8, %esp 2707; X86-BMI1BMI2-NEXT: pushl %edi 2708; X86-BMI1BMI2-NEXT: pushl %esi 2709; X86-BMI1BMI2-NEXT: calll use64 2710; X86-BMI1BMI2-NEXT: addl $16, %esp 2711; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %esi 2712; X86-BMI1BMI2-NEXT: andl {{[0-9]+}}(%esp), %edi 2713; X86-BMI1BMI2-NEXT: movl %esi, %eax 2714; X86-BMI1BMI2-NEXT: movl %edi, %edx 2715; X86-BMI1BMI2-NEXT: addl $4, %esp 2716; X86-BMI1BMI2-NEXT: popl %esi 2717; X86-BMI1BMI2-NEXT: popl %edi 2718; X86-BMI1BMI2-NEXT: retl 2719; 2720; X64-NOBMI-LABEL: bzhi64_c4_commutative: 2721; X64-NOBMI: # %bb.0: 2722; X64-NOBMI-NEXT: pushq %r14 2723; X64-NOBMI-NEXT: pushq %rbx 2724; X64-NOBMI-NEXT: pushq %rax 2725; X64-NOBMI-NEXT: movq %rsi, %rcx 2726; X64-NOBMI-NEXT: movq %rdi, %r14 2727; X64-NOBMI-NEXT: negb %cl 2728; X64-NOBMI-NEXT: movq $-1, %rbx 2729; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 2730; X64-NOBMI-NEXT: shrq %cl, %rbx 2731; X64-NOBMI-NEXT: movq %rbx, %rdi 2732; X64-NOBMI-NEXT: callq use64 2733; X64-NOBMI-NEXT: andq %r14, %rbx 2734; X64-NOBMI-NEXT: movq %rbx, %rax 2735; X64-NOBMI-NEXT: addq $8, %rsp 2736; X64-NOBMI-NEXT: popq %rbx 2737; X64-NOBMI-NEXT: popq %r14 2738; X64-NOBMI-NEXT: retq 2739; 2740; X64-BMI1NOTBM-LABEL: bzhi64_c4_commutative: 2741; X64-BMI1NOTBM: # %bb.0: 2742; X64-BMI1NOTBM-NEXT: pushq %r14 2743; X64-BMI1NOTBM-NEXT: pushq %rbx 2744; X64-BMI1NOTBM-NEXT: pushq %rax 2745; X64-BMI1NOTBM-NEXT: movq %rsi, %rcx 2746; X64-BMI1NOTBM-NEXT: movq %rdi, %r14 2747; X64-BMI1NOTBM-NEXT: negb %cl 2748; X64-BMI1NOTBM-NEXT: movq $-1, %rbx 2749; X64-BMI1NOTBM-NEXT: # kill: def $cl killed $cl killed $rcx 2750; X64-BMI1NOTBM-NEXT: shrq %cl, %rbx 2751; X64-BMI1NOTBM-NEXT: movq %rbx, %rdi 2752; X64-BMI1NOTBM-NEXT: callq use64 2753; X64-BMI1NOTBM-NEXT: andq %r14, %rbx 2754; X64-BMI1NOTBM-NEXT: movq %rbx, %rax 2755; X64-BMI1NOTBM-NEXT: addq $8, %rsp 2756; X64-BMI1NOTBM-NEXT: popq %rbx 2757; X64-BMI1NOTBM-NEXT: popq %r14 2758; X64-BMI1NOTBM-NEXT: retq 2759; 2760; X64-BMI1BMI2-LABEL: bzhi64_c4_commutative: 2761; X64-BMI1BMI2: # %bb.0: 2762; X64-BMI1BMI2-NEXT: pushq %r14 2763; X64-BMI1BMI2-NEXT: pushq %rbx 2764; X64-BMI1BMI2-NEXT: pushq %rax 2765; X64-BMI1BMI2-NEXT: movq %rsi, %rbx 2766; X64-BMI1BMI2-NEXT: movq %rdi, %r14 2767; X64-BMI1BMI2-NEXT: movl %ebx, %eax 2768; X64-BMI1BMI2-NEXT: negb %al 2769; X64-BMI1BMI2-NEXT: movq $-1, %rcx 2770; X64-BMI1BMI2-NEXT: shrxq %rax, %rcx, %rdi 2771; X64-BMI1BMI2-NEXT: callq use64 2772; X64-BMI1BMI2-NEXT: bzhiq %rbx, %r14, %rax 2773; X64-BMI1BMI2-NEXT: addq $8, %rsp 2774; X64-BMI1BMI2-NEXT: popq %rbx 2775; X64-BMI1BMI2-NEXT: popq %r14 2776; X64-BMI1BMI2-NEXT: retq 2777 %numhighbits = sub i64 64, %numlowbits 2778 %mask = lshr i64 -1, %numhighbits 2779 call void @use64(i64 %mask) 2780 %masked = and i64 %val, %mask ; swapped order 2781 ret i64 %masked 2782} 2783 2784; ---------------------------------------------------------------------------- ; 2785; Pattern d. 32-bit. 2786; ---------------------------------------------------------------------------- ; 2787 2788define i32 @bzhi32_d0(i32 %val, i32 %numlowbits) nounwind { 2789; X86-NOBMI-LABEL: bzhi32_d0: 2790; X86-NOBMI: # %bb.0: 2791; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2792; X86-NOBMI-NEXT: xorl %ecx, %ecx 2793; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 2794; X86-NOBMI-NEXT: shll %cl, %eax 2795; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2796; X86-NOBMI-NEXT: shrl %cl, %eax 2797; X86-NOBMI-NEXT: retl 2798; 2799; X86-BMI1NOTBM-LABEL: bzhi32_d0: 2800; X86-BMI1NOTBM: # %bb.0: 2801; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %al 2802; X86-BMI1NOTBM-NEXT: shll $8, %eax 2803; X86-BMI1NOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 2804; X86-BMI1NOTBM-NEXT: retl 2805; 2806; X86-BMI1BMI2-LABEL: bzhi32_d0: 2807; X86-BMI1BMI2: # %bb.0: 2808; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 2809; X86-BMI1BMI2-NEXT: bzhil %eax, {{[0-9]+}}(%esp), %eax 2810; X86-BMI1BMI2-NEXT: retl 2811; 2812; X64-NOBMI-LABEL: bzhi32_d0: 2813; X64-NOBMI: # %bb.0: 2814; X64-NOBMI-NEXT: movl %esi, %ecx 2815; X64-NOBMI-NEXT: movl %edi, %eax 2816; X64-NOBMI-NEXT: negb %cl 2817; X64-NOBMI-NEXT: shll %cl, %eax 2818; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2819; X64-NOBMI-NEXT: shrl %cl, %eax 2820; X64-NOBMI-NEXT: retq 2821; 2822; X64-BMI1NOTBM-LABEL: bzhi32_d0: 2823; X64-BMI1NOTBM: # %bb.0: 2824; X64-BMI1NOTBM-NEXT: shll $8, %esi 2825; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax 2826; X64-BMI1NOTBM-NEXT: retq 2827; 2828; X64-BMI1BMI2-LABEL: bzhi32_d0: 2829; X64-BMI1BMI2: # %bb.0: 2830; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax 2831; X64-BMI1BMI2-NEXT: retq 2832 %numhighbits = sub i32 32, %numlowbits 2833 %highbitscleared = shl i32 %val, %numhighbits 2834 %masked = lshr i32 %highbitscleared, %numhighbits 2835 ret i32 %masked 2836} 2837 2838define i32 @bzhi32_d1_indexzext(i32 %val, i8 %numlowbits) nounwind { 2839; X86-NOBMI-LABEL: bzhi32_d1_indexzext: 2840; X86-NOBMI: # %bb.0: 2841; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2842; X86-NOBMI-NEXT: xorl %ecx, %ecx 2843; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 2844; X86-NOBMI-NEXT: shll %cl, %eax 2845; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2846; X86-NOBMI-NEXT: shrl %cl, %eax 2847; X86-NOBMI-NEXT: retl 2848; 2849; X86-BMI1NOTBM-LABEL: bzhi32_d1_indexzext: 2850; X86-BMI1NOTBM: # %bb.0: 2851; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %al 2852; X86-BMI1NOTBM-NEXT: shll $8, %eax 2853; X86-BMI1NOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 2854; X86-BMI1NOTBM-NEXT: retl 2855; 2856; X86-BMI1BMI2-LABEL: bzhi32_d1_indexzext: 2857; X86-BMI1BMI2: # %bb.0: 2858; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 2859; X86-BMI1BMI2-NEXT: bzhil %eax, {{[0-9]+}}(%esp), %eax 2860; X86-BMI1BMI2-NEXT: retl 2861; 2862; X64-NOBMI-LABEL: bzhi32_d1_indexzext: 2863; X64-NOBMI: # %bb.0: 2864; X64-NOBMI-NEXT: movl %esi, %ecx 2865; X64-NOBMI-NEXT: movl %edi, %eax 2866; X64-NOBMI-NEXT: negb %cl 2867; X64-NOBMI-NEXT: shll %cl, %eax 2868; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2869; X64-NOBMI-NEXT: shrl %cl, %eax 2870; X64-NOBMI-NEXT: retq 2871; 2872; X64-BMI1NOTBM-LABEL: bzhi32_d1_indexzext: 2873; X64-BMI1NOTBM: # %bb.0: 2874; X64-BMI1NOTBM-NEXT: shll $8, %esi 2875; X64-BMI1NOTBM-NEXT: bextrl %esi, %edi, %eax 2876; X64-BMI1NOTBM-NEXT: retq 2877; 2878; X64-BMI1BMI2-LABEL: bzhi32_d1_indexzext: 2879; X64-BMI1BMI2: # %bb.0: 2880; X64-BMI1BMI2-NEXT: bzhil %esi, %edi, %eax 2881; X64-BMI1BMI2-NEXT: retq 2882 %numhighbits = sub i8 32, %numlowbits 2883 %sh_prom = zext i8 %numhighbits to i32 2884 %highbitscleared = shl i32 %val, %sh_prom 2885 %masked = lshr i32 %highbitscleared, %sh_prom 2886 ret i32 %masked 2887} 2888 2889define i32 @bzhi32_d2_load(i32* %w, i32 %numlowbits) nounwind { 2890; X86-NOBMI-LABEL: bzhi32_d2_load: 2891; X86-NOBMI: # %bb.0: 2892; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2893; X86-NOBMI-NEXT: movl (%eax), %eax 2894; X86-NOBMI-NEXT: xorl %ecx, %ecx 2895; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 2896; X86-NOBMI-NEXT: shll %cl, %eax 2897; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2898; X86-NOBMI-NEXT: shrl %cl, %eax 2899; X86-NOBMI-NEXT: retl 2900; 2901; X86-BMI1NOTBM-LABEL: bzhi32_d2_load: 2902; X86-BMI1NOTBM: # %bb.0: 2903; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 2904; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 2905; X86-BMI1NOTBM-NEXT: shll $8, %ecx 2906; X86-BMI1NOTBM-NEXT: bextrl %ecx, (%eax), %eax 2907; X86-BMI1NOTBM-NEXT: retl 2908; 2909; X86-BMI1BMI2-LABEL: bzhi32_d2_load: 2910; X86-BMI1BMI2: # %bb.0: 2911; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 2912; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 2913; X86-BMI1BMI2-NEXT: bzhil %ecx, (%eax), %eax 2914; X86-BMI1BMI2-NEXT: retl 2915; 2916; X64-NOBMI-LABEL: bzhi32_d2_load: 2917; X64-NOBMI: # %bb.0: 2918; X64-NOBMI-NEXT: movl %esi, %ecx 2919; X64-NOBMI-NEXT: movl (%rdi), %eax 2920; X64-NOBMI-NEXT: negb %cl 2921; X64-NOBMI-NEXT: shll %cl, %eax 2922; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2923; X64-NOBMI-NEXT: shrl %cl, %eax 2924; X64-NOBMI-NEXT: retq 2925; 2926; X64-BMI1NOTBM-LABEL: bzhi32_d2_load: 2927; X64-BMI1NOTBM: # %bb.0: 2928; X64-BMI1NOTBM-NEXT: shll $8, %esi 2929; X64-BMI1NOTBM-NEXT: bextrl %esi, (%rdi), %eax 2930; X64-BMI1NOTBM-NEXT: retq 2931; 2932; X64-BMI1BMI2-LABEL: bzhi32_d2_load: 2933; X64-BMI1BMI2: # %bb.0: 2934; X64-BMI1BMI2-NEXT: bzhil %esi, (%rdi), %eax 2935; X64-BMI1BMI2-NEXT: retq 2936 %val = load i32, i32* %w 2937 %numhighbits = sub i32 32, %numlowbits 2938 %highbitscleared = shl i32 %val, %numhighbits 2939 %masked = lshr i32 %highbitscleared, %numhighbits 2940 ret i32 %masked 2941} 2942 2943define i32 @bzhi32_d3_load_indexzext(i32* %w, i8 %numlowbits) nounwind { 2944; X86-NOBMI-LABEL: bzhi32_d3_load_indexzext: 2945; X86-NOBMI: # %bb.0: 2946; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2947; X86-NOBMI-NEXT: movl (%eax), %eax 2948; X86-NOBMI-NEXT: xorl %ecx, %ecx 2949; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 2950; X86-NOBMI-NEXT: shll %cl, %eax 2951; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2952; X86-NOBMI-NEXT: shrl %cl, %eax 2953; X86-NOBMI-NEXT: retl 2954; 2955; X86-BMI1NOTBM-LABEL: bzhi32_d3_load_indexzext: 2956; X86-BMI1NOTBM: # %bb.0: 2957; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 2958; X86-BMI1NOTBM-NEXT: movb {{[0-9]+}}(%esp), %cl 2959; X86-BMI1NOTBM-NEXT: shll $8, %ecx 2960; X86-BMI1NOTBM-NEXT: bextrl %ecx, (%eax), %eax 2961; X86-BMI1NOTBM-NEXT: retl 2962; 2963; X86-BMI1BMI2-LABEL: bzhi32_d3_load_indexzext: 2964; X86-BMI1BMI2: # %bb.0: 2965; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 2966; X86-BMI1BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 2967; X86-BMI1BMI2-NEXT: bzhil %ecx, (%eax), %eax 2968; X86-BMI1BMI2-NEXT: retl 2969; 2970; X64-NOBMI-LABEL: bzhi32_d3_load_indexzext: 2971; X64-NOBMI: # %bb.0: 2972; X64-NOBMI-NEXT: movl %esi, %ecx 2973; X64-NOBMI-NEXT: movl (%rdi), %eax 2974; X64-NOBMI-NEXT: negb %cl 2975; X64-NOBMI-NEXT: shll %cl, %eax 2976; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2977; X64-NOBMI-NEXT: shrl %cl, %eax 2978; X64-NOBMI-NEXT: retq 2979; 2980; X64-BMI1NOTBM-LABEL: bzhi32_d3_load_indexzext: 2981; X64-BMI1NOTBM: # %bb.0: 2982; X64-BMI1NOTBM-NEXT: shll $8, %esi 2983; X64-BMI1NOTBM-NEXT: bextrl %esi, (%rdi), %eax 2984; X64-BMI1NOTBM-NEXT: retq 2985; 2986; X64-BMI1BMI2-LABEL: bzhi32_d3_load_indexzext: 2987; X64-BMI1BMI2: # %bb.0: 2988; X64-BMI1BMI2-NEXT: bzhil %esi, (%rdi), %eax 2989; X64-BMI1BMI2-NEXT: retq 2990 %val = load i32, i32* %w 2991 %numhighbits = sub i8 32, %numlowbits 2992 %sh_prom = zext i8 %numhighbits to i32 2993 %highbitscleared = shl i32 %val, %sh_prom 2994 %masked = lshr i32 %highbitscleared, %sh_prom 2995 ret i32 %masked 2996} 2997 2998; 64-bit. 2999 3000define i64 @bzhi64_d0(i64 %val, i64 %numlowbits) nounwind { 3001; X86-NOBMI-LABEL: bzhi64_d0: 3002; X86-NOBMI: # %bb.0: 3003; X86-NOBMI-NEXT: pushl %ebx 3004; X86-NOBMI-NEXT: pushl %edi 3005; X86-NOBMI-NEXT: pushl %esi 3006; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 3007; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 3008; X86-NOBMI-NEXT: movb $64, %cl 3009; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 3010; X86-NOBMI-NEXT: movl %edx, %esi 3011; X86-NOBMI-NEXT: shll %cl, %esi 3012; X86-NOBMI-NEXT: shldl %cl, %edx, %eax 3013; X86-NOBMI-NEXT: testb $32, %cl 3014; X86-NOBMI-NEXT: movl %esi, %edi 3015; X86-NOBMI-NEXT: jne .LBB34_2 3016; X86-NOBMI-NEXT: # %bb.1: 3017; X86-NOBMI-NEXT: movl %eax, %edi 3018; X86-NOBMI-NEXT: .LBB34_2: 3019; X86-NOBMI-NEXT: movl %edi, %eax 3020; X86-NOBMI-NEXT: shrl %cl, %eax 3021; X86-NOBMI-NEXT: xorl %ebx, %ebx 3022; X86-NOBMI-NEXT: testb $32, %cl 3023; X86-NOBMI-NEXT: movl $0, %edx 3024; X86-NOBMI-NEXT: jne .LBB34_4 3025; X86-NOBMI-NEXT: # %bb.3: 3026; X86-NOBMI-NEXT: movl %esi, %ebx 3027; X86-NOBMI-NEXT: movl %eax, %edx 3028; X86-NOBMI-NEXT: .LBB34_4: 3029; X86-NOBMI-NEXT: shrdl %cl, %edi, %ebx 3030; X86-NOBMI-NEXT: testb $32, %cl 3031; X86-NOBMI-NEXT: jne .LBB34_6 3032; X86-NOBMI-NEXT: # %bb.5: 3033; X86-NOBMI-NEXT: movl %ebx, %eax 3034; X86-NOBMI-NEXT: .LBB34_6: 3035; X86-NOBMI-NEXT: popl %esi 3036; X86-NOBMI-NEXT: popl %edi 3037; X86-NOBMI-NEXT: popl %ebx 3038; X86-NOBMI-NEXT: retl 3039; 3040; X86-BMI1NOTBM-LABEL: bzhi64_d0: 3041; X86-BMI1NOTBM: # %bb.0: 3042; X86-BMI1NOTBM-NEXT: pushl %ebx 3043; X86-BMI1NOTBM-NEXT: pushl %edi 3044; X86-BMI1NOTBM-NEXT: pushl %esi 3045; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %edx 3046; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 3047; X86-BMI1NOTBM-NEXT: movb $64, %cl 3048; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 3049; X86-BMI1NOTBM-NEXT: movl %edx, %esi 3050; X86-BMI1NOTBM-NEXT: shll %cl, %esi 3051; X86-BMI1NOTBM-NEXT: shldl %cl, %edx, %eax 3052; X86-BMI1NOTBM-NEXT: testb $32, %cl 3053; X86-BMI1NOTBM-NEXT: movl %esi, %edi 3054; X86-BMI1NOTBM-NEXT: jne .LBB34_2 3055; X86-BMI1NOTBM-NEXT: # %bb.1: 3056; X86-BMI1NOTBM-NEXT: movl %eax, %edi 3057; X86-BMI1NOTBM-NEXT: .LBB34_2: 3058; X86-BMI1NOTBM-NEXT: movl %edi, %eax 3059; X86-BMI1NOTBM-NEXT: shrl %cl, %eax 3060; X86-BMI1NOTBM-NEXT: xorl %ebx, %ebx 3061; X86-BMI1NOTBM-NEXT: testb $32, %cl 3062; X86-BMI1NOTBM-NEXT: movl $0, %edx 3063; X86-BMI1NOTBM-NEXT: jne .LBB34_4 3064; X86-BMI1NOTBM-NEXT: # %bb.3: 3065; X86-BMI1NOTBM-NEXT: movl %esi, %ebx 3066; X86-BMI1NOTBM-NEXT: movl %eax, %edx 3067; X86-BMI1NOTBM-NEXT: .LBB34_4: 3068; X86-BMI1NOTBM-NEXT: shrdl %cl, %edi, %ebx 3069; X86-BMI1NOTBM-NEXT: testb $32, %cl 3070; X86-BMI1NOTBM-NEXT: jne .LBB34_6 3071; X86-BMI1NOTBM-NEXT: # %bb.5: 3072; X86-BMI1NOTBM-NEXT: movl %ebx, %eax 3073; X86-BMI1NOTBM-NEXT: .LBB34_6: 3074; X86-BMI1NOTBM-NEXT: popl %esi 3075; X86-BMI1NOTBM-NEXT: popl %edi 3076; X86-BMI1NOTBM-NEXT: popl %ebx 3077; X86-BMI1NOTBM-NEXT: retl 3078; 3079; X86-BMI1BMI2-LABEL: bzhi64_d0: 3080; X86-BMI1BMI2: # %bb.0: 3081; X86-BMI1BMI2-NEXT: pushl %edi 3082; X86-BMI1BMI2-NEXT: pushl %esi 3083; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 3084; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 3085; X86-BMI1BMI2-NEXT: movb $64, %cl 3086; X86-BMI1BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 3087; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %esi 3088; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %edi 3089; X86-BMI1BMI2-NEXT: xorl %edx, %edx 3090; X86-BMI1BMI2-NEXT: testb $32, %cl 3091; X86-BMI1BMI2-NEXT: je .LBB34_2 3092; X86-BMI1BMI2-NEXT: # %bb.1: 3093; X86-BMI1BMI2-NEXT: movl %edi, %esi 3094; X86-BMI1BMI2-NEXT: movl $0, %edi 3095; X86-BMI1BMI2-NEXT: .LBB34_2: 3096; X86-BMI1BMI2-NEXT: shrxl %ecx, %esi, %eax 3097; X86-BMI1BMI2-NEXT: jne .LBB34_4 3098; X86-BMI1BMI2-NEXT: # %bb.3: 3099; X86-BMI1BMI2-NEXT: movl %eax, %edx 3100; X86-BMI1BMI2-NEXT: .LBB34_4: 3101; X86-BMI1BMI2-NEXT: shrdl %cl, %esi, %edi 3102; X86-BMI1BMI2-NEXT: testb $32, %cl 3103; X86-BMI1BMI2-NEXT: jne .LBB34_6 3104; X86-BMI1BMI2-NEXT: # %bb.5: 3105; X86-BMI1BMI2-NEXT: movl %edi, %eax 3106; X86-BMI1BMI2-NEXT: .LBB34_6: 3107; X86-BMI1BMI2-NEXT: popl %esi 3108; X86-BMI1BMI2-NEXT: popl %edi 3109; X86-BMI1BMI2-NEXT: retl 3110; 3111; X64-NOBMI-LABEL: bzhi64_d0: 3112; X64-NOBMI: # %bb.0: 3113; X64-NOBMI-NEXT: movq %rsi, %rcx 3114; X64-NOBMI-NEXT: movq %rdi, %rax 3115; X64-NOBMI-NEXT: negb %cl 3116; X64-NOBMI-NEXT: shlq %cl, %rax 3117; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 3118; X64-NOBMI-NEXT: shrq %cl, %rax 3119; X64-NOBMI-NEXT: retq 3120; 3121; X64-BMI1NOTBM-LABEL: bzhi64_d0: 3122; X64-BMI1NOTBM: # %bb.0: 3123; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 3124; X64-BMI1NOTBM-NEXT: bextrq %rsi, %rdi, %rax 3125; X64-BMI1NOTBM-NEXT: retq 3126; 3127; X64-BMI1BMI2-LABEL: bzhi64_d0: 3128; X64-BMI1BMI2: # %bb.0: 3129; X64-BMI1BMI2-NEXT: bzhiq %rsi, %rdi, %rax 3130; X64-BMI1BMI2-NEXT: retq 3131 %numhighbits = sub i64 64, %numlowbits 3132 %highbitscleared = shl i64 %val, %numhighbits 3133 %masked = lshr i64 %highbitscleared, %numhighbits 3134 ret i64 %masked 3135} 3136 3137define i64 @bzhi64_d1_indexzext(i64 %val, i8 %numlowbits) nounwind { 3138; X86-NOBMI-LABEL: bzhi64_d1_indexzext: 3139; X86-NOBMI: # %bb.0: 3140; X86-NOBMI-NEXT: pushl %ebx 3141; X86-NOBMI-NEXT: pushl %edi 3142; X86-NOBMI-NEXT: pushl %esi 3143; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 3144; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 3145; X86-NOBMI-NEXT: movb $64, %cl 3146; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 3147; X86-NOBMI-NEXT: movl %edx, %esi 3148; X86-NOBMI-NEXT: shll %cl, %esi 3149; X86-NOBMI-NEXT: shldl %cl, %edx, %eax 3150; X86-NOBMI-NEXT: testb $32, %cl 3151; X86-NOBMI-NEXT: movl %esi, %edi 3152; X86-NOBMI-NEXT: jne .LBB35_2 3153; X86-NOBMI-NEXT: # %bb.1: 3154; X86-NOBMI-NEXT: movl %eax, %edi 3155; X86-NOBMI-NEXT: .LBB35_2: 3156; X86-NOBMI-NEXT: movl %edi, %eax 3157; X86-NOBMI-NEXT: shrl %cl, %eax 3158; X86-NOBMI-NEXT: xorl %ebx, %ebx 3159; X86-NOBMI-NEXT: testb $32, %cl 3160; X86-NOBMI-NEXT: movl $0, %edx 3161; X86-NOBMI-NEXT: jne .LBB35_4 3162; X86-NOBMI-NEXT: # %bb.3: 3163; X86-NOBMI-NEXT: movl %esi, %ebx 3164; X86-NOBMI-NEXT: movl %eax, %edx 3165; X86-NOBMI-NEXT: .LBB35_4: 3166; X86-NOBMI-NEXT: shrdl %cl, %edi, %ebx 3167; X86-NOBMI-NEXT: testb $32, %cl 3168; X86-NOBMI-NEXT: jne .LBB35_6 3169; X86-NOBMI-NEXT: # %bb.5: 3170; X86-NOBMI-NEXT: movl %ebx, %eax 3171; X86-NOBMI-NEXT: .LBB35_6: 3172; X86-NOBMI-NEXT: popl %esi 3173; X86-NOBMI-NEXT: popl %edi 3174; X86-NOBMI-NEXT: popl %ebx 3175; X86-NOBMI-NEXT: retl 3176; 3177; X86-BMI1NOTBM-LABEL: bzhi64_d1_indexzext: 3178; X86-BMI1NOTBM: # %bb.0: 3179; X86-BMI1NOTBM-NEXT: pushl %ebx 3180; X86-BMI1NOTBM-NEXT: pushl %edi 3181; X86-BMI1NOTBM-NEXT: pushl %esi 3182; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %edx 3183; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 3184; X86-BMI1NOTBM-NEXT: movb $64, %cl 3185; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 3186; X86-BMI1NOTBM-NEXT: movl %edx, %esi 3187; X86-BMI1NOTBM-NEXT: shll %cl, %esi 3188; X86-BMI1NOTBM-NEXT: shldl %cl, %edx, %eax 3189; X86-BMI1NOTBM-NEXT: testb $32, %cl 3190; X86-BMI1NOTBM-NEXT: movl %esi, %edi 3191; X86-BMI1NOTBM-NEXT: jne .LBB35_2 3192; X86-BMI1NOTBM-NEXT: # %bb.1: 3193; X86-BMI1NOTBM-NEXT: movl %eax, %edi 3194; X86-BMI1NOTBM-NEXT: .LBB35_2: 3195; X86-BMI1NOTBM-NEXT: movl %edi, %eax 3196; X86-BMI1NOTBM-NEXT: shrl %cl, %eax 3197; X86-BMI1NOTBM-NEXT: xorl %ebx, %ebx 3198; X86-BMI1NOTBM-NEXT: testb $32, %cl 3199; X86-BMI1NOTBM-NEXT: movl $0, %edx 3200; X86-BMI1NOTBM-NEXT: jne .LBB35_4 3201; X86-BMI1NOTBM-NEXT: # %bb.3: 3202; X86-BMI1NOTBM-NEXT: movl %esi, %ebx 3203; X86-BMI1NOTBM-NEXT: movl %eax, %edx 3204; X86-BMI1NOTBM-NEXT: .LBB35_4: 3205; X86-BMI1NOTBM-NEXT: shrdl %cl, %edi, %ebx 3206; X86-BMI1NOTBM-NEXT: testb $32, %cl 3207; X86-BMI1NOTBM-NEXT: jne .LBB35_6 3208; X86-BMI1NOTBM-NEXT: # %bb.5: 3209; X86-BMI1NOTBM-NEXT: movl %ebx, %eax 3210; X86-BMI1NOTBM-NEXT: .LBB35_6: 3211; X86-BMI1NOTBM-NEXT: popl %esi 3212; X86-BMI1NOTBM-NEXT: popl %edi 3213; X86-BMI1NOTBM-NEXT: popl %ebx 3214; X86-BMI1NOTBM-NEXT: retl 3215; 3216; X86-BMI1BMI2-LABEL: bzhi64_d1_indexzext: 3217; X86-BMI1BMI2: # %bb.0: 3218; X86-BMI1BMI2-NEXT: pushl %edi 3219; X86-BMI1BMI2-NEXT: pushl %esi 3220; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 3221; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 3222; X86-BMI1BMI2-NEXT: movb $64, %cl 3223; X86-BMI1BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 3224; X86-BMI1BMI2-NEXT: shldl %cl, %eax, %esi 3225; X86-BMI1BMI2-NEXT: shlxl %ecx, %eax, %edi 3226; X86-BMI1BMI2-NEXT: xorl %edx, %edx 3227; X86-BMI1BMI2-NEXT: testb $32, %cl 3228; X86-BMI1BMI2-NEXT: je .LBB35_2 3229; X86-BMI1BMI2-NEXT: # %bb.1: 3230; X86-BMI1BMI2-NEXT: movl %edi, %esi 3231; X86-BMI1BMI2-NEXT: movl $0, %edi 3232; X86-BMI1BMI2-NEXT: .LBB35_2: 3233; X86-BMI1BMI2-NEXT: shrxl %ecx, %esi, %eax 3234; X86-BMI1BMI2-NEXT: jne .LBB35_4 3235; X86-BMI1BMI2-NEXT: # %bb.3: 3236; X86-BMI1BMI2-NEXT: movl %eax, %edx 3237; X86-BMI1BMI2-NEXT: .LBB35_4: 3238; X86-BMI1BMI2-NEXT: shrdl %cl, %esi, %edi 3239; X86-BMI1BMI2-NEXT: testb $32, %cl 3240; X86-BMI1BMI2-NEXT: jne .LBB35_6 3241; X86-BMI1BMI2-NEXT: # %bb.5: 3242; X86-BMI1BMI2-NEXT: movl %edi, %eax 3243; X86-BMI1BMI2-NEXT: .LBB35_6: 3244; X86-BMI1BMI2-NEXT: popl %esi 3245; X86-BMI1BMI2-NEXT: popl %edi 3246; X86-BMI1BMI2-NEXT: retl 3247; 3248; X64-NOBMI-LABEL: bzhi64_d1_indexzext: 3249; X64-NOBMI: # %bb.0: 3250; X64-NOBMI-NEXT: movl %esi, %ecx 3251; X64-NOBMI-NEXT: movq %rdi, %rax 3252; X64-NOBMI-NEXT: negb %cl 3253; X64-NOBMI-NEXT: shlq %cl, %rax 3254; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 3255; X64-NOBMI-NEXT: shrq %cl, %rax 3256; X64-NOBMI-NEXT: retq 3257; 3258; X64-BMI1NOTBM-LABEL: bzhi64_d1_indexzext: 3259; X64-BMI1NOTBM: # %bb.0: 3260; X64-BMI1NOTBM-NEXT: # kill: def $esi killed $esi def $rsi 3261; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 3262; X64-BMI1NOTBM-NEXT: bextrq %rsi, %rdi, %rax 3263; X64-BMI1NOTBM-NEXT: retq 3264; 3265; X64-BMI1BMI2-LABEL: bzhi64_d1_indexzext: 3266; X64-BMI1BMI2: # %bb.0: 3267; X64-BMI1BMI2-NEXT: # kill: def $esi killed $esi def $rsi 3268; X64-BMI1BMI2-NEXT: bzhiq %rsi, %rdi, %rax 3269; X64-BMI1BMI2-NEXT: retq 3270 %numhighbits = sub i8 64, %numlowbits 3271 %sh_prom = zext i8 %numhighbits to i64 3272 %highbitscleared = shl i64 %val, %sh_prom 3273 %masked = lshr i64 %highbitscleared, %sh_prom 3274 ret i64 %masked 3275} 3276 3277define i64 @bzhi64_d2_load(i64* %w, i64 %numlowbits) nounwind { 3278; X86-NOBMI-LABEL: bzhi64_d2_load: 3279; X86-NOBMI: # %bb.0: 3280; X86-NOBMI-NEXT: pushl %ebx 3281; X86-NOBMI-NEXT: pushl %edi 3282; X86-NOBMI-NEXT: pushl %esi 3283; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 3284; X86-NOBMI-NEXT: movl (%eax), %edx 3285; X86-NOBMI-NEXT: movl 4(%eax), %eax 3286; X86-NOBMI-NEXT: movb $64, %cl 3287; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 3288; X86-NOBMI-NEXT: movl %edx, %esi 3289; X86-NOBMI-NEXT: shll %cl, %esi 3290; X86-NOBMI-NEXT: shldl %cl, %edx, %eax 3291; X86-NOBMI-NEXT: testb $32, %cl 3292; X86-NOBMI-NEXT: movl %esi, %edi 3293; X86-NOBMI-NEXT: jne .LBB36_2 3294; X86-NOBMI-NEXT: # %bb.1: 3295; X86-NOBMI-NEXT: movl %eax, %edi 3296; X86-NOBMI-NEXT: .LBB36_2: 3297; X86-NOBMI-NEXT: movl %edi, %eax 3298; X86-NOBMI-NEXT: shrl %cl, %eax 3299; X86-NOBMI-NEXT: xorl %ebx, %ebx 3300; X86-NOBMI-NEXT: testb $32, %cl 3301; X86-NOBMI-NEXT: movl $0, %edx 3302; X86-NOBMI-NEXT: jne .LBB36_4 3303; X86-NOBMI-NEXT: # %bb.3: 3304; X86-NOBMI-NEXT: movl %esi, %ebx 3305; X86-NOBMI-NEXT: movl %eax, %edx 3306; X86-NOBMI-NEXT: .LBB36_4: 3307; X86-NOBMI-NEXT: shrdl %cl, %edi, %ebx 3308; X86-NOBMI-NEXT: testb $32, %cl 3309; X86-NOBMI-NEXT: jne .LBB36_6 3310; X86-NOBMI-NEXT: # %bb.5: 3311; X86-NOBMI-NEXT: movl %ebx, %eax 3312; X86-NOBMI-NEXT: .LBB36_6: 3313; X86-NOBMI-NEXT: popl %esi 3314; X86-NOBMI-NEXT: popl %edi 3315; X86-NOBMI-NEXT: popl %ebx 3316; X86-NOBMI-NEXT: retl 3317; 3318; X86-BMI1NOTBM-LABEL: bzhi64_d2_load: 3319; X86-BMI1NOTBM: # %bb.0: 3320; X86-BMI1NOTBM-NEXT: pushl %ebx 3321; X86-BMI1NOTBM-NEXT: pushl %edi 3322; X86-BMI1NOTBM-NEXT: pushl %esi 3323; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 3324; X86-BMI1NOTBM-NEXT: movl (%eax), %edx 3325; X86-BMI1NOTBM-NEXT: movl 4(%eax), %eax 3326; X86-BMI1NOTBM-NEXT: movb $64, %cl 3327; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 3328; X86-BMI1NOTBM-NEXT: movl %edx, %esi 3329; X86-BMI1NOTBM-NEXT: shll %cl, %esi 3330; X86-BMI1NOTBM-NEXT: shldl %cl, %edx, %eax 3331; X86-BMI1NOTBM-NEXT: testb $32, %cl 3332; X86-BMI1NOTBM-NEXT: movl %esi, %edi 3333; X86-BMI1NOTBM-NEXT: jne .LBB36_2 3334; X86-BMI1NOTBM-NEXT: # %bb.1: 3335; X86-BMI1NOTBM-NEXT: movl %eax, %edi 3336; X86-BMI1NOTBM-NEXT: .LBB36_2: 3337; X86-BMI1NOTBM-NEXT: movl %edi, %eax 3338; X86-BMI1NOTBM-NEXT: shrl %cl, %eax 3339; X86-BMI1NOTBM-NEXT: xorl %ebx, %ebx 3340; X86-BMI1NOTBM-NEXT: testb $32, %cl 3341; X86-BMI1NOTBM-NEXT: movl $0, %edx 3342; X86-BMI1NOTBM-NEXT: jne .LBB36_4 3343; X86-BMI1NOTBM-NEXT: # %bb.3: 3344; X86-BMI1NOTBM-NEXT: movl %esi, %ebx 3345; X86-BMI1NOTBM-NEXT: movl %eax, %edx 3346; X86-BMI1NOTBM-NEXT: .LBB36_4: 3347; X86-BMI1NOTBM-NEXT: shrdl %cl, %edi, %ebx 3348; X86-BMI1NOTBM-NEXT: testb $32, %cl 3349; X86-BMI1NOTBM-NEXT: jne .LBB36_6 3350; X86-BMI1NOTBM-NEXT: # %bb.5: 3351; X86-BMI1NOTBM-NEXT: movl %ebx, %eax 3352; X86-BMI1NOTBM-NEXT: .LBB36_6: 3353; X86-BMI1NOTBM-NEXT: popl %esi 3354; X86-BMI1NOTBM-NEXT: popl %edi 3355; X86-BMI1NOTBM-NEXT: popl %ebx 3356; X86-BMI1NOTBM-NEXT: retl 3357; 3358; X86-BMI1BMI2-LABEL: bzhi64_d2_load: 3359; X86-BMI1BMI2: # %bb.0: 3360; X86-BMI1BMI2-NEXT: pushl %edi 3361; X86-BMI1BMI2-NEXT: pushl %esi 3362; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 3363; X86-BMI1BMI2-NEXT: movl (%eax), %edx 3364; X86-BMI1BMI2-NEXT: movl 4(%eax), %esi 3365; X86-BMI1BMI2-NEXT: movb $64, %cl 3366; X86-BMI1BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 3367; X86-BMI1BMI2-NEXT: shldl %cl, %edx, %esi 3368; X86-BMI1BMI2-NEXT: shlxl %ecx, %edx, %edi 3369; X86-BMI1BMI2-NEXT: xorl %edx, %edx 3370; X86-BMI1BMI2-NEXT: testb $32, %cl 3371; X86-BMI1BMI2-NEXT: je .LBB36_2 3372; X86-BMI1BMI2-NEXT: # %bb.1: 3373; X86-BMI1BMI2-NEXT: movl %edi, %esi 3374; X86-BMI1BMI2-NEXT: movl $0, %edi 3375; X86-BMI1BMI2-NEXT: .LBB36_2: 3376; X86-BMI1BMI2-NEXT: shrxl %ecx, %esi, %eax 3377; X86-BMI1BMI2-NEXT: jne .LBB36_4 3378; X86-BMI1BMI2-NEXT: # %bb.3: 3379; X86-BMI1BMI2-NEXT: movl %eax, %edx 3380; X86-BMI1BMI2-NEXT: .LBB36_4: 3381; X86-BMI1BMI2-NEXT: shrdl %cl, %esi, %edi 3382; X86-BMI1BMI2-NEXT: testb $32, %cl 3383; X86-BMI1BMI2-NEXT: jne .LBB36_6 3384; X86-BMI1BMI2-NEXT: # %bb.5: 3385; X86-BMI1BMI2-NEXT: movl %edi, %eax 3386; X86-BMI1BMI2-NEXT: .LBB36_6: 3387; X86-BMI1BMI2-NEXT: popl %esi 3388; X86-BMI1BMI2-NEXT: popl %edi 3389; X86-BMI1BMI2-NEXT: retl 3390; 3391; X64-NOBMI-LABEL: bzhi64_d2_load: 3392; X64-NOBMI: # %bb.0: 3393; X64-NOBMI-NEXT: movq %rsi, %rcx 3394; X64-NOBMI-NEXT: movq (%rdi), %rax 3395; X64-NOBMI-NEXT: negb %cl 3396; X64-NOBMI-NEXT: shlq %cl, %rax 3397; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 3398; X64-NOBMI-NEXT: shrq %cl, %rax 3399; X64-NOBMI-NEXT: retq 3400; 3401; X64-BMI1NOTBM-LABEL: bzhi64_d2_load: 3402; X64-BMI1NOTBM: # %bb.0: 3403; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 3404; X64-BMI1NOTBM-NEXT: bextrq %rsi, (%rdi), %rax 3405; X64-BMI1NOTBM-NEXT: retq 3406; 3407; X64-BMI1BMI2-LABEL: bzhi64_d2_load: 3408; X64-BMI1BMI2: # %bb.0: 3409; X64-BMI1BMI2-NEXT: bzhiq %rsi, (%rdi), %rax 3410; X64-BMI1BMI2-NEXT: retq 3411 %val = load i64, i64* %w 3412 %numhighbits = sub i64 64, %numlowbits 3413 %highbitscleared = shl i64 %val, %numhighbits 3414 %masked = lshr i64 %highbitscleared, %numhighbits 3415 ret i64 %masked 3416} 3417 3418define i64 @bzhi64_d3_load_indexzext(i64* %w, i8 %numlowbits) nounwind { 3419; X86-NOBMI-LABEL: bzhi64_d3_load_indexzext: 3420; X86-NOBMI: # %bb.0: 3421; X86-NOBMI-NEXT: pushl %ebx 3422; X86-NOBMI-NEXT: pushl %edi 3423; X86-NOBMI-NEXT: pushl %esi 3424; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 3425; X86-NOBMI-NEXT: movl (%eax), %edx 3426; X86-NOBMI-NEXT: movl 4(%eax), %eax 3427; X86-NOBMI-NEXT: movb $64, %cl 3428; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 3429; X86-NOBMI-NEXT: movl %edx, %esi 3430; X86-NOBMI-NEXT: shll %cl, %esi 3431; X86-NOBMI-NEXT: shldl %cl, %edx, %eax 3432; X86-NOBMI-NEXT: testb $32, %cl 3433; X86-NOBMI-NEXT: movl %esi, %edi 3434; X86-NOBMI-NEXT: jne .LBB37_2 3435; X86-NOBMI-NEXT: # %bb.1: 3436; X86-NOBMI-NEXT: movl %eax, %edi 3437; X86-NOBMI-NEXT: .LBB37_2: 3438; X86-NOBMI-NEXT: movl %edi, %eax 3439; X86-NOBMI-NEXT: shrl %cl, %eax 3440; X86-NOBMI-NEXT: xorl %ebx, %ebx 3441; X86-NOBMI-NEXT: testb $32, %cl 3442; X86-NOBMI-NEXT: movl $0, %edx 3443; X86-NOBMI-NEXT: jne .LBB37_4 3444; X86-NOBMI-NEXT: # %bb.3: 3445; X86-NOBMI-NEXT: movl %esi, %ebx 3446; X86-NOBMI-NEXT: movl %eax, %edx 3447; X86-NOBMI-NEXT: .LBB37_4: 3448; X86-NOBMI-NEXT: shrdl %cl, %edi, %ebx 3449; X86-NOBMI-NEXT: testb $32, %cl 3450; X86-NOBMI-NEXT: jne .LBB37_6 3451; X86-NOBMI-NEXT: # %bb.5: 3452; X86-NOBMI-NEXT: movl %ebx, %eax 3453; X86-NOBMI-NEXT: .LBB37_6: 3454; X86-NOBMI-NEXT: popl %esi 3455; X86-NOBMI-NEXT: popl %edi 3456; X86-NOBMI-NEXT: popl %ebx 3457; X86-NOBMI-NEXT: retl 3458; 3459; X86-BMI1NOTBM-LABEL: bzhi64_d3_load_indexzext: 3460; X86-BMI1NOTBM: # %bb.0: 3461; X86-BMI1NOTBM-NEXT: pushl %ebx 3462; X86-BMI1NOTBM-NEXT: pushl %edi 3463; X86-BMI1NOTBM-NEXT: pushl %esi 3464; X86-BMI1NOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 3465; X86-BMI1NOTBM-NEXT: movl (%eax), %edx 3466; X86-BMI1NOTBM-NEXT: movl 4(%eax), %eax 3467; X86-BMI1NOTBM-NEXT: movb $64, %cl 3468; X86-BMI1NOTBM-NEXT: subb {{[0-9]+}}(%esp), %cl 3469; X86-BMI1NOTBM-NEXT: movl %edx, %esi 3470; X86-BMI1NOTBM-NEXT: shll %cl, %esi 3471; X86-BMI1NOTBM-NEXT: shldl %cl, %edx, %eax 3472; X86-BMI1NOTBM-NEXT: testb $32, %cl 3473; X86-BMI1NOTBM-NEXT: movl %esi, %edi 3474; X86-BMI1NOTBM-NEXT: jne .LBB37_2 3475; X86-BMI1NOTBM-NEXT: # %bb.1: 3476; X86-BMI1NOTBM-NEXT: movl %eax, %edi 3477; X86-BMI1NOTBM-NEXT: .LBB37_2: 3478; X86-BMI1NOTBM-NEXT: movl %edi, %eax 3479; X86-BMI1NOTBM-NEXT: shrl %cl, %eax 3480; X86-BMI1NOTBM-NEXT: xorl %ebx, %ebx 3481; X86-BMI1NOTBM-NEXT: testb $32, %cl 3482; X86-BMI1NOTBM-NEXT: movl $0, %edx 3483; X86-BMI1NOTBM-NEXT: jne .LBB37_4 3484; X86-BMI1NOTBM-NEXT: # %bb.3: 3485; X86-BMI1NOTBM-NEXT: movl %esi, %ebx 3486; X86-BMI1NOTBM-NEXT: movl %eax, %edx 3487; X86-BMI1NOTBM-NEXT: .LBB37_4: 3488; X86-BMI1NOTBM-NEXT: shrdl %cl, %edi, %ebx 3489; X86-BMI1NOTBM-NEXT: testb $32, %cl 3490; X86-BMI1NOTBM-NEXT: jne .LBB37_6 3491; X86-BMI1NOTBM-NEXT: # %bb.5: 3492; X86-BMI1NOTBM-NEXT: movl %ebx, %eax 3493; X86-BMI1NOTBM-NEXT: .LBB37_6: 3494; X86-BMI1NOTBM-NEXT: popl %esi 3495; X86-BMI1NOTBM-NEXT: popl %edi 3496; X86-BMI1NOTBM-NEXT: popl %ebx 3497; X86-BMI1NOTBM-NEXT: retl 3498; 3499; X86-BMI1BMI2-LABEL: bzhi64_d3_load_indexzext: 3500; X86-BMI1BMI2: # %bb.0: 3501; X86-BMI1BMI2-NEXT: pushl %edi 3502; X86-BMI1BMI2-NEXT: pushl %esi 3503; X86-BMI1BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 3504; X86-BMI1BMI2-NEXT: movl (%eax), %edx 3505; X86-BMI1BMI2-NEXT: movl 4(%eax), %esi 3506; X86-BMI1BMI2-NEXT: movb $64, %cl 3507; X86-BMI1BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 3508; X86-BMI1BMI2-NEXT: shldl %cl, %edx, %esi 3509; X86-BMI1BMI2-NEXT: shlxl %ecx, %edx, %edi 3510; X86-BMI1BMI2-NEXT: xorl %edx, %edx 3511; X86-BMI1BMI2-NEXT: testb $32, %cl 3512; X86-BMI1BMI2-NEXT: je .LBB37_2 3513; X86-BMI1BMI2-NEXT: # %bb.1: 3514; X86-BMI1BMI2-NEXT: movl %edi, %esi 3515; X86-BMI1BMI2-NEXT: movl $0, %edi 3516; X86-BMI1BMI2-NEXT: .LBB37_2: 3517; X86-BMI1BMI2-NEXT: shrxl %ecx, %esi, %eax 3518; X86-BMI1BMI2-NEXT: jne .LBB37_4 3519; X86-BMI1BMI2-NEXT: # %bb.3: 3520; X86-BMI1BMI2-NEXT: movl %eax, %edx 3521; X86-BMI1BMI2-NEXT: .LBB37_4: 3522; X86-BMI1BMI2-NEXT: shrdl %cl, %esi, %edi 3523; X86-BMI1BMI2-NEXT: testb $32, %cl 3524; X86-BMI1BMI2-NEXT: jne .LBB37_6 3525; X86-BMI1BMI2-NEXT: # %bb.5: 3526; X86-BMI1BMI2-NEXT: movl %edi, %eax 3527; X86-BMI1BMI2-NEXT: .LBB37_6: 3528; X86-BMI1BMI2-NEXT: popl %esi 3529; X86-BMI1BMI2-NEXT: popl %edi 3530; X86-BMI1BMI2-NEXT: retl 3531; 3532; X64-NOBMI-LABEL: bzhi64_d3_load_indexzext: 3533; X64-NOBMI: # %bb.0: 3534; X64-NOBMI-NEXT: movl %esi, %ecx 3535; X64-NOBMI-NEXT: movq (%rdi), %rax 3536; X64-NOBMI-NEXT: negb %cl 3537; X64-NOBMI-NEXT: shlq %cl, %rax 3538; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 3539; X64-NOBMI-NEXT: shrq %cl, %rax 3540; X64-NOBMI-NEXT: retq 3541; 3542; X64-BMI1NOTBM-LABEL: bzhi64_d3_load_indexzext: 3543; X64-BMI1NOTBM: # %bb.0: 3544; X64-BMI1NOTBM-NEXT: # kill: def $esi killed $esi def $rsi 3545; X64-BMI1NOTBM-NEXT: shlq $8, %rsi 3546; X64-BMI1NOTBM-NEXT: bextrq %rsi, (%rdi), %rax 3547; X64-BMI1NOTBM-NEXT: retq 3548; 3549; X64-BMI1BMI2-LABEL: bzhi64_d3_load_indexzext: 3550; X64-BMI1BMI2: # %bb.0: 3551; X64-BMI1BMI2-NEXT: # kill: def $esi killed $esi def $rsi 3552; X64-BMI1BMI2-NEXT: bzhiq %rsi, (%rdi), %rax 3553; X64-BMI1BMI2-NEXT: retq 3554 %val = load i64, i64* %w 3555 %numhighbits = sub i8 64, %numlowbits 3556 %sh_prom = zext i8 %numhighbits to i64 3557 %highbitscleared = shl i64 %val, %sh_prom 3558 %masked = lshr i64 %highbitscleared, %sh_prom 3559 ret i64 %masked 3560} 3561 3562; ---------------------------------------------------------------------------- ; 3563; Constant mask 3564; ---------------------------------------------------------------------------- ; 3565 3566; 32-bit 3567 3568define i32 @bzhi32_constant_mask32(i32 %val) nounwind { 3569; X86-LABEL: bzhi32_constant_mask32: 3570; X86: # %bb.0: 3571; X86-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF 3572; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 3573; X86-NEXT: retl 3574; 3575; X64-LABEL: bzhi32_constant_mask32: 3576; X64: # %bb.0: 3577; X64-NEXT: movl %edi, %eax 3578; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF 3579; X64-NEXT: retq 3580 %masked = and i32 %val, 2147483647 3581 ret i32 %masked 3582} 3583 3584define i32 @bzhi32_constant_mask32_load(i32* %val) nounwind { 3585; X86-LABEL: bzhi32_constant_mask32_load: 3586; X86: # %bb.0: 3587; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 3588; X86-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF 3589; X86-NEXT: andl (%ecx), %eax 3590; X86-NEXT: retl 3591; 3592; X64-LABEL: bzhi32_constant_mask32_load: 3593; X64: # %bb.0: 3594; X64-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF 3595; X64-NEXT: andl (%rdi), %eax 3596; X64-NEXT: retq 3597 %val1 = load i32, i32* %val 3598 %masked = and i32 %val1, 2147483647 3599 ret i32 %masked 3600} 3601 3602define i32 @bzhi32_constant_mask16(i32 %val) nounwind { 3603; X86-LABEL: bzhi32_constant_mask16: 3604; X86: # %bb.0: 3605; X86-NEXT: movl $32767, %eax # imm = 0x7FFF 3606; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 3607; X86-NEXT: retl 3608; 3609; X64-LABEL: bzhi32_constant_mask16: 3610; X64: # %bb.0: 3611; X64-NEXT: movl %edi, %eax 3612; X64-NEXT: andl $32767, %eax # imm = 0x7FFF 3613; X64-NEXT: retq 3614 %masked = and i32 %val, 32767 3615 ret i32 %masked 3616} 3617 3618define i32 @bzhi32_constant_mask16_load(i32* %val) nounwind { 3619; X86-LABEL: bzhi32_constant_mask16_load: 3620; X86: # %bb.0: 3621; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 3622; X86-NEXT: movl $32767, %eax # imm = 0x7FFF 3623; X86-NEXT: andl (%ecx), %eax 3624; X86-NEXT: retl 3625; 3626; X64-LABEL: bzhi32_constant_mask16_load: 3627; X64: # %bb.0: 3628; X64-NEXT: movl $32767, %eax # imm = 0x7FFF 3629; X64-NEXT: andl (%rdi), %eax 3630; X64-NEXT: retq 3631 %val1 = load i32, i32* %val 3632 %masked = and i32 %val1, 32767 3633 ret i32 %masked 3634} 3635 3636define i32 @bzhi32_constant_mask8(i32 %val) nounwind { 3637; X86-LABEL: bzhi32_constant_mask8: 3638; X86: # %bb.0: 3639; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 3640; X86-NEXT: andl $127, %eax 3641; X86-NEXT: retl 3642; 3643; X64-LABEL: bzhi32_constant_mask8: 3644; X64: # %bb.0: 3645; X64-NEXT: movl %edi, %eax 3646; X64-NEXT: andl $127, %eax 3647; X64-NEXT: retq 3648 %masked = and i32 %val, 127 3649 ret i32 %masked 3650} 3651 3652define i32 @bzhi32_constant_mask8_load(i32* %val) nounwind { 3653; X86-LABEL: bzhi32_constant_mask8_load: 3654; X86: # %bb.0: 3655; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 3656; X86-NEXT: movl (%eax), %eax 3657; X86-NEXT: andl $127, %eax 3658; X86-NEXT: retl 3659; 3660; X64-LABEL: bzhi32_constant_mask8_load: 3661; X64: # %bb.0: 3662; X64-NEXT: movl (%rdi), %eax 3663; X64-NEXT: andl $127, %eax 3664; X64-NEXT: retq 3665 %val1 = load i32, i32* %val 3666 %masked = and i32 %val1, 127 3667 ret i32 %masked 3668} 3669 3670; 64-bit 3671 3672define i64 @bzhi64_constant_mask64(i64 %val) nounwind { 3673; X86-LABEL: bzhi64_constant_mask64: 3674; X86: # %bb.0: 3675; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 3676; X86-NEXT: movl $1073741823, %edx # imm = 0x3FFFFFFF 3677; X86-NEXT: andl {{[0-9]+}}(%esp), %edx 3678; X86-NEXT: retl 3679; 3680; X64-NOBMI-LABEL: bzhi64_constant_mask64: 3681; X64-NOBMI: # %bb.0: 3682; X64-NOBMI-NEXT: movabsq $4611686018427387903, %rax # imm = 0x3FFFFFFFFFFFFFFF 3683; X64-NOBMI-NEXT: andq %rdi, %rax 3684; X64-NOBMI-NEXT: retq 3685; 3686; X64-BMI1NOTBM-LABEL: bzhi64_constant_mask64: 3687; X64-BMI1NOTBM: # %bb.0: 3688; X64-BMI1NOTBM-NEXT: movl $15872, %eax # imm = 0x3E00 3689; X64-BMI1NOTBM-NEXT: bextrq %rax, %rdi, %rax 3690; X64-BMI1NOTBM-NEXT: retq 3691; 3692; X64-BMI1TBM-LABEL: bzhi64_constant_mask64: 3693; X64-BMI1TBM: # %bb.0: 3694; X64-BMI1TBM-NEXT: bextrq $15872, %rdi, %rax # imm = 0x3E00 3695; X64-BMI1TBM-NEXT: retq 3696; 3697; X64-BMI1NOTBMBMI2-LABEL: bzhi64_constant_mask64: 3698; X64-BMI1NOTBMBMI2: # %bb.0: 3699; X64-BMI1NOTBMBMI2-NEXT: movb $62, %al 3700; X64-BMI1NOTBMBMI2-NEXT: bzhiq %rax, %rdi, %rax 3701; X64-BMI1NOTBMBMI2-NEXT: retq 3702 %masked = and i64 %val, 4611686018427387903 3703 ret i64 %masked 3704} 3705 3706define i64 @bzhi64_constant_mask64_load(i64* %val) nounwind { 3707; X86-LABEL: bzhi64_constant_mask64_load: 3708; X86: # %bb.0: 3709; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 3710; X86-NEXT: movl (%ecx), %eax 3711; X86-NEXT: movl $1073741823, %edx # imm = 0x3FFFFFFF 3712; X86-NEXT: andl 4(%ecx), %edx 3713; X86-NEXT: retl 3714; 3715; X64-NOBMI-LABEL: bzhi64_constant_mask64_load: 3716; X64-NOBMI: # %bb.0: 3717; X64-NOBMI-NEXT: movabsq $4611686018427387903, %rax # imm = 0x3FFFFFFFFFFFFFFF 3718; X64-NOBMI-NEXT: andq (%rdi), %rax 3719; X64-NOBMI-NEXT: retq 3720; 3721; X64-BMI1NOTBM-LABEL: bzhi64_constant_mask64_load: 3722; X64-BMI1NOTBM: # %bb.0: 3723; X64-BMI1NOTBM-NEXT: movl $15872, %eax # imm = 0x3E00 3724; X64-BMI1NOTBM-NEXT: bextrq %rax, (%rdi), %rax 3725; X64-BMI1NOTBM-NEXT: retq 3726; 3727; X64-BMI1TBM-LABEL: bzhi64_constant_mask64_load: 3728; X64-BMI1TBM: # %bb.0: 3729; X64-BMI1TBM-NEXT: bextrq $15872, (%rdi), %rax # imm = 0x3E00 3730; X64-BMI1TBM-NEXT: retq 3731; 3732; X64-BMI1NOTBMBMI2-LABEL: bzhi64_constant_mask64_load: 3733; X64-BMI1NOTBMBMI2: # %bb.0: 3734; X64-BMI1NOTBMBMI2-NEXT: movb $62, %al 3735; X64-BMI1NOTBMBMI2-NEXT: bzhiq %rax, (%rdi), %rax 3736; X64-BMI1NOTBMBMI2-NEXT: retq 3737 %val1 = load i64, i64* %val 3738 %masked = and i64 %val1, 4611686018427387903 3739 ret i64 %masked 3740} 3741 3742define i64 @bzhi64_constant_mask32(i64 %val) nounwind { 3743; X86-LABEL: bzhi64_constant_mask32: 3744; X86: # %bb.0: 3745; X86-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF 3746; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 3747; X86-NEXT: xorl %edx, %edx 3748; X86-NEXT: retl 3749; 3750; X64-LABEL: bzhi64_constant_mask32: 3751; X64: # %bb.0: 3752; X64-NEXT: movq %rdi, %rax 3753; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF 3754; X64-NEXT: retq 3755 %masked = and i64 %val, 2147483647 3756 ret i64 %masked 3757} 3758 3759define i64 @bzhi64_constant_mask32_load(i64* %val) nounwind { 3760; X86-LABEL: bzhi64_constant_mask32_load: 3761; X86: # %bb.0: 3762; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 3763; X86-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF 3764; X86-NEXT: andl (%ecx), %eax 3765; X86-NEXT: xorl %edx, %edx 3766; X86-NEXT: retl 3767; 3768; X64-LABEL: bzhi64_constant_mask32_load: 3769; X64: # %bb.0: 3770; X64-NEXT: movq (%rdi), %rax 3771; X64-NEXT: andl $2147483647, %eax # imm = 0x7FFFFFFF 3772; X64-NEXT: retq 3773 %val1 = load i64, i64* %val 3774 %masked = and i64 %val1, 2147483647 3775 ret i64 %masked 3776} 3777 3778define i64 @bzhi64_constant_mask16(i64 %val) nounwind { 3779; X86-LABEL: bzhi64_constant_mask16: 3780; X86: # %bb.0: 3781; X86-NEXT: movl $32767, %eax # imm = 0x7FFF 3782; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 3783; X86-NEXT: xorl %edx, %edx 3784; X86-NEXT: retl 3785; 3786; X64-LABEL: bzhi64_constant_mask16: 3787; X64: # %bb.0: 3788; X64-NEXT: movq %rdi, %rax 3789; X64-NEXT: andl $32767, %eax # imm = 0x7FFF 3790; X64-NEXT: retq 3791 %masked = and i64 %val, 32767 3792 ret i64 %masked 3793} 3794 3795define i64 @bzhi64_constant_mask16_load(i64* %val) nounwind { 3796; X86-LABEL: bzhi64_constant_mask16_load: 3797; X86: # %bb.0: 3798; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 3799; X86-NEXT: movl $32767, %eax # imm = 0x7FFF 3800; X86-NEXT: andl (%ecx), %eax 3801; X86-NEXT: xorl %edx, %edx 3802; X86-NEXT: retl 3803; 3804; X64-LABEL: bzhi64_constant_mask16_load: 3805; X64: # %bb.0: 3806; X64-NEXT: movq (%rdi), %rax 3807; X64-NEXT: andl $32767, %eax # imm = 0x7FFF 3808; X64-NEXT: retq 3809 %val1 = load i64, i64* %val 3810 %masked = and i64 %val1, 32767 3811 ret i64 %masked 3812} 3813 3814define i64 @bzhi64_constant_mask8(i64 %val) nounwind { 3815; X86-LABEL: bzhi64_constant_mask8: 3816; X86: # %bb.0: 3817; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 3818; X86-NEXT: andl $127, %eax 3819; X86-NEXT: xorl %edx, %edx 3820; X86-NEXT: retl 3821; 3822; X64-LABEL: bzhi64_constant_mask8: 3823; X64: # %bb.0: 3824; X64-NEXT: movq %rdi, %rax 3825; X64-NEXT: andl $127, %eax 3826; X64-NEXT: retq 3827 %masked = and i64 %val, 127 3828 ret i64 %masked 3829} 3830 3831define i64 @bzhi64_constant_mask8_load(i64* %val) nounwind { 3832; X86-LABEL: bzhi64_constant_mask8_load: 3833; X86: # %bb.0: 3834; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 3835; X86-NEXT: movl (%eax), %eax 3836; X86-NEXT: andl $127, %eax 3837; X86-NEXT: xorl %edx, %edx 3838; X86-NEXT: retl 3839; 3840; X64-LABEL: bzhi64_constant_mask8_load: 3841; X64: # %bb.0: 3842; X64-NEXT: movq (%rdi), %rax 3843; X64-NEXT: andl $127, %eax 3844; X64-NEXT: retq 3845 %val1 = load i64, i64* %val 3846 %masked = and i64 %val1, 127 3847 ret i64 %masked 3848} 3849