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,+fast-bextr < %s | FileCheck %s --check-prefixes=X86,X86-NOBMI 3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X86,X86-BMINOTBM,X86-BMI1 4; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X86,X86-BMITBM,X86-BMI1 5; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X86,X86-BMITBM,X86-BMI2 6; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X86,X86-BMINOTBM,X86-BMI2 7; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-NOBMI 8; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-BMINOTBM,X64-BMI1 9; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-BMITBM,X64-BMI1 10; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-BMITBM,X64-BMI2 11; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2,+fast-bextr < %s | FileCheck %s --check-prefixes=X64,X64-BMINOTBM,X64-BMI2 12 13; *Please* keep in sync with test/CodeGen/AArch64/extract-bits.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 >> start) & (1 << nbits) - 1 21; b) (x >> start) & ~(-1 << nbits) 22; c) (x >> start) & (-1 >> (32 - y)) 23; d) (x >> start) << (32 - y) >> (32 - y) 24; are equivalent. 25 26declare void @use32(i32) 27declare void @use64(i64) 28 29; ---------------------------------------------------------------------------- ; 30; Pattern a. 32-bit 31; ---------------------------------------------------------------------------- ; 32 33define i32 @bextr32_a0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 34; X86-NOBMI-LABEL: bextr32_a0: 35; X86-NOBMI: # %bb.0: 36; X86-NOBMI-NEXT: pushl %esi 37; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 38; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 39; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 40; X86-NOBMI-NEXT: shrl %cl, %esi 41; X86-NOBMI-NEXT: movl $1, %eax 42; X86-NOBMI-NEXT: movl %edx, %ecx 43; X86-NOBMI-NEXT: shll %cl, %eax 44; X86-NOBMI-NEXT: decl %eax 45; X86-NOBMI-NEXT: andl %esi, %eax 46; X86-NOBMI-NEXT: popl %esi 47; X86-NOBMI-NEXT: retl 48; 49; X86-BMI1-LABEL: bextr32_a0: 50; X86-BMI1: # %bb.0: 51; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 52; X86-BMI1-NEXT: shll $8, %eax 53; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 54; X86-BMI1-NEXT: orl %eax, %ecx 55; X86-BMI1-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %eax 56; X86-BMI1-NEXT: retl 57; 58; X86-BMI2-LABEL: bextr32_a0: 59; X86-BMI2: # %bb.0: 60; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 61; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 62; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %ecx 63; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 64; X86-BMI2-NEXT: retl 65; 66; X64-NOBMI-LABEL: bextr32_a0: 67; X64-NOBMI: # %bb.0: 68; X64-NOBMI-NEXT: movl %esi, %ecx 69; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 70; X64-NOBMI-NEXT: shrl %cl, %edi 71; X64-NOBMI-NEXT: movl $1, %eax 72; X64-NOBMI-NEXT: movl %edx, %ecx 73; X64-NOBMI-NEXT: shll %cl, %eax 74; X64-NOBMI-NEXT: decl %eax 75; X64-NOBMI-NEXT: andl %edi, %eax 76; X64-NOBMI-NEXT: retq 77; 78; X64-BMI1-LABEL: bextr32_a0: 79; X64-BMI1: # %bb.0: 80; X64-BMI1-NEXT: shll $8, %edx 81; X64-BMI1-NEXT: movzbl %sil, %eax 82; X64-BMI1-NEXT: orl %edx, %eax 83; X64-BMI1-NEXT: bextrl %eax, %edi, %eax 84; X64-BMI1-NEXT: retq 85; 86; X64-BMI2-LABEL: bextr32_a0: 87; X64-BMI2: # %bb.0: 88; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 89; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 90; X64-BMI2-NEXT: retq 91 %shifted = lshr i32 %val, %numskipbits 92 %onebit = shl i32 1, %numlowbits 93 %mask = add nsw i32 %onebit, -1 94 %masked = and i32 %mask, %shifted 95 ret i32 %masked 96} 97 98define i32 @bextr32_a0_arithmetic(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 99; X86-NOBMI-LABEL: bextr32_a0_arithmetic: 100; X86-NOBMI: # %bb.0: 101; X86-NOBMI-NEXT: pushl %esi 102; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 103; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 104; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 105; X86-NOBMI-NEXT: sarl %cl, %esi 106; X86-NOBMI-NEXT: movl $1, %eax 107; X86-NOBMI-NEXT: movl %edx, %ecx 108; X86-NOBMI-NEXT: shll %cl, %eax 109; X86-NOBMI-NEXT: decl %eax 110; X86-NOBMI-NEXT: andl %esi, %eax 111; X86-NOBMI-NEXT: popl %esi 112; X86-NOBMI-NEXT: retl 113; 114; X86-BMI1-LABEL: bextr32_a0_arithmetic: 115; X86-BMI1: # %bb.0: 116; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 117; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 118; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edx 119; X86-BMI1-NEXT: sarl %cl, %edx 120; X86-BMI1-NEXT: shll $8, %eax 121; X86-BMI1-NEXT: bextrl %eax, %edx, %eax 122; X86-BMI1-NEXT: retl 123; 124; X86-BMI2-LABEL: bextr32_a0_arithmetic: 125; X86-BMI2: # %bb.0: 126; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 127; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 128; X86-BMI2-NEXT: sarxl %ecx, {{[0-9]+}}(%esp), %ecx 129; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 130; X86-BMI2-NEXT: retl 131; 132; X64-NOBMI-LABEL: bextr32_a0_arithmetic: 133; X64-NOBMI: # %bb.0: 134; X64-NOBMI-NEXT: movl %esi, %ecx 135; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 136; X64-NOBMI-NEXT: sarl %cl, %edi 137; X64-NOBMI-NEXT: movl $1, %eax 138; X64-NOBMI-NEXT: movl %edx, %ecx 139; X64-NOBMI-NEXT: shll %cl, %eax 140; X64-NOBMI-NEXT: decl %eax 141; X64-NOBMI-NEXT: andl %edi, %eax 142; X64-NOBMI-NEXT: retq 143; 144; X64-BMI1-LABEL: bextr32_a0_arithmetic: 145; X64-BMI1: # %bb.0: 146; X64-BMI1-NEXT: movl %esi, %ecx 147; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 148; X64-BMI1-NEXT: sarl %cl, %edi 149; X64-BMI1-NEXT: shll $8, %edx 150; X64-BMI1-NEXT: bextrl %edx, %edi, %eax 151; X64-BMI1-NEXT: retq 152; 153; X64-BMI2-LABEL: bextr32_a0_arithmetic: 154; X64-BMI2: # %bb.0: 155; X64-BMI2-NEXT: sarxl %esi, %edi, %eax 156; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 157; X64-BMI2-NEXT: retq 158 %shifted = ashr i32 %val, %numskipbits 159 %onebit = shl i32 1, %numlowbits 160 %mask = add nsw i32 %onebit, -1 161 %masked = and i32 %mask, %shifted 162 ret i32 %masked 163} 164 165define i32 @bextr32_a1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind { 166; X86-NOBMI-LABEL: bextr32_a1_indexzext: 167; X86-NOBMI: # %bb.0: 168; X86-NOBMI-NEXT: pushl %esi 169; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 170; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 171; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 172; X86-NOBMI-NEXT: shrl %cl, %esi 173; X86-NOBMI-NEXT: movl $1, %eax 174; X86-NOBMI-NEXT: movl %edx, %ecx 175; X86-NOBMI-NEXT: shll %cl, %eax 176; X86-NOBMI-NEXT: decl %eax 177; X86-NOBMI-NEXT: andl %esi, %eax 178; X86-NOBMI-NEXT: popl %esi 179; X86-NOBMI-NEXT: retl 180; 181; X86-BMI1-LABEL: bextr32_a1_indexzext: 182; X86-BMI1: # %bb.0: 183; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 184; X86-BMI1-NEXT: shll $8, %eax 185; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 186; X86-BMI1-NEXT: orl %eax, %ecx 187; X86-BMI1-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %eax 188; X86-BMI1-NEXT: retl 189; 190; X86-BMI2-LABEL: bextr32_a1_indexzext: 191; X86-BMI2: # %bb.0: 192; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 193; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 194; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %ecx 195; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 196; X86-BMI2-NEXT: retl 197; 198; X64-NOBMI-LABEL: bextr32_a1_indexzext: 199; X64-NOBMI: # %bb.0: 200; X64-NOBMI-NEXT: movl %esi, %ecx 201; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 202; X64-NOBMI-NEXT: shrl %cl, %edi 203; X64-NOBMI-NEXT: movl $1, %eax 204; X64-NOBMI-NEXT: movl %edx, %ecx 205; X64-NOBMI-NEXT: shll %cl, %eax 206; X64-NOBMI-NEXT: decl %eax 207; X64-NOBMI-NEXT: andl %edi, %eax 208; X64-NOBMI-NEXT: retq 209; 210; X64-BMI1-LABEL: bextr32_a1_indexzext: 211; X64-BMI1: # %bb.0: 212; X64-BMI1-NEXT: shll $8, %edx 213; X64-BMI1-NEXT: orl %esi, %edx 214; X64-BMI1-NEXT: bextrl %edx, %edi, %eax 215; X64-BMI1-NEXT: retq 216; 217; X64-BMI2-LABEL: bextr32_a1_indexzext: 218; X64-BMI2: # %bb.0: 219; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 220; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 221; X64-BMI2-NEXT: retq 222 %skip = zext i8 %numskipbits to i32 223 %shifted = lshr i32 %val, %skip 224 %conv = zext i8 %numlowbits to i32 225 %onebit = shl i32 1, %conv 226 %mask = add nsw i32 %onebit, -1 227 %masked = and i32 %mask, %shifted 228 ret i32 %masked 229} 230 231define i32 @bextr32_a2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind { 232; X86-NOBMI-LABEL: bextr32_a2_load: 233; X86-NOBMI: # %bb.0: 234; X86-NOBMI-NEXT: pushl %esi 235; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 236; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 237; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 238; X86-NOBMI-NEXT: movl (%eax), %esi 239; X86-NOBMI-NEXT: shrl %cl, %esi 240; X86-NOBMI-NEXT: movl $1, %eax 241; X86-NOBMI-NEXT: movl %edx, %ecx 242; X86-NOBMI-NEXT: shll %cl, %eax 243; X86-NOBMI-NEXT: decl %eax 244; X86-NOBMI-NEXT: andl %esi, %eax 245; X86-NOBMI-NEXT: popl %esi 246; X86-NOBMI-NEXT: retl 247; 248; X86-BMI1-LABEL: bextr32_a2_load: 249; X86-BMI1: # %bb.0: 250; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 251; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 252; X86-BMI1-NEXT: shll $8, %ecx 253; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 254; X86-BMI1-NEXT: orl %ecx, %edx 255; X86-BMI1-NEXT: bextrl %edx, (%eax), %eax 256; X86-BMI1-NEXT: retl 257; 258; X86-BMI2-LABEL: bextr32_a2_load: 259; X86-BMI2: # %bb.0: 260; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 261; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 262; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %edx 263; X86-BMI2-NEXT: shrxl %edx, (%ecx), %ecx 264; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 265; X86-BMI2-NEXT: retl 266; 267; X64-NOBMI-LABEL: bextr32_a2_load: 268; X64-NOBMI: # %bb.0: 269; X64-NOBMI-NEXT: movl %esi, %ecx 270; X64-NOBMI-NEXT: movl (%rdi), %esi 271; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 272; X64-NOBMI-NEXT: shrl %cl, %esi 273; X64-NOBMI-NEXT: movl $1, %eax 274; X64-NOBMI-NEXT: movl %edx, %ecx 275; X64-NOBMI-NEXT: shll %cl, %eax 276; X64-NOBMI-NEXT: decl %eax 277; X64-NOBMI-NEXT: andl %esi, %eax 278; X64-NOBMI-NEXT: retq 279; 280; X64-BMI1-LABEL: bextr32_a2_load: 281; X64-BMI1: # %bb.0: 282; X64-BMI1-NEXT: shll $8, %edx 283; X64-BMI1-NEXT: movzbl %sil, %eax 284; X64-BMI1-NEXT: orl %edx, %eax 285; X64-BMI1-NEXT: bextrl %eax, (%rdi), %eax 286; X64-BMI1-NEXT: retq 287; 288; X64-BMI2-LABEL: bextr32_a2_load: 289; X64-BMI2: # %bb.0: 290; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 291; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 292; X64-BMI2-NEXT: retq 293 %val = load i32, ptr %w 294 %shifted = lshr i32 %val, %numskipbits 295 %onebit = shl i32 1, %numlowbits 296 %mask = add nsw i32 %onebit, -1 297 %masked = and i32 %mask, %shifted 298 ret i32 %masked 299} 300 301define i32 @bextr32_a3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind { 302; X86-NOBMI-LABEL: bextr32_a3_load_indexzext: 303; X86-NOBMI: # %bb.0: 304; X86-NOBMI-NEXT: pushl %esi 305; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 306; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 307; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 308; X86-NOBMI-NEXT: movl (%eax), %esi 309; X86-NOBMI-NEXT: shrl %cl, %esi 310; X86-NOBMI-NEXT: movl $1, %eax 311; X86-NOBMI-NEXT: movl %edx, %ecx 312; X86-NOBMI-NEXT: shll %cl, %eax 313; X86-NOBMI-NEXT: decl %eax 314; X86-NOBMI-NEXT: andl %esi, %eax 315; X86-NOBMI-NEXT: popl %esi 316; X86-NOBMI-NEXT: retl 317; 318; X86-BMI1-LABEL: bextr32_a3_load_indexzext: 319; X86-BMI1: # %bb.0: 320; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 321; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 322; X86-BMI1-NEXT: shll $8, %ecx 323; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 324; X86-BMI1-NEXT: orl %ecx, %edx 325; X86-BMI1-NEXT: bextrl %edx, (%eax), %eax 326; X86-BMI1-NEXT: retl 327; 328; X86-BMI2-LABEL: bextr32_a3_load_indexzext: 329; X86-BMI2: # %bb.0: 330; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 331; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 332; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %edx 333; X86-BMI2-NEXT: shrxl %edx, (%ecx), %ecx 334; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 335; X86-BMI2-NEXT: retl 336; 337; X64-NOBMI-LABEL: bextr32_a3_load_indexzext: 338; X64-NOBMI: # %bb.0: 339; X64-NOBMI-NEXT: movl %esi, %ecx 340; X64-NOBMI-NEXT: movl (%rdi), %esi 341; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 342; X64-NOBMI-NEXT: shrl %cl, %esi 343; X64-NOBMI-NEXT: movl $1, %eax 344; X64-NOBMI-NEXT: movl %edx, %ecx 345; X64-NOBMI-NEXT: shll %cl, %eax 346; X64-NOBMI-NEXT: decl %eax 347; X64-NOBMI-NEXT: andl %esi, %eax 348; X64-NOBMI-NEXT: retq 349; 350; X64-BMI1-LABEL: bextr32_a3_load_indexzext: 351; X64-BMI1: # %bb.0: 352; X64-BMI1-NEXT: shll $8, %edx 353; X64-BMI1-NEXT: orl %esi, %edx 354; X64-BMI1-NEXT: bextrl %edx, (%rdi), %eax 355; X64-BMI1-NEXT: retq 356; 357; X64-BMI2-LABEL: bextr32_a3_load_indexzext: 358; X64-BMI2: # %bb.0: 359; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 360; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 361; X64-BMI2-NEXT: retq 362 %val = load i32, ptr %w 363 %skip = zext i8 %numskipbits to i32 364 %shifted = lshr i32 %val, %skip 365 %conv = zext i8 %numlowbits to i32 366 %onebit = shl i32 1, %conv 367 %mask = add nsw i32 %onebit, -1 368 %masked = and i32 %mask, %shifted 369 ret i32 %masked 370} 371 372define i32 @bextr32_a4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 373; X86-NOBMI-LABEL: bextr32_a4_commutative: 374; X86-NOBMI: # %bb.0: 375; X86-NOBMI-NEXT: pushl %esi 376; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 377; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 378; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 379; X86-NOBMI-NEXT: shrl %cl, %esi 380; X86-NOBMI-NEXT: movl $1, %eax 381; X86-NOBMI-NEXT: movl %edx, %ecx 382; X86-NOBMI-NEXT: shll %cl, %eax 383; X86-NOBMI-NEXT: decl %eax 384; X86-NOBMI-NEXT: andl %esi, %eax 385; X86-NOBMI-NEXT: popl %esi 386; X86-NOBMI-NEXT: retl 387; 388; X86-BMI1-LABEL: bextr32_a4_commutative: 389; X86-BMI1: # %bb.0: 390; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 391; X86-BMI1-NEXT: shll $8, %eax 392; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 393; X86-BMI1-NEXT: orl %eax, %ecx 394; X86-BMI1-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %eax 395; X86-BMI1-NEXT: retl 396; 397; X86-BMI2-LABEL: bextr32_a4_commutative: 398; X86-BMI2: # %bb.0: 399; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 400; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 401; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %ecx 402; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 403; X86-BMI2-NEXT: retl 404; 405; X64-NOBMI-LABEL: bextr32_a4_commutative: 406; X64-NOBMI: # %bb.0: 407; X64-NOBMI-NEXT: movl %esi, %ecx 408; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 409; X64-NOBMI-NEXT: shrl %cl, %edi 410; X64-NOBMI-NEXT: movl $1, %eax 411; X64-NOBMI-NEXT: movl %edx, %ecx 412; X64-NOBMI-NEXT: shll %cl, %eax 413; X64-NOBMI-NEXT: decl %eax 414; X64-NOBMI-NEXT: andl %edi, %eax 415; X64-NOBMI-NEXT: retq 416; 417; X64-BMI1-LABEL: bextr32_a4_commutative: 418; X64-BMI1: # %bb.0: 419; X64-BMI1-NEXT: shll $8, %edx 420; X64-BMI1-NEXT: movzbl %sil, %eax 421; X64-BMI1-NEXT: orl %edx, %eax 422; X64-BMI1-NEXT: bextrl %eax, %edi, %eax 423; X64-BMI1-NEXT: retq 424; 425; X64-BMI2-LABEL: bextr32_a4_commutative: 426; X64-BMI2: # %bb.0: 427; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 428; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 429; X64-BMI2-NEXT: retq 430 %shifted = lshr i32 %val, %numskipbits 431 %onebit = shl i32 1, %numlowbits 432 %mask = add nsw i32 %onebit, -1 433 %masked = and i32 %shifted, %mask ; swapped order 434 ret i32 %masked 435} 436 437define i32 @bextr32_a5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 438; X86-NOBMI-LABEL: bextr32_a5_skipextrauses: 439; X86-NOBMI: # %bb.0: 440; X86-NOBMI-NEXT: pushl %edi 441; X86-NOBMI-NEXT: pushl %esi 442; X86-NOBMI-NEXT: pushl %eax 443; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 444; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 445; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 446; X86-NOBMI-NEXT: movl %eax, %ecx 447; X86-NOBMI-NEXT: shrl %cl, %edi 448; X86-NOBMI-NEXT: movl $1, %esi 449; X86-NOBMI-NEXT: movl %edx, %ecx 450; X86-NOBMI-NEXT: shll %cl, %esi 451; X86-NOBMI-NEXT: decl %esi 452; X86-NOBMI-NEXT: andl %edi, %esi 453; X86-NOBMI-NEXT: movl %eax, (%esp) 454; X86-NOBMI-NEXT: calll use32@PLT 455; X86-NOBMI-NEXT: movl %esi, %eax 456; X86-NOBMI-NEXT: addl $4, %esp 457; X86-NOBMI-NEXT: popl %esi 458; X86-NOBMI-NEXT: popl %edi 459; X86-NOBMI-NEXT: retl 460; 461; X86-BMI1-LABEL: bextr32_a5_skipextrauses: 462; X86-BMI1: # %bb.0: 463; X86-BMI1-NEXT: pushl %esi 464; X86-BMI1-NEXT: subl $8, %esp 465; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 466; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 467; X86-BMI1-NEXT: shll $8, %ecx 468; X86-BMI1-NEXT: movzbl %al, %edx 469; X86-BMI1-NEXT: orl %ecx, %edx 470; X86-BMI1-NEXT: bextrl %edx, {{[0-9]+}}(%esp), %esi 471; X86-BMI1-NEXT: movl %eax, (%esp) 472; X86-BMI1-NEXT: calll use32@PLT 473; X86-BMI1-NEXT: movl %esi, %eax 474; X86-BMI1-NEXT: addl $8, %esp 475; X86-BMI1-NEXT: popl %esi 476; X86-BMI1-NEXT: retl 477; 478; X86-BMI2-LABEL: bextr32_a5_skipextrauses: 479; X86-BMI2: # %bb.0: 480; X86-BMI2-NEXT: pushl %esi 481; X86-BMI2-NEXT: subl $8, %esp 482; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 483; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 484; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %edx 485; X86-BMI2-NEXT: bzhil %eax, %edx, %esi 486; X86-BMI2-NEXT: movl %ecx, (%esp) 487; X86-BMI2-NEXT: calll use32@PLT 488; X86-BMI2-NEXT: movl %esi, %eax 489; X86-BMI2-NEXT: addl $8, %esp 490; X86-BMI2-NEXT: popl %esi 491; X86-BMI2-NEXT: retl 492; 493; X64-NOBMI-LABEL: bextr32_a5_skipextrauses: 494; X64-NOBMI: # %bb.0: 495; X64-NOBMI-NEXT: pushq %rbx 496; X64-NOBMI-NEXT: movl %esi, %ecx 497; X64-NOBMI-NEXT: shrl %cl, %edi 498; X64-NOBMI-NEXT: movl $1, %ebx 499; X64-NOBMI-NEXT: movl %edx, %ecx 500; X64-NOBMI-NEXT: shll %cl, %ebx 501; X64-NOBMI-NEXT: decl %ebx 502; X64-NOBMI-NEXT: andl %edi, %ebx 503; X64-NOBMI-NEXT: movl %esi, %edi 504; X64-NOBMI-NEXT: callq use32@PLT 505; X64-NOBMI-NEXT: movl %ebx, %eax 506; X64-NOBMI-NEXT: popq %rbx 507; X64-NOBMI-NEXT: retq 508; 509; X64-BMI1-LABEL: bextr32_a5_skipextrauses: 510; X64-BMI1: # %bb.0: 511; X64-BMI1-NEXT: pushq %rbx 512; X64-BMI1-NEXT: shll $8, %edx 513; X64-BMI1-NEXT: movzbl %sil, %eax 514; X64-BMI1-NEXT: orl %edx, %eax 515; X64-BMI1-NEXT: bextrl %eax, %edi, %ebx 516; X64-BMI1-NEXT: movl %esi, %edi 517; X64-BMI1-NEXT: callq use32@PLT 518; X64-BMI1-NEXT: movl %ebx, %eax 519; X64-BMI1-NEXT: popq %rbx 520; X64-BMI1-NEXT: retq 521; 522; X64-BMI2-LABEL: bextr32_a5_skipextrauses: 523; X64-BMI2: # %bb.0: 524; X64-BMI2-NEXT: pushq %rbx 525; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 526; X64-BMI2-NEXT: bzhil %edx, %eax, %ebx 527; X64-BMI2-NEXT: movl %esi, %edi 528; X64-BMI2-NEXT: callq use32@PLT 529; X64-BMI2-NEXT: movl %ebx, %eax 530; X64-BMI2-NEXT: popq %rbx 531; X64-BMI2-NEXT: retq 532 %shifted = lshr i32 %val, %numskipbits 533 %onebit = shl i32 1, %numlowbits 534 %mask = add nsw i32 %onebit, -1 535 %masked = and i32 %mask, %shifted 536 call void @use32(i32 %numskipbits) 537 ret i32 %masked 538} 539 540; 64-bit 541 542define i64 @bextr64_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 543; X86-NOBMI-LABEL: bextr64_a0: 544; X86-NOBMI: # %bb.0: 545; X86-NOBMI-NEXT: pushl %edi 546; X86-NOBMI-NEXT: pushl %esi 547; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 548; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 549; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 550; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 551; X86-NOBMI-NEXT: movl %eax, %edi 552; X86-NOBMI-NEXT: shrl %cl, %edi 553; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 554; X86-NOBMI-NEXT: testb $32, %cl 555; X86-NOBMI-NEXT: je .LBB7_2 556; X86-NOBMI-NEXT: # %bb.1: 557; X86-NOBMI-NEXT: movl %edi, %esi 558; X86-NOBMI-NEXT: xorl %edi, %edi 559; X86-NOBMI-NEXT: .LBB7_2: 560; X86-NOBMI-NEXT: movl $1, %eax 561; X86-NOBMI-NEXT: xorl %edx, %edx 562; X86-NOBMI-NEXT: movb %ch, %cl 563; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 564; X86-NOBMI-NEXT: shll %cl, %eax 565; X86-NOBMI-NEXT: testb $32, %ch 566; X86-NOBMI-NEXT: je .LBB7_4 567; X86-NOBMI-NEXT: # %bb.3: 568; X86-NOBMI-NEXT: movl %eax, %edx 569; X86-NOBMI-NEXT: xorl %eax, %eax 570; X86-NOBMI-NEXT: .LBB7_4: 571; X86-NOBMI-NEXT: addl $-1, %eax 572; X86-NOBMI-NEXT: adcl $-1, %edx 573; X86-NOBMI-NEXT: andl %esi, %eax 574; X86-NOBMI-NEXT: andl %edi, %edx 575; X86-NOBMI-NEXT: popl %esi 576; X86-NOBMI-NEXT: popl %edi 577; X86-NOBMI-NEXT: retl 578; 579; X86-BMI1-LABEL: bextr64_a0: 580; X86-BMI1: # %bb.0: 581; X86-BMI1-NEXT: pushl %edi 582; X86-BMI1-NEXT: pushl %esi 583; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %ch 584; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl 585; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 586; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 587; X86-BMI1-NEXT: movl %eax, %edi 588; X86-BMI1-NEXT: shrl %cl, %edi 589; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 590; X86-BMI1-NEXT: testb $32, %cl 591; X86-BMI1-NEXT: je .LBB7_2 592; X86-BMI1-NEXT: # %bb.1: 593; X86-BMI1-NEXT: movl %edi, %esi 594; X86-BMI1-NEXT: xorl %edi, %edi 595; X86-BMI1-NEXT: .LBB7_2: 596; X86-BMI1-NEXT: movl $1, %eax 597; X86-BMI1-NEXT: xorl %edx, %edx 598; X86-BMI1-NEXT: movb %ch, %cl 599; X86-BMI1-NEXT: shldl %cl, %eax, %edx 600; X86-BMI1-NEXT: shll %cl, %eax 601; X86-BMI1-NEXT: testb $32, %ch 602; X86-BMI1-NEXT: je .LBB7_4 603; X86-BMI1-NEXT: # %bb.3: 604; X86-BMI1-NEXT: movl %eax, %edx 605; X86-BMI1-NEXT: xorl %eax, %eax 606; X86-BMI1-NEXT: .LBB7_4: 607; X86-BMI1-NEXT: addl $-1, %eax 608; X86-BMI1-NEXT: adcl $-1, %edx 609; X86-BMI1-NEXT: andl %esi, %eax 610; X86-BMI1-NEXT: andl %edi, %edx 611; X86-BMI1-NEXT: popl %esi 612; X86-BMI1-NEXT: popl %edi 613; X86-BMI1-NEXT: retl 614; 615; X86-BMI2-LABEL: bextr64_a0: 616; X86-BMI2: # %bb.0: 617; X86-BMI2-NEXT: pushl %ebx 618; X86-BMI2-NEXT: pushl %edi 619; X86-BMI2-NEXT: pushl %esi 620; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 621; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 622; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 623; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 624; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 625; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 626; X86-BMI2-NEXT: testb $32, %cl 627; X86-BMI2-NEXT: je .LBB7_2 628; X86-BMI2-NEXT: # %bb.1: 629; X86-BMI2-NEXT: movl %edi, %esi 630; X86-BMI2-NEXT: xorl %edi, %edi 631; X86-BMI2-NEXT: .LBB7_2: 632; X86-BMI2-NEXT: movl $1, %eax 633; X86-BMI2-NEXT: xorl %edx, %edx 634; X86-BMI2-NEXT: movl %ebx, %ecx 635; X86-BMI2-NEXT: shldl %cl, %eax, %edx 636; X86-BMI2-NEXT: shlxl %ebx, %eax, %eax 637; X86-BMI2-NEXT: testb $32, %bl 638; X86-BMI2-NEXT: je .LBB7_4 639; X86-BMI2-NEXT: # %bb.3: 640; X86-BMI2-NEXT: movl %eax, %edx 641; X86-BMI2-NEXT: xorl %eax, %eax 642; X86-BMI2-NEXT: .LBB7_4: 643; X86-BMI2-NEXT: addl $-1, %eax 644; X86-BMI2-NEXT: adcl $-1, %edx 645; X86-BMI2-NEXT: andl %esi, %eax 646; X86-BMI2-NEXT: andl %edi, %edx 647; X86-BMI2-NEXT: popl %esi 648; X86-BMI2-NEXT: popl %edi 649; X86-BMI2-NEXT: popl %ebx 650; X86-BMI2-NEXT: retl 651; 652; X64-NOBMI-LABEL: bextr64_a0: 653; X64-NOBMI: # %bb.0: 654; X64-NOBMI-NEXT: movq %rsi, %rcx 655; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 656; X64-NOBMI-NEXT: shrq %cl, %rdi 657; X64-NOBMI-NEXT: movl $1, %eax 658; X64-NOBMI-NEXT: movl %edx, %ecx 659; X64-NOBMI-NEXT: shlq %cl, %rax 660; X64-NOBMI-NEXT: decq %rax 661; X64-NOBMI-NEXT: andq %rdi, %rax 662; X64-NOBMI-NEXT: retq 663; 664; X64-BMI1-LABEL: bextr64_a0: 665; X64-BMI1: # %bb.0: 666; X64-BMI1-NEXT: shll $8, %edx 667; X64-BMI1-NEXT: movzbl %sil, %eax 668; X64-BMI1-NEXT: orl %edx, %eax 669; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 670; X64-BMI1-NEXT: retq 671; 672; X64-BMI2-LABEL: bextr64_a0: 673; X64-BMI2: # %bb.0: 674; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 675; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 676; X64-BMI2-NEXT: retq 677 %shifted = lshr i64 %val, %numskipbits 678 %onebit = shl i64 1, %numlowbits 679 %mask = add nsw i64 %onebit, -1 680 %masked = and i64 %mask, %shifted 681 ret i64 %masked 682} 683 684define i64 @bextr64_a0_arithmetic(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 685; X86-NOBMI-LABEL: bextr64_a0_arithmetic: 686; X86-NOBMI: # %bb.0: 687; X86-NOBMI-NEXT: pushl %edi 688; X86-NOBMI-NEXT: pushl %esi 689; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 690; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 691; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 692; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 693; X86-NOBMI-NEXT: movl %eax, %esi 694; X86-NOBMI-NEXT: sarl %cl, %esi 695; X86-NOBMI-NEXT: shrdl %cl, %eax, %edi 696; X86-NOBMI-NEXT: testb $32, %cl 697; X86-NOBMI-NEXT: je .LBB8_2 698; X86-NOBMI-NEXT: # %bb.1: 699; X86-NOBMI-NEXT: sarl $31, %eax 700; X86-NOBMI-NEXT: movl %esi, %edi 701; X86-NOBMI-NEXT: movl %eax, %esi 702; X86-NOBMI-NEXT: .LBB8_2: 703; X86-NOBMI-NEXT: movl $1, %eax 704; X86-NOBMI-NEXT: xorl %edx, %edx 705; X86-NOBMI-NEXT: movb %ch, %cl 706; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 707; X86-NOBMI-NEXT: shll %cl, %eax 708; X86-NOBMI-NEXT: testb $32, %ch 709; X86-NOBMI-NEXT: je .LBB8_4 710; X86-NOBMI-NEXT: # %bb.3: 711; X86-NOBMI-NEXT: movl %eax, %edx 712; X86-NOBMI-NEXT: xorl %eax, %eax 713; X86-NOBMI-NEXT: .LBB8_4: 714; X86-NOBMI-NEXT: addl $-1, %eax 715; X86-NOBMI-NEXT: adcl $-1, %edx 716; X86-NOBMI-NEXT: andl %edi, %eax 717; X86-NOBMI-NEXT: andl %esi, %edx 718; X86-NOBMI-NEXT: popl %esi 719; X86-NOBMI-NEXT: popl %edi 720; X86-NOBMI-NEXT: retl 721; 722; X86-BMI1-LABEL: bextr64_a0_arithmetic: 723; X86-BMI1: # %bb.0: 724; X86-BMI1-NEXT: pushl %edi 725; X86-BMI1-NEXT: pushl %esi 726; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %ch 727; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl 728; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 729; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 730; X86-BMI1-NEXT: movl %eax, %esi 731; X86-BMI1-NEXT: sarl %cl, %esi 732; X86-BMI1-NEXT: shrdl %cl, %eax, %edi 733; X86-BMI1-NEXT: testb $32, %cl 734; X86-BMI1-NEXT: je .LBB8_2 735; X86-BMI1-NEXT: # %bb.1: 736; X86-BMI1-NEXT: sarl $31, %eax 737; X86-BMI1-NEXT: movl %esi, %edi 738; X86-BMI1-NEXT: movl %eax, %esi 739; X86-BMI1-NEXT: .LBB8_2: 740; X86-BMI1-NEXT: movl $1, %eax 741; X86-BMI1-NEXT: xorl %edx, %edx 742; X86-BMI1-NEXT: movb %ch, %cl 743; X86-BMI1-NEXT: shldl %cl, %eax, %edx 744; X86-BMI1-NEXT: shll %cl, %eax 745; X86-BMI1-NEXT: testb $32, %ch 746; X86-BMI1-NEXT: je .LBB8_4 747; X86-BMI1-NEXT: # %bb.3: 748; X86-BMI1-NEXT: movl %eax, %edx 749; X86-BMI1-NEXT: xorl %eax, %eax 750; X86-BMI1-NEXT: .LBB8_4: 751; X86-BMI1-NEXT: addl $-1, %eax 752; X86-BMI1-NEXT: adcl $-1, %edx 753; X86-BMI1-NEXT: andl %edi, %eax 754; X86-BMI1-NEXT: andl %esi, %edx 755; X86-BMI1-NEXT: popl %esi 756; X86-BMI1-NEXT: popl %edi 757; X86-BMI1-NEXT: retl 758; 759; X86-BMI2-LABEL: bextr64_a0_arithmetic: 760; X86-BMI2: # %bb.0: 761; X86-BMI2-NEXT: pushl %ebx 762; X86-BMI2-NEXT: pushl %edi 763; X86-BMI2-NEXT: pushl %esi 764; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 765; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 766; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 767; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 768; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 769; X86-BMI2-NEXT: sarxl %ecx, %eax, %edi 770; X86-BMI2-NEXT: testb $32, %cl 771; X86-BMI2-NEXT: je .LBB8_2 772; X86-BMI2-NEXT: # %bb.1: 773; X86-BMI2-NEXT: sarl $31, %eax 774; X86-BMI2-NEXT: movl %edi, %esi 775; X86-BMI2-NEXT: movl %eax, %edi 776; X86-BMI2-NEXT: .LBB8_2: 777; X86-BMI2-NEXT: movl $1, %eax 778; X86-BMI2-NEXT: xorl %edx, %edx 779; X86-BMI2-NEXT: movl %ebx, %ecx 780; X86-BMI2-NEXT: shldl %cl, %eax, %edx 781; X86-BMI2-NEXT: shlxl %ebx, %eax, %eax 782; X86-BMI2-NEXT: testb $32, %bl 783; X86-BMI2-NEXT: je .LBB8_4 784; X86-BMI2-NEXT: # %bb.3: 785; X86-BMI2-NEXT: movl %eax, %edx 786; X86-BMI2-NEXT: xorl %eax, %eax 787; X86-BMI2-NEXT: .LBB8_4: 788; X86-BMI2-NEXT: addl $-1, %eax 789; X86-BMI2-NEXT: adcl $-1, %edx 790; X86-BMI2-NEXT: andl %esi, %eax 791; X86-BMI2-NEXT: andl %edi, %edx 792; X86-BMI2-NEXT: popl %esi 793; X86-BMI2-NEXT: popl %edi 794; X86-BMI2-NEXT: popl %ebx 795; X86-BMI2-NEXT: retl 796; 797; X64-NOBMI-LABEL: bextr64_a0_arithmetic: 798; X64-NOBMI: # %bb.0: 799; X64-NOBMI-NEXT: movq %rsi, %rcx 800; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 801; X64-NOBMI-NEXT: sarq %cl, %rdi 802; X64-NOBMI-NEXT: movl $1, %eax 803; X64-NOBMI-NEXT: movl %edx, %ecx 804; X64-NOBMI-NEXT: shlq %cl, %rax 805; X64-NOBMI-NEXT: decq %rax 806; X64-NOBMI-NEXT: andq %rdi, %rax 807; X64-NOBMI-NEXT: retq 808; 809; X64-BMI1-LABEL: bextr64_a0_arithmetic: 810; X64-BMI1: # %bb.0: 811; X64-BMI1-NEXT: movq %rsi, %rcx 812; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $rcx 813; X64-BMI1-NEXT: sarq %cl, %rdi 814; X64-BMI1-NEXT: shll $8, %edx 815; X64-BMI1-NEXT: bextrq %rdx, %rdi, %rax 816; X64-BMI1-NEXT: retq 817; 818; X64-BMI2-LABEL: bextr64_a0_arithmetic: 819; X64-BMI2: # %bb.0: 820; X64-BMI2-NEXT: sarxq %rsi, %rdi, %rax 821; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 822; X64-BMI2-NEXT: retq 823 %shifted = ashr i64 %val, %numskipbits 824 %onebit = shl i64 1, %numlowbits 825 %mask = add nsw i64 %onebit, -1 826 %masked = and i64 %mask, %shifted 827 ret i64 %masked 828} 829 830define i64 @bextr64_a1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind { 831; X86-NOBMI-LABEL: bextr64_a1_indexzext: 832; X86-NOBMI: # %bb.0: 833; X86-NOBMI-NEXT: pushl %edi 834; X86-NOBMI-NEXT: pushl %esi 835; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 836; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 837; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 838; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 839; X86-NOBMI-NEXT: movl %eax, %edi 840; X86-NOBMI-NEXT: shrl %cl, %edi 841; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 842; X86-NOBMI-NEXT: testb $32, %cl 843; X86-NOBMI-NEXT: je .LBB9_2 844; X86-NOBMI-NEXT: # %bb.1: 845; X86-NOBMI-NEXT: movl %edi, %esi 846; X86-NOBMI-NEXT: xorl %edi, %edi 847; X86-NOBMI-NEXT: .LBB9_2: 848; X86-NOBMI-NEXT: movl $1, %eax 849; X86-NOBMI-NEXT: xorl %edx, %edx 850; X86-NOBMI-NEXT: movb %ch, %cl 851; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 852; X86-NOBMI-NEXT: shll %cl, %eax 853; X86-NOBMI-NEXT: testb $32, %ch 854; X86-NOBMI-NEXT: je .LBB9_4 855; X86-NOBMI-NEXT: # %bb.3: 856; X86-NOBMI-NEXT: movl %eax, %edx 857; X86-NOBMI-NEXT: xorl %eax, %eax 858; X86-NOBMI-NEXT: .LBB9_4: 859; X86-NOBMI-NEXT: addl $-1, %eax 860; X86-NOBMI-NEXT: adcl $-1, %edx 861; X86-NOBMI-NEXT: andl %esi, %eax 862; X86-NOBMI-NEXT: andl %edi, %edx 863; X86-NOBMI-NEXT: popl %esi 864; X86-NOBMI-NEXT: popl %edi 865; X86-NOBMI-NEXT: retl 866; 867; X86-BMI1-LABEL: bextr64_a1_indexzext: 868; X86-BMI1: # %bb.0: 869; X86-BMI1-NEXT: pushl %edi 870; X86-BMI1-NEXT: pushl %esi 871; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %ch 872; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl 873; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 874; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 875; X86-BMI1-NEXT: movl %eax, %edi 876; X86-BMI1-NEXT: shrl %cl, %edi 877; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 878; X86-BMI1-NEXT: testb $32, %cl 879; X86-BMI1-NEXT: je .LBB9_2 880; X86-BMI1-NEXT: # %bb.1: 881; X86-BMI1-NEXT: movl %edi, %esi 882; X86-BMI1-NEXT: xorl %edi, %edi 883; X86-BMI1-NEXT: .LBB9_2: 884; X86-BMI1-NEXT: movl $1, %eax 885; X86-BMI1-NEXT: xorl %edx, %edx 886; X86-BMI1-NEXT: movb %ch, %cl 887; X86-BMI1-NEXT: shldl %cl, %eax, %edx 888; X86-BMI1-NEXT: shll %cl, %eax 889; X86-BMI1-NEXT: testb $32, %ch 890; X86-BMI1-NEXT: je .LBB9_4 891; X86-BMI1-NEXT: # %bb.3: 892; X86-BMI1-NEXT: movl %eax, %edx 893; X86-BMI1-NEXT: xorl %eax, %eax 894; X86-BMI1-NEXT: .LBB9_4: 895; X86-BMI1-NEXT: addl $-1, %eax 896; X86-BMI1-NEXT: adcl $-1, %edx 897; X86-BMI1-NEXT: andl %esi, %eax 898; X86-BMI1-NEXT: andl %edi, %edx 899; X86-BMI1-NEXT: popl %esi 900; X86-BMI1-NEXT: popl %edi 901; X86-BMI1-NEXT: retl 902; 903; X86-BMI2-LABEL: bextr64_a1_indexzext: 904; X86-BMI2: # %bb.0: 905; X86-BMI2-NEXT: pushl %ebx 906; X86-BMI2-NEXT: pushl %edi 907; X86-BMI2-NEXT: pushl %esi 908; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 909; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 910; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 911; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 912; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 913; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 914; X86-BMI2-NEXT: testb $32, %cl 915; X86-BMI2-NEXT: je .LBB9_2 916; X86-BMI2-NEXT: # %bb.1: 917; X86-BMI2-NEXT: movl %edi, %esi 918; X86-BMI2-NEXT: xorl %edi, %edi 919; X86-BMI2-NEXT: .LBB9_2: 920; X86-BMI2-NEXT: movl $1, %eax 921; X86-BMI2-NEXT: xorl %edx, %edx 922; X86-BMI2-NEXT: movl %ebx, %ecx 923; X86-BMI2-NEXT: shldl %cl, %eax, %edx 924; X86-BMI2-NEXT: shlxl %ebx, %eax, %eax 925; X86-BMI2-NEXT: testb $32, %bl 926; X86-BMI2-NEXT: je .LBB9_4 927; X86-BMI2-NEXT: # %bb.3: 928; X86-BMI2-NEXT: movl %eax, %edx 929; X86-BMI2-NEXT: xorl %eax, %eax 930; X86-BMI2-NEXT: .LBB9_4: 931; X86-BMI2-NEXT: addl $-1, %eax 932; X86-BMI2-NEXT: adcl $-1, %edx 933; X86-BMI2-NEXT: andl %esi, %eax 934; X86-BMI2-NEXT: andl %edi, %edx 935; X86-BMI2-NEXT: popl %esi 936; X86-BMI2-NEXT: popl %edi 937; X86-BMI2-NEXT: popl %ebx 938; X86-BMI2-NEXT: retl 939; 940; X64-NOBMI-LABEL: bextr64_a1_indexzext: 941; X64-NOBMI: # %bb.0: 942; X64-NOBMI-NEXT: movl %esi, %ecx 943; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 944; X64-NOBMI-NEXT: shrq %cl, %rdi 945; X64-NOBMI-NEXT: movl $1, %eax 946; X64-NOBMI-NEXT: movl %edx, %ecx 947; X64-NOBMI-NEXT: shlq %cl, %rax 948; X64-NOBMI-NEXT: decq %rax 949; X64-NOBMI-NEXT: andq %rdi, %rax 950; X64-NOBMI-NEXT: retq 951; 952; X64-BMI1-LABEL: bextr64_a1_indexzext: 953; X64-BMI1: # %bb.0: 954; X64-BMI1-NEXT: # kill: def $edx killed $edx def $rdx 955; X64-BMI1-NEXT: shll $8, %edx 956; X64-BMI1-NEXT: orl %esi, %edx 957; X64-BMI1-NEXT: bextrq %rdx, %rdi, %rax 958; X64-BMI1-NEXT: retq 959; 960; X64-BMI2-LABEL: bextr64_a1_indexzext: 961; X64-BMI2: # %bb.0: 962; X64-BMI2-NEXT: # kill: def $edx killed $edx def $rdx 963; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 964; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 965; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 966; X64-BMI2-NEXT: retq 967 %skip = zext i8 %numskipbits to i64 968 %shifted = lshr i64 %val, %skip 969 %conv = zext i8 %numlowbits to i64 970 %onebit = shl i64 1, %conv 971 %mask = add nsw i64 %onebit, -1 972 %masked = and i64 %mask, %shifted 973 ret i64 %masked 974} 975 976define i64 @bextr64_a2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind { 977; X86-NOBMI-LABEL: bextr64_a2_load: 978; X86-NOBMI: # %bb.0: 979; X86-NOBMI-NEXT: pushl %edi 980; X86-NOBMI-NEXT: pushl %esi 981; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 982; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 983; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 984; X86-NOBMI-NEXT: movl (%eax), %esi 985; X86-NOBMI-NEXT: movl 4(%eax), %eax 986; X86-NOBMI-NEXT: movl %eax, %edi 987; X86-NOBMI-NEXT: shrl %cl, %edi 988; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 989; X86-NOBMI-NEXT: testb $32, %cl 990; X86-NOBMI-NEXT: je .LBB10_2 991; X86-NOBMI-NEXT: # %bb.1: 992; X86-NOBMI-NEXT: movl %edi, %esi 993; X86-NOBMI-NEXT: xorl %edi, %edi 994; X86-NOBMI-NEXT: .LBB10_2: 995; X86-NOBMI-NEXT: movl $1, %eax 996; X86-NOBMI-NEXT: xorl %edx, %edx 997; X86-NOBMI-NEXT: movb %ch, %cl 998; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 999; X86-NOBMI-NEXT: shll %cl, %eax 1000; X86-NOBMI-NEXT: testb $32, %ch 1001; X86-NOBMI-NEXT: je .LBB10_4 1002; X86-NOBMI-NEXT: # %bb.3: 1003; X86-NOBMI-NEXT: movl %eax, %edx 1004; X86-NOBMI-NEXT: xorl %eax, %eax 1005; X86-NOBMI-NEXT: .LBB10_4: 1006; X86-NOBMI-NEXT: addl $-1, %eax 1007; X86-NOBMI-NEXT: adcl $-1, %edx 1008; X86-NOBMI-NEXT: andl %esi, %eax 1009; X86-NOBMI-NEXT: andl %edi, %edx 1010; X86-NOBMI-NEXT: popl %esi 1011; X86-NOBMI-NEXT: popl %edi 1012; X86-NOBMI-NEXT: retl 1013; 1014; X86-BMI1-LABEL: bextr64_a2_load: 1015; X86-BMI1: # %bb.0: 1016; X86-BMI1-NEXT: pushl %edi 1017; X86-BMI1-NEXT: pushl %esi 1018; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %ch 1019; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl 1020; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 1021; X86-BMI1-NEXT: movl (%eax), %esi 1022; X86-BMI1-NEXT: movl 4(%eax), %eax 1023; X86-BMI1-NEXT: movl %eax, %edi 1024; X86-BMI1-NEXT: shrl %cl, %edi 1025; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 1026; X86-BMI1-NEXT: testb $32, %cl 1027; X86-BMI1-NEXT: je .LBB10_2 1028; X86-BMI1-NEXT: # %bb.1: 1029; X86-BMI1-NEXT: movl %edi, %esi 1030; X86-BMI1-NEXT: xorl %edi, %edi 1031; X86-BMI1-NEXT: .LBB10_2: 1032; X86-BMI1-NEXT: movl $1, %eax 1033; X86-BMI1-NEXT: xorl %edx, %edx 1034; X86-BMI1-NEXT: movb %ch, %cl 1035; X86-BMI1-NEXT: shldl %cl, %eax, %edx 1036; X86-BMI1-NEXT: shll %cl, %eax 1037; X86-BMI1-NEXT: testb $32, %ch 1038; X86-BMI1-NEXT: je .LBB10_4 1039; X86-BMI1-NEXT: # %bb.3: 1040; X86-BMI1-NEXT: movl %eax, %edx 1041; X86-BMI1-NEXT: xorl %eax, %eax 1042; X86-BMI1-NEXT: .LBB10_4: 1043; X86-BMI1-NEXT: addl $-1, %eax 1044; X86-BMI1-NEXT: adcl $-1, %edx 1045; X86-BMI1-NEXT: andl %esi, %eax 1046; X86-BMI1-NEXT: andl %edi, %edx 1047; X86-BMI1-NEXT: popl %esi 1048; X86-BMI1-NEXT: popl %edi 1049; X86-BMI1-NEXT: retl 1050; 1051; X86-BMI2-LABEL: bextr64_a2_load: 1052; X86-BMI2: # %bb.0: 1053; X86-BMI2-NEXT: pushl %ebx 1054; X86-BMI2-NEXT: pushl %edi 1055; X86-BMI2-NEXT: pushl %esi 1056; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 1057; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1058; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1059; X86-BMI2-NEXT: movl (%eax), %esi 1060; X86-BMI2-NEXT: movl 4(%eax), %eax 1061; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 1062; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 1063; X86-BMI2-NEXT: testb $32, %cl 1064; X86-BMI2-NEXT: je .LBB10_2 1065; X86-BMI2-NEXT: # %bb.1: 1066; X86-BMI2-NEXT: movl %edi, %esi 1067; X86-BMI2-NEXT: xorl %edi, %edi 1068; X86-BMI2-NEXT: .LBB10_2: 1069; X86-BMI2-NEXT: movl $1, %eax 1070; X86-BMI2-NEXT: xorl %edx, %edx 1071; X86-BMI2-NEXT: movl %ebx, %ecx 1072; X86-BMI2-NEXT: shldl %cl, %eax, %edx 1073; X86-BMI2-NEXT: shlxl %ebx, %eax, %eax 1074; X86-BMI2-NEXT: testb $32, %bl 1075; X86-BMI2-NEXT: je .LBB10_4 1076; X86-BMI2-NEXT: # %bb.3: 1077; X86-BMI2-NEXT: movl %eax, %edx 1078; X86-BMI2-NEXT: xorl %eax, %eax 1079; X86-BMI2-NEXT: .LBB10_4: 1080; X86-BMI2-NEXT: addl $-1, %eax 1081; X86-BMI2-NEXT: adcl $-1, %edx 1082; X86-BMI2-NEXT: andl %esi, %eax 1083; X86-BMI2-NEXT: andl %edi, %edx 1084; X86-BMI2-NEXT: popl %esi 1085; X86-BMI2-NEXT: popl %edi 1086; X86-BMI2-NEXT: popl %ebx 1087; X86-BMI2-NEXT: retl 1088; 1089; X64-NOBMI-LABEL: bextr64_a2_load: 1090; X64-NOBMI: # %bb.0: 1091; X64-NOBMI-NEXT: movq %rsi, %rcx 1092; X64-NOBMI-NEXT: movq (%rdi), %rsi 1093; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 1094; X64-NOBMI-NEXT: shrq %cl, %rsi 1095; X64-NOBMI-NEXT: movl $1, %eax 1096; X64-NOBMI-NEXT: movl %edx, %ecx 1097; X64-NOBMI-NEXT: shlq %cl, %rax 1098; X64-NOBMI-NEXT: decq %rax 1099; X64-NOBMI-NEXT: andq %rsi, %rax 1100; X64-NOBMI-NEXT: retq 1101; 1102; X64-BMI1-LABEL: bextr64_a2_load: 1103; X64-BMI1: # %bb.0: 1104; X64-BMI1-NEXT: shll $8, %edx 1105; X64-BMI1-NEXT: movzbl %sil, %eax 1106; X64-BMI1-NEXT: orl %edx, %eax 1107; X64-BMI1-NEXT: bextrq %rax, (%rdi), %rax 1108; X64-BMI1-NEXT: retq 1109; 1110; X64-BMI2-LABEL: bextr64_a2_load: 1111; X64-BMI2: # %bb.0: 1112; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 1113; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 1114; X64-BMI2-NEXT: retq 1115 %val = load i64, ptr %w 1116 %shifted = lshr i64 %val, %numskipbits 1117 %onebit = shl i64 1, %numlowbits 1118 %mask = add nsw i64 %onebit, -1 1119 %masked = and i64 %mask, %shifted 1120 ret i64 %masked 1121} 1122 1123define i64 @bextr64_a3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind { 1124; X86-NOBMI-LABEL: bextr64_a3_load_indexzext: 1125; X86-NOBMI: # %bb.0: 1126; X86-NOBMI-NEXT: pushl %edi 1127; X86-NOBMI-NEXT: pushl %esi 1128; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 1129; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 1130; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 1131; X86-NOBMI-NEXT: movl (%eax), %esi 1132; X86-NOBMI-NEXT: movl 4(%eax), %eax 1133; X86-NOBMI-NEXT: movl %eax, %edi 1134; X86-NOBMI-NEXT: shrl %cl, %edi 1135; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 1136; X86-NOBMI-NEXT: testb $32, %cl 1137; X86-NOBMI-NEXT: je .LBB11_2 1138; X86-NOBMI-NEXT: # %bb.1: 1139; X86-NOBMI-NEXT: movl %edi, %esi 1140; X86-NOBMI-NEXT: xorl %edi, %edi 1141; X86-NOBMI-NEXT: .LBB11_2: 1142; X86-NOBMI-NEXT: movl $1, %eax 1143; X86-NOBMI-NEXT: xorl %edx, %edx 1144; X86-NOBMI-NEXT: movb %ch, %cl 1145; X86-NOBMI-NEXT: shldl %cl, %eax, %edx 1146; X86-NOBMI-NEXT: shll %cl, %eax 1147; X86-NOBMI-NEXT: testb $32, %ch 1148; X86-NOBMI-NEXT: je .LBB11_4 1149; X86-NOBMI-NEXT: # %bb.3: 1150; X86-NOBMI-NEXT: movl %eax, %edx 1151; X86-NOBMI-NEXT: xorl %eax, %eax 1152; X86-NOBMI-NEXT: .LBB11_4: 1153; X86-NOBMI-NEXT: addl $-1, %eax 1154; X86-NOBMI-NEXT: adcl $-1, %edx 1155; X86-NOBMI-NEXT: andl %esi, %eax 1156; X86-NOBMI-NEXT: andl %edi, %edx 1157; X86-NOBMI-NEXT: popl %esi 1158; X86-NOBMI-NEXT: popl %edi 1159; X86-NOBMI-NEXT: retl 1160; 1161; X86-BMI1-LABEL: bextr64_a3_load_indexzext: 1162; X86-BMI1: # %bb.0: 1163; X86-BMI1-NEXT: pushl %edi 1164; X86-BMI1-NEXT: pushl %esi 1165; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %ch 1166; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl 1167; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 1168; X86-BMI1-NEXT: movl (%eax), %esi 1169; X86-BMI1-NEXT: movl 4(%eax), %eax 1170; X86-BMI1-NEXT: movl %eax, %edi 1171; X86-BMI1-NEXT: shrl %cl, %edi 1172; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 1173; X86-BMI1-NEXT: testb $32, %cl 1174; X86-BMI1-NEXT: je .LBB11_2 1175; X86-BMI1-NEXT: # %bb.1: 1176; X86-BMI1-NEXT: movl %edi, %esi 1177; X86-BMI1-NEXT: xorl %edi, %edi 1178; X86-BMI1-NEXT: .LBB11_2: 1179; X86-BMI1-NEXT: movl $1, %eax 1180; X86-BMI1-NEXT: xorl %edx, %edx 1181; X86-BMI1-NEXT: movb %ch, %cl 1182; X86-BMI1-NEXT: shldl %cl, %eax, %edx 1183; X86-BMI1-NEXT: shll %cl, %eax 1184; X86-BMI1-NEXT: testb $32, %ch 1185; X86-BMI1-NEXT: je .LBB11_4 1186; X86-BMI1-NEXT: # %bb.3: 1187; X86-BMI1-NEXT: movl %eax, %edx 1188; X86-BMI1-NEXT: xorl %eax, %eax 1189; X86-BMI1-NEXT: .LBB11_4: 1190; X86-BMI1-NEXT: addl $-1, %eax 1191; X86-BMI1-NEXT: adcl $-1, %edx 1192; X86-BMI1-NEXT: andl %esi, %eax 1193; X86-BMI1-NEXT: andl %edi, %edx 1194; X86-BMI1-NEXT: popl %esi 1195; X86-BMI1-NEXT: popl %edi 1196; X86-BMI1-NEXT: retl 1197; 1198; X86-BMI2-LABEL: bextr64_a3_load_indexzext: 1199; X86-BMI2: # %bb.0: 1200; X86-BMI2-NEXT: pushl %ebx 1201; X86-BMI2-NEXT: pushl %edi 1202; X86-BMI2-NEXT: pushl %esi 1203; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 1204; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1205; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1206; X86-BMI2-NEXT: movl (%eax), %esi 1207; X86-BMI2-NEXT: movl 4(%eax), %eax 1208; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 1209; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 1210; X86-BMI2-NEXT: testb $32, %cl 1211; X86-BMI2-NEXT: je .LBB11_2 1212; X86-BMI2-NEXT: # %bb.1: 1213; X86-BMI2-NEXT: movl %edi, %esi 1214; X86-BMI2-NEXT: xorl %edi, %edi 1215; X86-BMI2-NEXT: .LBB11_2: 1216; X86-BMI2-NEXT: movl $1, %eax 1217; X86-BMI2-NEXT: xorl %edx, %edx 1218; X86-BMI2-NEXT: movl %ebx, %ecx 1219; X86-BMI2-NEXT: shldl %cl, %eax, %edx 1220; X86-BMI2-NEXT: shlxl %ebx, %eax, %eax 1221; X86-BMI2-NEXT: testb $32, %bl 1222; X86-BMI2-NEXT: je .LBB11_4 1223; X86-BMI2-NEXT: # %bb.3: 1224; X86-BMI2-NEXT: movl %eax, %edx 1225; X86-BMI2-NEXT: xorl %eax, %eax 1226; X86-BMI2-NEXT: .LBB11_4: 1227; X86-BMI2-NEXT: addl $-1, %eax 1228; X86-BMI2-NEXT: adcl $-1, %edx 1229; X86-BMI2-NEXT: andl %esi, %eax 1230; X86-BMI2-NEXT: andl %edi, %edx 1231; X86-BMI2-NEXT: popl %esi 1232; X86-BMI2-NEXT: popl %edi 1233; X86-BMI2-NEXT: popl %ebx 1234; X86-BMI2-NEXT: retl 1235; 1236; X64-NOBMI-LABEL: bextr64_a3_load_indexzext: 1237; X64-NOBMI: # %bb.0: 1238; X64-NOBMI-NEXT: movl %esi, %ecx 1239; X64-NOBMI-NEXT: movq (%rdi), %rsi 1240; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 1241; X64-NOBMI-NEXT: shrq %cl, %rsi 1242; X64-NOBMI-NEXT: movl $1, %eax 1243; X64-NOBMI-NEXT: movl %edx, %ecx 1244; X64-NOBMI-NEXT: shlq %cl, %rax 1245; X64-NOBMI-NEXT: decq %rax 1246; X64-NOBMI-NEXT: andq %rsi, %rax 1247; X64-NOBMI-NEXT: retq 1248; 1249; X64-BMI1-LABEL: bextr64_a3_load_indexzext: 1250; X64-BMI1: # %bb.0: 1251; X64-BMI1-NEXT: # kill: def $edx killed $edx def $rdx 1252; X64-BMI1-NEXT: shll $8, %edx 1253; X64-BMI1-NEXT: orl %esi, %edx 1254; X64-BMI1-NEXT: bextrq %rdx, (%rdi), %rax 1255; X64-BMI1-NEXT: retq 1256; 1257; X64-BMI2-LABEL: bextr64_a3_load_indexzext: 1258; X64-BMI2: # %bb.0: 1259; X64-BMI2-NEXT: # kill: def $edx killed $edx def $rdx 1260; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 1261; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 1262; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 1263; X64-BMI2-NEXT: retq 1264 %val = load i64, ptr %w 1265 %skip = zext i8 %numskipbits to i64 1266 %shifted = lshr i64 %val, %skip 1267 %conv = zext i8 %numlowbits to i64 1268 %onebit = shl i64 1, %conv 1269 %mask = add nsw i64 %onebit, -1 1270 %masked = and i64 %mask, %shifted 1271 ret i64 %masked 1272} 1273 1274define i64 @bextr64_a4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 1275; X86-NOBMI-LABEL: bextr64_a4_commutative: 1276; X86-NOBMI: # %bb.0: 1277; X86-NOBMI-NEXT: pushl %edi 1278; X86-NOBMI-NEXT: pushl %esi 1279; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 1280; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 1281; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 1282; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 1283; X86-NOBMI-NEXT: movl %esi, %edx 1284; X86-NOBMI-NEXT: shrl %cl, %edx 1285; X86-NOBMI-NEXT: shrdl %cl, %esi, %eax 1286; X86-NOBMI-NEXT: testb $32, %cl 1287; X86-NOBMI-NEXT: je .LBB12_2 1288; X86-NOBMI-NEXT: # %bb.1: 1289; X86-NOBMI-NEXT: movl %edx, %eax 1290; X86-NOBMI-NEXT: xorl %edx, %edx 1291; X86-NOBMI-NEXT: .LBB12_2: 1292; X86-NOBMI-NEXT: movl $1, %esi 1293; X86-NOBMI-NEXT: xorl %edi, %edi 1294; X86-NOBMI-NEXT: movb %ch, %cl 1295; X86-NOBMI-NEXT: shldl %cl, %esi, %edi 1296; X86-NOBMI-NEXT: shll %cl, %esi 1297; X86-NOBMI-NEXT: testb $32, %ch 1298; X86-NOBMI-NEXT: je .LBB12_4 1299; X86-NOBMI-NEXT: # %bb.3: 1300; X86-NOBMI-NEXT: movl %esi, %edi 1301; X86-NOBMI-NEXT: xorl %esi, %esi 1302; X86-NOBMI-NEXT: .LBB12_4: 1303; X86-NOBMI-NEXT: addl $-1, %esi 1304; X86-NOBMI-NEXT: adcl $-1, %edi 1305; X86-NOBMI-NEXT: andl %esi, %eax 1306; X86-NOBMI-NEXT: andl %edi, %edx 1307; X86-NOBMI-NEXT: popl %esi 1308; X86-NOBMI-NEXT: popl %edi 1309; X86-NOBMI-NEXT: retl 1310; 1311; X86-BMI1-LABEL: bextr64_a4_commutative: 1312; X86-BMI1: # %bb.0: 1313; X86-BMI1-NEXT: pushl %edi 1314; X86-BMI1-NEXT: pushl %esi 1315; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %ch 1316; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl 1317; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 1318; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 1319; X86-BMI1-NEXT: movl %esi, %edx 1320; X86-BMI1-NEXT: shrl %cl, %edx 1321; X86-BMI1-NEXT: shrdl %cl, %esi, %eax 1322; X86-BMI1-NEXT: testb $32, %cl 1323; X86-BMI1-NEXT: je .LBB12_2 1324; X86-BMI1-NEXT: # %bb.1: 1325; X86-BMI1-NEXT: movl %edx, %eax 1326; X86-BMI1-NEXT: xorl %edx, %edx 1327; X86-BMI1-NEXT: .LBB12_2: 1328; X86-BMI1-NEXT: movl $1, %esi 1329; X86-BMI1-NEXT: xorl %edi, %edi 1330; X86-BMI1-NEXT: movb %ch, %cl 1331; X86-BMI1-NEXT: shldl %cl, %esi, %edi 1332; X86-BMI1-NEXT: shll %cl, %esi 1333; X86-BMI1-NEXT: testb $32, %ch 1334; X86-BMI1-NEXT: je .LBB12_4 1335; X86-BMI1-NEXT: # %bb.3: 1336; X86-BMI1-NEXT: movl %esi, %edi 1337; X86-BMI1-NEXT: xorl %esi, %esi 1338; X86-BMI1-NEXT: .LBB12_4: 1339; X86-BMI1-NEXT: addl $-1, %esi 1340; X86-BMI1-NEXT: adcl $-1, %edi 1341; X86-BMI1-NEXT: andl %esi, %eax 1342; X86-BMI1-NEXT: andl %edi, %edx 1343; X86-BMI1-NEXT: popl %esi 1344; X86-BMI1-NEXT: popl %edi 1345; X86-BMI1-NEXT: retl 1346; 1347; X86-BMI2-LABEL: bextr64_a4_commutative: 1348; X86-BMI2: # %bb.0: 1349; X86-BMI2-NEXT: pushl %ebx 1350; X86-BMI2-NEXT: pushl %edi 1351; X86-BMI2-NEXT: pushl %esi 1352; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 1353; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1354; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1355; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 1356; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 1357; X86-BMI2-NEXT: shrxl %ecx, %edx, %edx 1358; X86-BMI2-NEXT: testb $32, %cl 1359; X86-BMI2-NEXT: je .LBB12_2 1360; X86-BMI2-NEXT: # %bb.1: 1361; X86-BMI2-NEXT: movl %edx, %eax 1362; X86-BMI2-NEXT: xorl %edx, %edx 1363; X86-BMI2-NEXT: .LBB12_2: 1364; X86-BMI2-NEXT: movl $1, %edi 1365; X86-BMI2-NEXT: xorl %esi, %esi 1366; X86-BMI2-NEXT: movl %ebx, %ecx 1367; X86-BMI2-NEXT: shldl %cl, %edi, %esi 1368; X86-BMI2-NEXT: shlxl %ebx, %edi, %ecx 1369; X86-BMI2-NEXT: testb $32, %bl 1370; X86-BMI2-NEXT: je .LBB12_4 1371; X86-BMI2-NEXT: # %bb.3: 1372; X86-BMI2-NEXT: movl %ecx, %esi 1373; X86-BMI2-NEXT: xorl %ecx, %ecx 1374; X86-BMI2-NEXT: .LBB12_4: 1375; X86-BMI2-NEXT: addl $-1, %ecx 1376; X86-BMI2-NEXT: adcl $-1, %esi 1377; X86-BMI2-NEXT: andl %ecx, %eax 1378; X86-BMI2-NEXT: andl %esi, %edx 1379; X86-BMI2-NEXT: popl %esi 1380; X86-BMI2-NEXT: popl %edi 1381; X86-BMI2-NEXT: popl %ebx 1382; X86-BMI2-NEXT: retl 1383; 1384; X64-NOBMI-LABEL: bextr64_a4_commutative: 1385; X64-NOBMI: # %bb.0: 1386; X64-NOBMI-NEXT: movq %rsi, %rcx 1387; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 1388; X64-NOBMI-NEXT: shrq %cl, %rdi 1389; X64-NOBMI-NEXT: movl $1, %eax 1390; X64-NOBMI-NEXT: movl %edx, %ecx 1391; X64-NOBMI-NEXT: shlq %cl, %rax 1392; X64-NOBMI-NEXT: decq %rax 1393; X64-NOBMI-NEXT: andq %rdi, %rax 1394; X64-NOBMI-NEXT: retq 1395; 1396; X64-BMI1-LABEL: bextr64_a4_commutative: 1397; X64-BMI1: # %bb.0: 1398; X64-BMI1-NEXT: shll $8, %edx 1399; X64-BMI1-NEXT: movzbl %sil, %eax 1400; X64-BMI1-NEXT: orl %edx, %eax 1401; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 1402; X64-BMI1-NEXT: retq 1403; 1404; X64-BMI2-LABEL: bextr64_a4_commutative: 1405; X64-BMI2: # %bb.0: 1406; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 1407; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 1408; X64-BMI2-NEXT: retq 1409 %shifted = lshr i64 %val, %numskipbits 1410 %onebit = shl i64 1, %numlowbits 1411 %mask = add nsw i64 %onebit, -1 1412 %masked = and i64 %shifted, %mask ; swapped order 1413 ret i64 %masked 1414} 1415 1416define i64 @bextr64_a5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 1417; X86-NOBMI-LABEL: bextr64_a5_skipextrauses: 1418; X86-NOBMI: # %bb.0: 1419; X86-NOBMI-NEXT: pushl %ebp 1420; X86-NOBMI-NEXT: pushl %ebx 1421; X86-NOBMI-NEXT: pushl %edi 1422; X86-NOBMI-NEXT: pushl %esi 1423; X86-NOBMI-NEXT: subl $12, %esp 1424; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 1425; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ebx 1426; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 1427; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 1428; X86-NOBMI-NEXT: movl %esi, %ebp 1429; X86-NOBMI-NEXT: movl %eax, %ecx 1430; X86-NOBMI-NEXT: shrl %cl, %ebp 1431; X86-NOBMI-NEXT: shrdl %cl, %esi, %ebx 1432; X86-NOBMI-NEXT: testb $32, %al 1433; X86-NOBMI-NEXT: je .LBB13_2 1434; X86-NOBMI-NEXT: # %bb.1: 1435; X86-NOBMI-NEXT: movl %ebp, %ebx 1436; X86-NOBMI-NEXT: xorl %ebp, %ebp 1437; X86-NOBMI-NEXT: .LBB13_2: 1438; X86-NOBMI-NEXT: movl $1, %esi 1439; X86-NOBMI-NEXT: xorl %edi, %edi 1440; X86-NOBMI-NEXT: movl %edx, %ecx 1441; X86-NOBMI-NEXT: shldl %cl, %esi, %edi 1442; X86-NOBMI-NEXT: shll %cl, %esi 1443; X86-NOBMI-NEXT: testb $32, %dl 1444; X86-NOBMI-NEXT: je .LBB13_4 1445; X86-NOBMI-NEXT: # %bb.3: 1446; X86-NOBMI-NEXT: movl %esi, %edi 1447; X86-NOBMI-NEXT: xorl %esi, %esi 1448; X86-NOBMI-NEXT: .LBB13_4: 1449; X86-NOBMI-NEXT: addl $-1, %esi 1450; X86-NOBMI-NEXT: adcl $-1, %edi 1451; X86-NOBMI-NEXT: andl %ebx, %esi 1452; X86-NOBMI-NEXT: andl %ebp, %edi 1453; X86-NOBMI-NEXT: subl $8, %esp 1454; X86-NOBMI-NEXT: pushl {{[0-9]+}}(%esp) 1455; X86-NOBMI-NEXT: pushl %eax 1456; X86-NOBMI-NEXT: calll use64@PLT 1457; X86-NOBMI-NEXT: addl $16, %esp 1458; X86-NOBMI-NEXT: movl %esi, %eax 1459; X86-NOBMI-NEXT: movl %edi, %edx 1460; X86-NOBMI-NEXT: addl $12, %esp 1461; X86-NOBMI-NEXT: popl %esi 1462; X86-NOBMI-NEXT: popl %edi 1463; X86-NOBMI-NEXT: popl %ebx 1464; X86-NOBMI-NEXT: popl %ebp 1465; X86-NOBMI-NEXT: retl 1466; 1467; X86-BMI1-LABEL: bextr64_a5_skipextrauses: 1468; X86-BMI1: # %bb.0: 1469; X86-BMI1-NEXT: pushl %ebp 1470; X86-BMI1-NEXT: pushl %ebx 1471; X86-BMI1-NEXT: pushl %edi 1472; X86-BMI1-NEXT: pushl %esi 1473; X86-BMI1-NEXT: subl $12, %esp 1474; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 1475; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %ebx 1476; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 1477; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 1478; X86-BMI1-NEXT: movl %esi, %ebp 1479; X86-BMI1-NEXT: movl %eax, %ecx 1480; X86-BMI1-NEXT: shrl %cl, %ebp 1481; X86-BMI1-NEXT: shrdl %cl, %esi, %ebx 1482; X86-BMI1-NEXT: testb $32, %al 1483; X86-BMI1-NEXT: je .LBB13_2 1484; X86-BMI1-NEXT: # %bb.1: 1485; X86-BMI1-NEXT: movl %ebp, %ebx 1486; X86-BMI1-NEXT: xorl %ebp, %ebp 1487; X86-BMI1-NEXT: .LBB13_2: 1488; X86-BMI1-NEXT: movl $1, %esi 1489; X86-BMI1-NEXT: xorl %edi, %edi 1490; X86-BMI1-NEXT: movl %edx, %ecx 1491; X86-BMI1-NEXT: shldl %cl, %esi, %edi 1492; X86-BMI1-NEXT: shll %cl, %esi 1493; X86-BMI1-NEXT: testb $32, %dl 1494; X86-BMI1-NEXT: je .LBB13_4 1495; X86-BMI1-NEXT: # %bb.3: 1496; X86-BMI1-NEXT: movl %esi, %edi 1497; X86-BMI1-NEXT: xorl %esi, %esi 1498; X86-BMI1-NEXT: .LBB13_4: 1499; X86-BMI1-NEXT: addl $-1, %esi 1500; X86-BMI1-NEXT: adcl $-1, %edi 1501; X86-BMI1-NEXT: andl %ebx, %esi 1502; X86-BMI1-NEXT: andl %ebp, %edi 1503; X86-BMI1-NEXT: subl $8, %esp 1504; X86-BMI1-NEXT: pushl {{[0-9]+}}(%esp) 1505; X86-BMI1-NEXT: pushl %eax 1506; X86-BMI1-NEXT: calll use64@PLT 1507; X86-BMI1-NEXT: addl $16, %esp 1508; X86-BMI1-NEXT: movl %esi, %eax 1509; X86-BMI1-NEXT: movl %edi, %edx 1510; X86-BMI1-NEXT: addl $12, %esp 1511; X86-BMI1-NEXT: popl %esi 1512; X86-BMI1-NEXT: popl %edi 1513; X86-BMI1-NEXT: popl %ebx 1514; X86-BMI1-NEXT: popl %ebp 1515; X86-BMI1-NEXT: retl 1516; 1517; X86-BMI2-LABEL: bextr64_a5_skipextrauses: 1518; X86-BMI2: # %bb.0: 1519; X86-BMI2-NEXT: pushl %ebp 1520; X86-BMI2-NEXT: pushl %ebx 1521; X86-BMI2-NEXT: pushl %edi 1522; X86-BMI2-NEXT: pushl %esi 1523; X86-BMI2-NEXT: subl $12, %esp 1524; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %edx 1525; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ebx 1526; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 1527; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1528; X86-BMI2-NEXT: movl %eax, %ecx 1529; X86-BMI2-NEXT: shrdl %cl, %esi, %ebx 1530; X86-BMI2-NEXT: shrxl %eax, %esi, %ebp 1531; X86-BMI2-NEXT: testb $32, %al 1532; X86-BMI2-NEXT: je .LBB13_2 1533; X86-BMI2-NEXT: # %bb.1: 1534; X86-BMI2-NEXT: movl %ebp, %ebx 1535; X86-BMI2-NEXT: xorl %ebp, %ebp 1536; X86-BMI2-NEXT: .LBB13_2: 1537; X86-BMI2-NEXT: movl $1, %edi 1538; X86-BMI2-NEXT: xorl %esi, %esi 1539; X86-BMI2-NEXT: movl %edx, %ecx 1540; X86-BMI2-NEXT: shldl %cl, %edi, %esi 1541; X86-BMI2-NEXT: shlxl %edx, %edi, %edi 1542; X86-BMI2-NEXT: testb $32, %dl 1543; X86-BMI2-NEXT: je .LBB13_4 1544; X86-BMI2-NEXT: # %bb.3: 1545; X86-BMI2-NEXT: movl %edi, %esi 1546; X86-BMI2-NEXT: xorl %edi, %edi 1547; X86-BMI2-NEXT: .LBB13_4: 1548; X86-BMI2-NEXT: addl $-1, %edi 1549; X86-BMI2-NEXT: adcl $-1, %esi 1550; X86-BMI2-NEXT: andl %ebx, %edi 1551; X86-BMI2-NEXT: andl %ebp, %esi 1552; X86-BMI2-NEXT: subl $8, %esp 1553; X86-BMI2-NEXT: pushl {{[0-9]+}}(%esp) 1554; X86-BMI2-NEXT: pushl %eax 1555; X86-BMI2-NEXT: calll use64@PLT 1556; X86-BMI2-NEXT: addl $16, %esp 1557; X86-BMI2-NEXT: movl %edi, %eax 1558; X86-BMI2-NEXT: movl %esi, %edx 1559; X86-BMI2-NEXT: addl $12, %esp 1560; X86-BMI2-NEXT: popl %esi 1561; X86-BMI2-NEXT: popl %edi 1562; X86-BMI2-NEXT: popl %ebx 1563; X86-BMI2-NEXT: popl %ebp 1564; X86-BMI2-NEXT: retl 1565; 1566; X64-NOBMI-LABEL: bextr64_a5_skipextrauses: 1567; X64-NOBMI: # %bb.0: 1568; X64-NOBMI-NEXT: pushq %rbx 1569; X64-NOBMI-NEXT: movl %esi, %ecx 1570; X64-NOBMI-NEXT: shrq %cl, %rdi 1571; X64-NOBMI-NEXT: movl $1, %ebx 1572; X64-NOBMI-NEXT: movl %edx, %ecx 1573; X64-NOBMI-NEXT: shlq %cl, %rbx 1574; X64-NOBMI-NEXT: decq %rbx 1575; X64-NOBMI-NEXT: andq %rdi, %rbx 1576; X64-NOBMI-NEXT: movq %rsi, %rdi 1577; X64-NOBMI-NEXT: callq use64@PLT 1578; X64-NOBMI-NEXT: movq %rbx, %rax 1579; X64-NOBMI-NEXT: popq %rbx 1580; X64-NOBMI-NEXT: retq 1581; 1582; X64-BMI1-LABEL: bextr64_a5_skipextrauses: 1583; X64-BMI1: # %bb.0: 1584; X64-BMI1-NEXT: pushq %rbx 1585; X64-BMI1-NEXT: shll $8, %edx 1586; X64-BMI1-NEXT: movzbl %sil, %eax 1587; X64-BMI1-NEXT: orl %edx, %eax 1588; X64-BMI1-NEXT: bextrq %rax, %rdi, %rbx 1589; X64-BMI1-NEXT: movq %rsi, %rdi 1590; X64-BMI1-NEXT: callq use64@PLT 1591; X64-BMI1-NEXT: movq %rbx, %rax 1592; X64-BMI1-NEXT: popq %rbx 1593; X64-BMI1-NEXT: retq 1594; 1595; X64-BMI2-LABEL: bextr64_a5_skipextrauses: 1596; X64-BMI2: # %bb.0: 1597; X64-BMI2-NEXT: pushq %rbx 1598; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 1599; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rbx 1600; X64-BMI2-NEXT: movq %rsi, %rdi 1601; X64-BMI2-NEXT: callq use64@PLT 1602; X64-BMI2-NEXT: movq %rbx, %rax 1603; X64-BMI2-NEXT: popq %rbx 1604; X64-BMI2-NEXT: retq 1605 %shifted = lshr i64 %val, %numskipbits 1606 %onebit = shl i64 1, %numlowbits 1607 %mask = add nsw i64 %onebit, -1 1608 %masked = and i64 %mask, %shifted 1609 call void @use64(i64 %numskipbits) 1610 ret i64 %masked 1611} 1612 1613; 64-bit, but with 32-bit output 1614 1615; Everything done in 64-bit, truncation happens last. 1616define i32 @bextr64_32_a0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 1617; X86-NOBMI-LABEL: bextr64_32_a0: 1618; X86-NOBMI: # %bb.0: 1619; X86-NOBMI-NEXT: pushl %edi 1620; X86-NOBMI-NEXT: pushl %esi 1621; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 1622; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1623; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 1624; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 1625; X86-NOBMI-NEXT: movl %edi, %esi 1626; X86-NOBMI-NEXT: shrl %cl, %esi 1627; X86-NOBMI-NEXT: shrdl %cl, %edi, %eax 1628; X86-NOBMI-NEXT: testb $32, %cl 1629; X86-NOBMI-NEXT: jne .LBB14_2 1630; X86-NOBMI-NEXT: # %bb.1: 1631; X86-NOBMI-NEXT: movl %eax, %esi 1632; X86-NOBMI-NEXT: .LBB14_2: 1633; X86-NOBMI-NEXT: movl $1, %edi 1634; X86-NOBMI-NEXT: movl %edx, %ecx 1635; X86-NOBMI-NEXT: shll %cl, %edi 1636; X86-NOBMI-NEXT: xorl %eax, %eax 1637; X86-NOBMI-NEXT: testb $32, %dl 1638; X86-NOBMI-NEXT: jne .LBB14_4 1639; X86-NOBMI-NEXT: # %bb.3: 1640; X86-NOBMI-NEXT: movl %edi, %eax 1641; X86-NOBMI-NEXT: .LBB14_4: 1642; X86-NOBMI-NEXT: decl %eax 1643; X86-NOBMI-NEXT: andl %esi, %eax 1644; X86-NOBMI-NEXT: popl %esi 1645; X86-NOBMI-NEXT: popl %edi 1646; X86-NOBMI-NEXT: retl 1647; 1648; X86-BMI1-LABEL: bextr64_32_a0: 1649; X86-BMI1: # %bb.0: 1650; X86-BMI1-NEXT: pushl %edi 1651; X86-BMI1-NEXT: pushl %esi 1652; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 1653; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1654; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 1655; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 1656; X86-BMI1-NEXT: movl %edi, %esi 1657; X86-BMI1-NEXT: shrl %cl, %esi 1658; X86-BMI1-NEXT: shrdl %cl, %edi, %eax 1659; X86-BMI1-NEXT: testb $32, %cl 1660; X86-BMI1-NEXT: jne .LBB14_2 1661; X86-BMI1-NEXT: # %bb.1: 1662; X86-BMI1-NEXT: movl %eax, %esi 1663; X86-BMI1-NEXT: .LBB14_2: 1664; X86-BMI1-NEXT: movl $1, %edi 1665; X86-BMI1-NEXT: movl %edx, %ecx 1666; X86-BMI1-NEXT: shll %cl, %edi 1667; X86-BMI1-NEXT: xorl %eax, %eax 1668; X86-BMI1-NEXT: testb $32, %dl 1669; X86-BMI1-NEXT: jne .LBB14_4 1670; X86-BMI1-NEXT: # %bb.3: 1671; X86-BMI1-NEXT: movl %edi, %eax 1672; X86-BMI1-NEXT: .LBB14_4: 1673; X86-BMI1-NEXT: decl %eax 1674; X86-BMI1-NEXT: andl %esi, %eax 1675; X86-BMI1-NEXT: popl %esi 1676; X86-BMI1-NEXT: popl %edi 1677; X86-BMI1-NEXT: retl 1678; 1679; X86-BMI2-LABEL: bextr64_32_a0: 1680; X86-BMI2: # %bb.0: 1681; X86-BMI2-NEXT: pushl %ebx 1682; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 1683; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1684; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 1685; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1686; X86-BMI2-NEXT: shrdl %cl, %eax, %edx 1687; X86-BMI2-NEXT: testb $32, %cl 1688; X86-BMI2-NEXT: je .LBB14_2 1689; X86-BMI2-NEXT: # %bb.1: 1690; X86-BMI2-NEXT: shrxl %ecx, %eax, %edx 1691; X86-BMI2-NEXT: .LBB14_2: 1692; X86-BMI2-NEXT: xorl %eax, %eax 1693; X86-BMI2-NEXT: testb $32, %bl 1694; X86-BMI2-NEXT: jne .LBB14_4 1695; X86-BMI2-NEXT: # %bb.3: 1696; X86-BMI2-NEXT: movl $1, %eax 1697; X86-BMI2-NEXT: shlxl %ebx, %eax, %eax 1698; X86-BMI2-NEXT: .LBB14_4: 1699; X86-BMI2-NEXT: decl %eax 1700; X86-BMI2-NEXT: andl %edx, %eax 1701; X86-BMI2-NEXT: popl %ebx 1702; X86-BMI2-NEXT: retl 1703; 1704; X64-NOBMI-LABEL: bextr64_32_a0: 1705; X64-NOBMI: # %bb.0: 1706; X64-NOBMI-NEXT: movq %rsi, %rcx 1707; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 1708; X64-NOBMI-NEXT: shrq %cl, %rdi 1709; X64-NOBMI-NEXT: movl $1, %eax 1710; X64-NOBMI-NEXT: movl %edx, %ecx 1711; X64-NOBMI-NEXT: shlq %cl, %rax 1712; X64-NOBMI-NEXT: decl %eax 1713; X64-NOBMI-NEXT: andl %edi, %eax 1714; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 1715; X64-NOBMI-NEXT: retq 1716; 1717; X64-BMI1-LABEL: bextr64_32_a0: 1718; X64-BMI1: # %bb.0: 1719; X64-BMI1-NEXT: shll $8, %edx 1720; X64-BMI1-NEXT: movzbl %sil, %eax 1721; X64-BMI1-NEXT: orl %edx, %eax 1722; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 1723; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 1724; X64-BMI1-NEXT: retq 1725; 1726; X64-BMI2-LABEL: bextr64_32_a0: 1727; X64-BMI2: # %bb.0: 1728; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 1729; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 1730; X64-BMI2-NEXT: retq 1731 %shifted = lshr i64 %val, %numskipbits 1732 %onebit = shl i64 1, %numlowbits 1733 %mask = add nsw i64 %onebit, -1 1734 %masked = and i64 %mask, %shifted 1735 %res = trunc i64 %masked to i32 1736 ret i32 %res 1737} 1738 1739; Shifting happens in 64-bit, then truncation. Masking is 32-bit. 1740define i32 @bextr64_32_a1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind { 1741; X86-NOBMI-LABEL: bextr64_32_a1: 1742; X86-NOBMI: # %bb.0: 1743; X86-NOBMI-NEXT: pushl %edi 1744; X86-NOBMI-NEXT: pushl %esi 1745; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 1746; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1747; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 1748; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 1749; X86-NOBMI-NEXT: movl %edi, %esi 1750; X86-NOBMI-NEXT: shrl %cl, %esi 1751; X86-NOBMI-NEXT: shrdl %cl, %edi, %eax 1752; X86-NOBMI-NEXT: testb $32, %cl 1753; X86-NOBMI-NEXT: jne .LBB15_2 1754; X86-NOBMI-NEXT: # %bb.1: 1755; X86-NOBMI-NEXT: movl %eax, %esi 1756; X86-NOBMI-NEXT: .LBB15_2: 1757; X86-NOBMI-NEXT: movl $1, %eax 1758; X86-NOBMI-NEXT: movl %edx, %ecx 1759; X86-NOBMI-NEXT: shll %cl, %eax 1760; X86-NOBMI-NEXT: decl %eax 1761; X86-NOBMI-NEXT: andl %esi, %eax 1762; X86-NOBMI-NEXT: popl %esi 1763; X86-NOBMI-NEXT: popl %edi 1764; X86-NOBMI-NEXT: retl 1765; 1766; X86-BMI1-LABEL: bextr64_32_a1: 1767; X86-BMI1: # %bb.0: 1768; X86-BMI1-NEXT: pushl %edi 1769; X86-BMI1-NEXT: pushl %esi 1770; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 1771; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1772; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 1773; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 1774; X86-BMI1-NEXT: movl %edi, %edx 1775; X86-BMI1-NEXT: shrl %cl, %edx 1776; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 1777; X86-BMI1-NEXT: testb $32, %cl 1778; X86-BMI1-NEXT: jne .LBB15_2 1779; X86-BMI1-NEXT: # %bb.1: 1780; X86-BMI1-NEXT: movl %esi, %edx 1781; X86-BMI1-NEXT: .LBB15_2: 1782; X86-BMI1-NEXT: shll $8, %eax 1783; X86-BMI1-NEXT: bextrl %eax, %edx, %eax 1784; X86-BMI1-NEXT: popl %esi 1785; X86-BMI1-NEXT: popl %edi 1786; X86-BMI1-NEXT: retl 1787; 1788; X86-BMI2-LABEL: bextr64_32_a1: 1789; X86-BMI2: # %bb.0: 1790; X86-BMI2-NEXT: pushl %esi 1791; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 1792; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1793; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 1794; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 1795; X86-BMI2-NEXT: shrdl %cl, %esi, %edx 1796; X86-BMI2-NEXT: testb $32, %cl 1797; X86-BMI2-NEXT: je .LBB15_2 1798; X86-BMI2-NEXT: # %bb.1: 1799; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 1800; X86-BMI2-NEXT: .LBB15_2: 1801; X86-BMI2-NEXT: bzhil %eax, %edx, %eax 1802; X86-BMI2-NEXT: popl %esi 1803; X86-BMI2-NEXT: retl 1804; 1805; X64-NOBMI-LABEL: bextr64_32_a1: 1806; X64-NOBMI: # %bb.0: 1807; X64-NOBMI-NEXT: movq %rsi, %rcx 1808; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 1809; X64-NOBMI-NEXT: shrq %cl, %rdi 1810; X64-NOBMI-NEXT: movl $1, %eax 1811; X64-NOBMI-NEXT: movl %edx, %ecx 1812; X64-NOBMI-NEXT: shll %cl, %eax 1813; X64-NOBMI-NEXT: decl %eax 1814; X64-NOBMI-NEXT: andl %edi, %eax 1815; X64-NOBMI-NEXT: retq 1816; 1817; X64-BMI1-LABEL: bextr64_32_a1: 1818; X64-BMI1: # %bb.0: 1819; X64-BMI1-NEXT: shll $8, %edx 1820; X64-BMI1-NEXT: movzbl %sil, %eax 1821; X64-BMI1-NEXT: orl %edx, %eax 1822; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 1823; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 1824; X64-BMI1-NEXT: retq 1825; 1826; X64-BMI2-LABEL: bextr64_32_a1: 1827; X64-BMI2: # %bb.0: 1828; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 1829; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 1830; X64-BMI2-NEXT: retq 1831 %shifted = lshr i64 %val, %numskipbits 1832 %truncshifted = trunc i64 %shifted to i32 1833 %onebit = shl i32 1, %numlowbits 1834 %mask = add nsw i32 %onebit, -1 1835 %masked = and i32 %mask, %truncshifted 1836 ret i32 %masked 1837} 1838 1839; Shifting happens in 64-bit, then truncation (with extra use). 1840; Masking is 32-bit. 1841define i32 @bextr64_32_a1_trunc_extrause(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind { 1842; X86-NOBMI-LABEL: bextr64_32_a1_trunc_extrause: 1843; X86-NOBMI: # %bb.0: 1844; X86-NOBMI-NEXT: pushl %ebx 1845; X86-NOBMI-NEXT: pushl %esi 1846; X86-NOBMI-NEXT: pushl %eax 1847; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 1848; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1849; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 1850; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 1851; X86-NOBMI-NEXT: movl %edx, %esi 1852; X86-NOBMI-NEXT: shrl %cl, %esi 1853; X86-NOBMI-NEXT: shrdl %cl, %edx, %eax 1854; X86-NOBMI-NEXT: testb $32, %cl 1855; X86-NOBMI-NEXT: jne .LBB16_2 1856; X86-NOBMI-NEXT: # %bb.1: 1857; X86-NOBMI-NEXT: movl %eax, %esi 1858; X86-NOBMI-NEXT: .LBB16_2: 1859; X86-NOBMI-NEXT: movl %esi, (%esp) 1860; X86-NOBMI-NEXT: calll use32@PLT 1861; X86-NOBMI-NEXT: movl $1, %eax 1862; X86-NOBMI-NEXT: movl %ebx, %ecx 1863; X86-NOBMI-NEXT: shll %cl, %eax 1864; X86-NOBMI-NEXT: decl %eax 1865; X86-NOBMI-NEXT: andl %esi, %eax 1866; X86-NOBMI-NEXT: addl $4, %esp 1867; X86-NOBMI-NEXT: popl %esi 1868; X86-NOBMI-NEXT: popl %ebx 1869; X86-NOBMI-NEXT: retl 1870; 1871; X86-BMI1-LABEL: bextr64_32_a1_trunc_extrause: 1872; X86-BMI1: # %bb.0: 1873; X86-BMI1-NEXT: pushl %ebx 1874; X86-BMI1-NEXT: pushl %esi 1875; X86-BMI1-NEXT: pushl %eax 1876; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 1877; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1878; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 1879; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edx 1880; X86-BMI1-NEXT: movl %edx, %esi 1881; X86-BMI1-NEXT: shrl %cl, %esi 1882; X86-BMI1-NEXT: shrdl %cl, %edx, %eax 1883; X86-BMI1-NEXT: testb $32, %cl 1884; X86-BMI1-NEXT: jne .LBB16_2 1885; X86-BMI1-NEXT: # %bb.1: 1886; X86-BMI1-NEXT: movl %eax, %esi 1887; X86-BMI1-NEXT: .LBB16_2: 1888; X86-BMI1-NEXT: movl %esi, (%esp) 1889; X86-BMI1-NEXT: calll use32@PLT 1890; X86-BMI1-NEXT: shll $8, %ebx 1891; X86-BMI1-NEXT: bextrl %ebx, %esi, %eax 1892; X86-BMI1-NEXT: addl $4, %esp 1893; X86-BMI1-NEXT: popl %esi 1894; X86-BMI1-NEXT: popl %ebx 1895; X86-BMI1-NEXT: retl 1896; 1897; X86-BMI2-LABEL: bextr64_32_a1_trunc_extrause: 1898; X86-BMI2: # %bb.0: 1899; X86-BMI2-NEXT: pushl %ebx 1900; X86-BMI2-NEXT: pushl %esi 1901; X86-BMI2-NEXT: pushl %eax 1902; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 1903; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1904; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 1905; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1906; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 1907; X86-BMI2-NEXT: testb $32, %cl 1908; X86-BMI2-NEXT: je .LBB16_2 1909; X86-BMI2-NEXT: # %bb.1: 1910; X86-BMI2-NEXT: shrxl %ecx, %eax, %esi 1911; X86-BMI2-NEXT: .LBB16_2: 1912; X86-BMI2-NEXT: movl %esi, (%esp) 1913; X86-BMI2-NEXT: calll use32@PLT 1914; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax 1915; X86-BMI2-NEXT: addl $4, %esp 1916; X86-BMI2-NEXT: popl %esi 1917; X86-BMI2-NEXT: popl %ebx 1918; X86-BMI2-NEXT: retl 1919; 1920; X64-NOBMI-LABEL: bextr64_32_a1_trunc_extrause: 1921; X64-NOBMI: # %bb.0: 1922; X64-NOBMI-NEXT: pushq %r14 1923; X64-NOBMI-NEXT: pushq %rbx 1924; X64-NOBMI-NEXT: pushq %rax 1925; X64-NOBMI-NEXT: movl %edx, %ebx 1926; X64-NOBMI-NEXT: movq %rsi, %rcx 1927; X64-NOBMI-NEXT: movq %rdi, %r14 1928; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 1929; X64-NOBMI-NEXT: shrq %cl, %r14 1930; X64-NOBMI-NEXT: movl %r14d, %edi 1931; X64-NOBMI-NEXT: callq use32@PLT 1932; X64-NOBMI-NEXT: movl $1, %eax 1933; X64-NOBMI-NEXT: movl %ebx, %ecx 1934; X64-NOBMI-NEXT: shll %cl, %eax 1935; X64-NOBMI-NEXT: decl %eax 1936; X64-NOBMI-NEXT: andl %r14d, %eax 1937; X64-NOBMI-NEXT: addq $8, %rsp 1938; X64-NOBMI-NEXT: popq %rbx 1939; X64-NOBMI-NEXT: popq %r14 1940; X64-NOBMI-NEXT: retq 1941; 1942; X64-BMI1-LABEL: bextr64_32_a1_trunc_extrause: 1943; X64-BMI1: # %bb.0: 1944; X64-BMI1-NEXT: pushq %r14 1945; X64-BMI1-NEXT: pushq %rbx 1946; X64-BMI1-NEXT: pushq %rax 1947; X64-BMI1-NEXT: movl %edx, %ebx 1948; X64-BMI1-NEXT: movq %rsi, %rcx 1949; X64-BMI1-NEXT: movq %rdi, %r14 1950; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $rcx 1951; X64-BMI1-NEXT: shrq %cl, %r14 1952; X64-BMI1-NEXT: movl %r14d, %edi 1953; X64-BMI1-NEXT: callq use32@PLT 1954; X64-BMI1-NEXT: shll $8, %ebx 1955; X64-BMI1-NEXT: bextrl %ebx, %r14d, %eax 1956; X64-BMI1-NEXT: addq $8, %rsp 1957; X64-BMI1-NEXT: popq %rbx 1958; X64-BMI1-NEXT: popq %r14 1959; X64-BMI1-NEXT: retq 1960; 1961; X64-BMI2-LABEL: bextr64_32_a1_trunc_extrause: 1962; X64-BMI2: # %bb.0: 1963; X64-BMI2-NEXT: pushq %r14 1964; X64-BMI2-NEXT: pushq %rbx 1965; X64-BMI2-NEXT: pushq %rax 1966; X64-BMI2-NEXT: movl %edx, %ebx 1967; X64-BMI2-NEXT: shrxq %rsi, %rdi, %r14 1968; X64-BMI2-NEXT: movl %r14d, %edi 1969; X64-BMI2-NEXT: callq use32@PLT 1970; X64-BMI2-NEXT: bzhil %ebx, %r14d, %eax 1971; X64-BMI2-NEXT: addq $8, %rsp 1972; X64-BMI2-NEXT: popq %rbx 1973; X64-BMI2-NEXT: popq %r14 1974; X64-BMI2-NEXT: retq 1975 %shifted = lshr i64 %val, %numskipbits 1976 %truncshifted = trunc i64 %shifted to i32 1977 call void @use32(i32 %truncshifted) 1978 %onebit = shl i32 1, %numlowbits 1979 %mask = add nsw i32 %onebit, -1 1980 %masked = and i32 %mask, %truncshifted 1981 ret i32 %masked 1982} 1983 1984; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit. 1985; Masking is 64-bit. Then truncation. 1986define i32 @bextr64_32_a2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind { 1987; X86-NOBMI-LABEL: bextr64_32_a2: 1988; X86-NOBMI: # %bb.0: 1989; X86-NOBMI-NEXT: pushl %edi 1990; X86-NOBMI-NEXT: pushl %esi 1991; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 1992; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 1993; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 1994; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 1995; X86-NOBMI-NEXT: movl %edi, %esi 1996; X86-NOBMI-NEXT: shrl %cl, %esi 1997; X86-NOBMI-NEXT: shrdl %cl, %edi, %eax 1998; X86-NOBMI-NEXT: testb $32, %cl 1999; X86-NOBMI-NEXT: jne .LBB17_2 2000; X86-NOBMI-NEXT: # %bb.1: 2001; X86-NOBMI-NEXT: movl %eax, %esi 2002; X86-NOBMI-NEXT: .LBB17_2: 2003; X86-NOBMI-NEXT: movl $1, %eax 2004; X86-NOBMI-NEXT: movl %edx, %ecx 2005; X86-NOBMI-NEXT: shll %cl, %eax 2006; X86-NOBMI-NEXT: decl %eax 2007; X86-NOBMI-NEXT: andl %esi, %eax 2008; X86-NOBMI-NEXT: popl %esi 2009; X86-NOBMI-NEXT: popl %edi 2010; X86-NOBMI-NEXT: retl 2011; 2012; X86-BMI1-LABEL: bextr64_32_a2: 2013; X86-BMI1: # %bb.0: 2014; X86-BMI1-NEXT: pushl %edi 2015; X86-BMI1-NEXT: pushl %esi 2016; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2017; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2018; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 2019; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 2020; X86-BMI1-NEXT: movl %edi, %edx 2021; X86-BMI1-NEXT: shrl %cl, %edx 2022; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 2023; X86-BMI1-NEXT: testb $32, %cl 2024; X86-BMI1-NEXT: jne .LBB17_2 2025; X86-BMI1-NEXT: # %bb.1: 2026; X86-BMI1-NEXT: movl %esi, %edx 2027; X86-BMI1-NEXT: .LBB17_2: 2028; X86-BMI1-NEXT: shll $8, %eax 2029; X86-BMI1-NEXT: bextrl %eax, %edx, %eax 2030; X86-BMI1-NEXT: popl %esi 2031; X86-BMI1-NEXT: popl %edi 2032; X86-BMI1-NEXT: retl 2033; 2034; X86-BMI2-LABEL: bextr64_32_a2: 2035; X86-BMI2: # %bb.0: 2036; X86-BMI2-NEXT: pushl %esi 2037; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2038; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2039; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 2040; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 2041; X86-BMI2-NEXT: shrdl %cl, %esi, %edx 2042; X86-BMI2-NEXT: testb $32, %cl 2043; X86-BMI2-NEXT: je .LBB17_2 2044; X86-BMI2-NEXT: # %bb.1: 2045; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 2046; X86-BMI2-NEXT: .LBB17_2: 2047; X86-BMI2-NEXT: bzhil %eax, %edx, %eax 2048; X86-BMI2-NEXT: popl %esi 2049; X86-BMI2-NEXT: retl 2050; 2051; X64-NOBMI-LABEL: bextr64_32_a2: 2052; X64-NOBMI: # %bb.0: 2053; X64-NOBMI-NEXT: movq %rsi, %rcx 2054; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 2055; X64-NOBMI-NEXT: shrq %cl, %rdi 2056; X64-NOBMI-NEXT: movl $1, %eax 2057; X64-NOBMI-NEXT: movl %edx, %ecx 2058; X64-NOBMI-NEXT: shll %cl, %eax 2059; X64-NOBMI-NEXT: decl %eax 2060; X64-NOBMI-NEXT: andl %edi, %eax 2061; X64-NOBMI-NEXT: retq 2062; 2063; X64-BMI1-LABEL: bextr64_32_a2: 2064; X64-BMI1: # %bb.0: 2065; X64-BMI1-NEXT: shll $8, %edx 2066; X64-BMI1-NEXT: movzbl %sil, %eax 2067; X64-BMI1-NEXT: orl %edx, %eax 2068; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 2069; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 2070; X64-BMI1-NEXT: retq 2071; 2072; X64-BMI2-LABEL: bextr64_32_a2: 2073; X64-BMI2: # %bb.0: 2074; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 2075; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 2076; X64-BMI2-NEXT: retq 2077 %shifted = lshr i64 %val, %numskipbits 2078 %onebit = shl i32 1, %numlowbits 2079 %mask = add nsw i32 %onebit, -1 2080 %zextmask = zext i32 %mask to i64 2081 %masked = and i64 %zextmask, %shifted 2082 %truncmasked = trunc i64 %masked to i32 2083 ret i32 %truncmasked 2084} 2085 2086; Shifting happens in 64-bit. Mask is 32-bit, but calculated in 64-bit. 2087; Masking is 64-bit. Then truncation. 2088define i32 @bextr64_32_a3(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 2089; X86-NOBMI-LABEL: bextr64_32_a3: 2090; X86-NOBMI: # %bb.0: 2091; X86-NOBMI-NEXT: pushl %edi 2092; X86-NOBMI-NEXT: pushl %esi 2093; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2094; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2095; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2096; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 2097; X86-NOBMI-NEXT: movl %edi, %esi 2098; X86-NOBMI-NEXT: shrl %cl, %esi 2099; X86-NOBMI-NEXT: shrdl %cl, %edi, %eax 2100; X86-NOBMI-NEXT: testb $32, %cl 2101; X86-NOBMI-NEXT: jne .LBB18_2 2102; X86-NOBMI-NEXT: # %bb.1: 2103; X86-NOBMI-NEXT: movl %eax, %esi 2104; X86-NOBMI-NEXT: .LBB18_2: 2105; X86-NOBMI-NEXT: movl $1, %edi 2106; X86-NOBMI-NEXT: movl %edx, %ecx 2107; X86-NOBMI-NEXT: shll %cl, %edi 2108; X86-NOBMI-NEXT: xorl %eax, %eax 2109; X86-NOBMI-NEXT: testb $32, %dl 2110; X86-NOBMI-NEXT: jne .LBB18_4 2111; X86-NOBMI-NEXT: # %bb.3: 2112; X86-NOBMI-NEXT: movl %edi, %eax 2113; X86-NOBMI-NEXT: .LBB18_4: 2114; X86-NOBMI-NEXT: decl %eax 2115; X86-NOBMI-NEXT: andl %esi, %eax 2116; X86-NOBMI-NEXT: popl %esi 2117; X86-NOBMI-NEXT: popl %edi 2118; X86-NOBMI-NEXT: retl 2119; 2120; X86-BMI1-LABEL: bextr64_32_a3: 2121; X86-BMI1: # %bb.0: 2122; X86-BMI1-NEXT: pushl %edi 2123; X86-BMI1-NEXT: pushl %esi 2124; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2125; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2126; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 2127; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 2128; X86-BMI1-NEXT: movl %edi, %esi 2129; X86-BMI1-NEXT: shrl %cl, %esi 2130; X86-BMI1-NEXT: shrdl %cl, %edi, %eax 2131; X86-BMI1-NEXT: testb $32, %cl 2132; X86-BMI1-NEXT: jne .LBB18_2 2133; X86-BMI1-NEXT: # %bb.1: 2134; X86-BMI1-NEXT: movl %eax, %esi 2135; X86-BMI1-NEXT: .LBB18_2: 2136; X86-BMI1-NEXT: movl $1, %edi 2137; X86-BMI1-NEXT: movl %edx, %ecx 2138; X86-BMI1-NEXT: shll %cl, %edi 2139; X86-BMI1-NEXT: xorl %eax, %eax 2140; X86-BMI1-NEXT: testb $32, %dl 2141; X86-BMI1-NEXT: jne .LBB18_4 2142; X86-BMI1-NEXT: # %bb.3: 2143; X86-BMI1-NEXT: movl %edi, %eax 2144; X86-BMI1-NEXT: .LBB18_4: 2145; X86-BMI1-NEXT: decl %eax 2146; X86-BMI1-NEXT: andl %esi, %eax 2147; X86-BMI1-NEXT: popl %esi 2148; X86-BMI1-NEXT: popl %edi 2149; X86-BMI1-NEXT: retl 2150; 2151; X86-BMI2-LABEL: bextr64_32_a3: 2152; X86-BMI2: # %bb.0: 2153; X86-BMI2-NEXT: pushl %ebx 2154; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 2155; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2156; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 2157; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 2158; X86-BMI2-NEXT: shrdl %cl, %eax, %edx 2159; X86-BMI2-NEXT: testb $32, %cl 2160; X86-BMI2-NEXT: je .LBB18_2 2161; X86-BMI2-NEXT: # %bb.1: 2162; X86-BMI2-NEXT: shrxl %ecx, %eax, %edx 2163; X86-BMI2-NEXT: .LBB18_2: 2164; X86-BMI2-NEXT: xorl %eax, %eax 2165; X86-BMI2-NEXT: testb $32, %bl 2166; X86-BMI2-NEXT: jne .LBB18_4 2167; X86-BMI2-NEXT: # %bb.3: 2168; X86-BMI2-NEXT: movl $1, %eax 2169; X86-BMI2-NEXT: shlxl %ebx, %eax, %eax 2170; X86-BMI2-NEXT: .LBB18_4: 2171; X86-BMI2-NEXT: decl %eax 2172; X86-BMI2-NEXT: andl %edx, %eax 2173; X86-BMI2-NEXT: popl %ebx 2174; X86-BMI2-NEXT: retl 2175; 2176; X64-NOBMI-LABEL: bextr64_32_a3: 2177; X64-NOBMI: # %bb.0: 2178; X64-NOBMI-NEXT: movq %rsi, %rcx 2179; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 2180; X64-NOBMI-NEXT: shrq %cl, %rdi 2181; X64-NOBMI-NEXT: movl $1, %eax 2182; X64-NOBMI-NEXT: movl %edx, %ecx 2183; X64-NOBMI-NEXT: shlq %cl, %rax 2184; X64-NOBMI-NEXT: decl %eax 2185; X64-NOBMI-NEXT: andl %edi, %eax 2186; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 2187; X64-NOBMI-NEXT: retq 2188; 2189; X64-BMI1-LABEL: bextr64_32_a3: 2190; X64-BMI1: # %bb.0: 2191; X64-BMI1-NEXT: shll $8, %edx 2192; X64-BMI1-NEXT: movzbl %sil, %eax 2193; X64-BMI1-NEXT: orl %edx, %eax 2194; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 2195; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 2196; X64-BMI1-NEXT: retq 2197; 2198; X64-BMI2-LABEL: bextr64_32_a3: 2199; X64-BMI2: # %bb.0: 2200; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 2201; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 2202; X64-BMI2-NEXT: retq 2203 %shifted = lshr i64 %val, %numskipbits 2204 %onebit = shl i64 1, %numlowbits 2205 %mask = add nsw i64 %onebit, 4294967295 2206 %masked = and i64 %mask, %shifted 2207 %truncmasked = trunc i64 %masked to i32 2208 ret i32 %truncmasked 2209} 2210 2211; ---------------------------------------------------------------------------- ; 2212; Pattern b. 32-bit 2213; ---------------------------------------------------------------------------- ; 2214 2215define i32 @bextr32_b0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 2216; X86-NOBMI-LABEL: bextr32_b0: 2217; X86-NOBMI: # %bb.0: 2218; X86-NOBMI-NEXT: pushl %esi 2219; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2220; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2221; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 2222; X86-NOBMI-NEXT: shrl %cl, %esi 2223; X86-NOBMI-NEXT: movl $-1, %eax 2224; X86-NOBMI-NEXT: movl %edx, %ecx 2225; X86-NOBMI-NEXT: shll %cl, %eax 2226; X86-NOBMI-NEXT: notl %eax 2227; X86-NOBMI-NEXT: andl %esi, %eax 2228; X86-NOBMI-NEXT: popl %esi 2229; X86-NOBMI-NEXT: retl 2230; 2231; X86-BMI1-LABEL: bextr32_b0: 2232; X86-BMI1: # %bb.0: 2233; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2234; X86-BMI1-NEXT: shll $8, %eax 2235; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2236; X86-BMI1-NEXT: orl %eax, %ecx 2237; X86-BMI1-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %eax 2238; X86-BMI1-NEXT: retl 2239; 2240; X86-BMI2-LABEL: bextr32_b0: 2241; X86-BMI2: # %bb.0: 2242; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2243; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2244; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %ecx 2245; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 2246; X86-BMI2-NEXT: retl 2247; 2248; X64-NOBMI-LABEL: bextr32_b0: 2249; X64-NOBMI: # %bb.0: 2250; X64-NOBMI-NEXT: movl %esi, %ecx 2251; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2252; X64-NOBMI-NEXT: shrl %cl, %edi 2253; X64-NOBMI-NEXT: movl $-1, %eax 2254; X64-NOBMI-NEXT: movl %edx, %ecx 2255; X64-NOBMI-NEXT: shll %cl, %eax 2256; X64-NOBMI-NEXT: notl %eax 2257; X64-NOBMI-NEXT: andl %edi, %eax 2258; X64-NOBMI-NEXT: retq 2259; 2260; X64-BMI1-LABEL: bextr32_b0: 2261; X64-BMI1: # %bb.0: 2262; X64-BMI1-NEXT: shll $8, %edx 2263; X64-BMI1-NEXT: movzbl %sil, %eax 2264; X64-BMI1-NEXT: orl %edx, %eax 2265; X64-BMI1-NEXT: bextrl %eax, %edi, %eax 2266; X64-BMI1-NEXT: retq 2267; 2268; X64-BMI2-LABEL: bextr32_b0: 2269; X64-BMI2: # %bb.0: 2270; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 2271; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 2272; X64-BMI2-NEXT: retq 2273 %shifted = lshr i32 %val, %numskipbits 2274 %notmask = shl i32 -1, %numlowbits 2275 %mask = xor i32 %notmask, -1 2276 %masked = and i32 %mask, %shifted 2277 ret i32 %masked 2278} 2279 2280define i32 @bextr32_b1_indexzext(i32 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind { 2281; X86-NOBMI-LABEL: bextr32_b1_indexzext: 2282; X86-NOBMI: # %bb.0: 2283; X86-NOBMI-NEXT: pushl %esi 2284; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2285; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2286; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 2287; X86-NOBMI-NEXT: shrl %cl, %esi 2288; X86-NOBMI-NEXT: movl $-1, %eax 2289; X86-NOBMI-NEXT: movl %edx, %ecx 2290; X86-NOBMI-NEXT: shll %cl, %eax 2291; X86-NOBMI-NEXT: notl %eax 2292; X86-NOBMI-NEXT: andl %esi, %eax 2293; X86-NOBMI-NEXT: popl %esi 2294; X86-NOBMI-NEXT: retl 2295; 2296; X86-BMI1-LABEL: bextr32_b1_indexzext: 2297; X86-BMI1: # %bb.0: 2298; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2299; X86-BMI1-NEXT: shll $8, %eax 2300; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2301; X86-BMI1-NEXT: orl %eax, %ecx 2302; X86-BMI1-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %eax 2303; X86-BMI1-NEXT: retl 2304; 2305; X86-BMI2-LABEL: bextr32_b1_indexzext: 2306; X86-BMI2: # %bb.0: 2307; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2308; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2309; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %ecx 2310; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 2311; X86-BMI2-NEXT: retl 2312; 2313; X64-NOBMI-LABEL: bextr32_b1_indexzext: 2314; X64-NOBMI: # %bb.0: 2315; X64-NOBMI-NEXT: movl %esi, %ecx 2316; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2317; X64-NOBMI-NEXT: shrl %cl, %edi 2318; X64-NOBMI-NEXT: movl $-1, %eax 2319; X64-NOBMI-NEXT: movl %edx, %ecx 2320; X64-NOBMI-NEXT: shll %cl, %eax 2321; X64-NOBMI-NEXT: notl %eax 2322; X64-NOBMI-NEXT: andl %edi, %eax 2323; X64-NOBMI-NEXT: retq 2324; 2325; X64-BMI1-LABEL: bextr32_b1_indexzext: 2326; X64-BMI1: # %bb.0: 2327; X64-BMI1-NEXT: shll $8, %edx 2328; X64-BMI1-NEXT: orl %esi, %edx 2329; X64-BMI1-NEXT: bextrl %edx, %edi, %eax 2330; X64-BMI1-NEXT: retq 2331; 2332; X64-BMI2-LABEL: bextr32_b1_indexzext: 2333; X64-BMI2: # %bb.0: 2334; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 2335; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 2336; X64-BMI2-NEXT: retq 2337 %skip = zext i8 %numskipbits to i32 2338 %shifted = lshr i32 %val, %skip 2339 %conv = zext i8 %numlowbits to i32 2340 %notmask = shl i32 -1, %conv 2341 %mask = xor i32 %notmask, -1 2342 %masked = and i32 %mask, %shifted 2343 ret i32 %masked 2344} 2345 2346define i32 @bextr32_b2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind { 2347; X86-NOBMI-LABEL: bextr32_b2_load: 2348; X86-NOBMI: # %bb.0: 2349; X86-NOBMI-NEXT: pushl %esi 2350; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2351; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2352; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2353; X86-NOBMI-NEXT: movl (%eax), %esi 2354; X86-NOBMI-NEXT: shrl %cl, %esi 2355; X86-NOBMI-NEXT: movl $-1, %eax 2356; X86-NOBMI-NEXT: movl %edx, %ecx 2357; X86-NOBMI-NEXT: shll %cl, %eax 2358; X86-NOBMI-NEXT: notl %eax 2359; X86-NOBMI-NEXT: andl %esi, %eax 2360; X86-NOBMI-NEXT: popl %esi 2361; X86-NOBMI-NEXT: retl 2362; 2363; X86-BMI1-LABEL: bextr32_b2_load: 2364; X86-BMI1: # %bb.0: 2365; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 2366; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2367; X86-BMI1-NEXT: shll $8, %ecx 2368; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2369; X86-BMI1-NEXT: orl %ecx, %edx 2370; X86-BMI1-NEXT: bextrl %edx, (%eax), %eax 2371; X86-BMI1-NEXT: retl 2372; 2373; X86-BMI2-LABEL: bextr32_b2_load: 2374; X86-BMI2: # %bb.0: 2375; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2376; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 2377; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2378; X86-BMI2-NEXT: shrxl %edx, (%ecx), %ecx 2379; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 2380; X86-BMI2-NEXT: retl 2381; 2382; X64-NOBMI-LABEL: bextr32_b2_load: 2383; X64-NOBMI: # %bb.0: 2384; X64-NOBMI-NEXT: movl %esi, %ecx 2385; X64-NOBMI-NEXT: movl (%rdi), %esi 2386; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2387; X64-NOBMI-NEXT: shrl %cl, %esi 2388; X64-NOBMI-NEXT: movl $-1, %eax 2389; X64-NOBMI-NEXT: movl %edx, %ecx 2390; X64-NOBMI-NEXT: shll %cl, %eax 2391; X64-NOBMI-NEXT: notl %eax 2392; X64-NOBMI-NEXT: andl %esi, %eax 2393; X64-NOBMI-NEXT: retq 2394; 2395; X64-BMI1-LABEL: bextr32_b2_load: 2396; X64-BMI1: # %bb.0: 2397; X64-BMI1-NEXT: shll $8, %edx 2398; X64-BMI1-NEXT: movzbl %sil, %eax 2399; X64-BMI1-NEXT: orl %edx, %eax 2400; X64-BMI1-NEXT: bextrl %eax, (%rdi), %eax 2401; X64-BMI1-NEXT: retq 2402; 2403; X64-BMI2-LABEL: bextr32_b2_load: 2404; X64-BMI2: # %bb.0: 2405; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 2406; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 2407; X64-BMI2-NEXT: retq 2408 %val = load i32, ptr %w 2409 %shifted = lshr i32 %val, %numskipbits 2410 %notmask = shl i32 -1, %numlowbits 2411 %mask = xor i32 %notmask, -1 2412 %masked = and i32 %mask, %shifted 2413 ret i32 %masked 2414} 2415 2416define i32 @bextr32_b3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind { 2417; X86-NOBMI-LABEL: bextr32_b3_load_indexzext: 2418; X86-NOBMI: # %bb.0: 2419; X86-NOBMI-NEXT: pushl %esi 2420; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2421; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2422; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2423; X86-NOBMI-NEXT: movl (%eax), %esi 2424; X86-NOBMI-NEXT: shrl %cl, %esi 2425; X86-NOBMI-NEXT: movl $-1, %eax 2426; X86-NOBMI-NEXT: movl %edx, %ecx 2427; X86-NOBMI-NEXT: shll %cl, %eax 2428; X86-NOBMI-NEXT: notl %eax 2429; X86-NOBMI-NEXT: andl %esi, %eax 2430; X86-NOBMI-NEXT: popl %esi 2431; X86-NOBMI-NEXT: retl 2432; 2433; X86-BMI1-LABEL: bextr32_b3_load_indexzext: 2434; X86-BMI1: # %bb.0: 2435; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 2436; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2437; X86-BMI1-NEXT: shll $8, %ecx 2438; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2439; X86-BMI1-NEXT: orl %ecx, %edx 2440; X86-BMI1-NEXT: bextrl %edx, (%eax), %eax 2441; X86-BMI1-NEXT: retl 2442; 2443; X86-BMI2-LABEL: bextr32_b3_load_indexzext: 2444; X86-BMI2: # %bb.0: 2445; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2446; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 2447; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2448; X86-BMI2-NEXT: shrxl %edx, (%ecx), %ecx 2449; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 2450; X86-BMI2-NEXT: retl 2451; 2452; X64-NOBMI-LABEL: bextr32_b3_load_indexzext: 2453; X64-NOBMI: # %bb.0: 2454; X64-NOBMI-NEXT: movl %esi, %ecx 2455; X64-NOBMI-NEXT: movl (%rdi), %esi 2456; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2457; X64-NOBMI-NEXT: shrl %cl, %esi 2458; X64-NOBMI-NEXT: movl $-1, %eax 2459; X64-NOBMI-NEXT: movl %edx, %ecx 2460; X64-NOBMI-NEXT: shll %cl, %eax 2461; X64-NOBMI-NEXT: notl %eax 2462; X64-NOBMI-NEXT: andl %esi, %eax 2463; X64-NOBMI-NEXT: retq 2464; 2465; X64-BMI1-LABEL: bextr32_b3_load_indexzext: 2466; X64-BMI1: # %bb.0: 2467; X64-BMI1-NEXT: shll $8, %edx 2468; X64-BMI1-NEXT: orl %esi, %edx 2469; X64-BMI1-NEXT: bextrl %edx, (%rdi), %eax 2470; X64-BMI1-NEXT: retq 2471; 2472; X64-BMI2-LABEL: bextr32_b3_load_indexzext: 2473; X64-BMI2: # %bb.0: 2474; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 2475; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 2476; X64-BMI2-NEXT: retq 2477 %val = load i32, ptr %w 2478 %skip = zext i8 %numskipbits to i32 2479 %shifted = lshr i32 %val, %skip 2480 %conv = zext i8 %numlowbits to i32 2481 %notmask = shl i32 -1, %conv 2482 %mask = xor i32 %notmask, -1 2483 %masked = and i32 %mask, %shifted 2484 ret i32 %masked 2485} 2486 2487define i32 @bextr32_b4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 2488; X86-NOBMI-LABEL: bextr32_b4_commutative: 2489; X86-NOBMI: # %bb.0: 2490; X86-NOBMI-NEXT: pushl %esi 2491; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2492; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2493; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 2494; X86-NOBMI-NEXT: shrl %cl, %esi 2495; X86-NOBMI-NEXT: movl $-1, %eax 2496; X86-NOBMI-NEXT: movl %edx, %ecx 2497; X86-NOBMI-NEXT: shll %cl, %eax 2498; X86-NOBMI-NEXT: notl %eax 2499; X86-NOBMI-NEXT: andl %esi, %eax 2500; X86-NOBMI-NEXT: popl %esi 2501; X86-NOBMI-NEXT: retl 2502; 2503; X86-BMI1-LABEL: bextr32_b4_commutative: 2504; X86-BMI1: # %bb.0: 2505; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2506; X86-BMI1-NEXT: shll $8, %eax 2507; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2508; X86-BMI1-NEXT: orl %eax, %ecx 2509; X86-BMI1-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %eax 2510; X86-BMI1-NEXT: retl 2511; 2512; X86-BMI2-LABEL: bextr32_b4_commutative: 2513; X86-BMI2: # %bb.0: 2514; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2515; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2516; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %ecx 2517; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 2518; X86-BMI2-NEXT: retl 2519; 2520; X64-NOBMI-LABEL: bextr32_b4_commutative: 2521; X64-NOBMI: # %bb.0: 2522; X64-NOBMI-NEXT: movl %esi, %ecx 2523; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2524; X64-NOBMI-NEXT: shrl %cl, %edi 2525; X64-NOBMI-NEXT: movl $-1, %eax 2526; X64-NOBMI-NEXT: movl %edx, %ecx 2527; X64-NOBMI-NEXT: shll %cl, %eax 2528; X64-NOBMI-NEXT: notl %eax 2529; X64-NOBMI-NEXT: andl %edi, %eax 2530; X64-NOBMI-NEXT: retq 2531; 2532; X64-BMI1-LABEL: bextr32_b4_commutative: 2533; X64-BMI1: # %bb.0: 2534; X64-BMI1-NEXT: shll $8, %edx 2535; X64-BMI1-NEXT: movzbl %sil, %eax 2536; X64-BMI1-NEXT: orl %edx, %eax 2537; X64-BMI1-NEXT: bextrl %eax, %edi, %eax 2538; X64-BMI1-NEXT: retq 2539; 2540; X64-BMI2-LABEL: bextr32_b4_commutative: 2541; X64-BMI2: # %bb.0: 2542; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 2543; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 2544; X64-BMI2-NEXT: retq 2545 %shifted = lshr i32 %val, %numskipbits 2546 %notmask = shl i32 -1, %numlowbits 2547 %mask = xor i32 %notmask, -1 2548 %masked = and i32 %shifted, %mask ; swapped order 2549 ret i32 %masked 2550} 2551 2552define i32 @bextr32_b5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 2553; X86-NOBMI-LABEL: bextr32_b5_skipextrauses: 2554; X86-NOBMI: # %bb.0: 2555; X86-NOBMI-NEXT: pushl %edi 2556; X86-NOBMI-NEXT: pushl %esi 2557; X86-NOBMI-NEXT: pushl %eax 2558; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 2559; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 2560; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2561; X86-NOBMI-NEXT: movl %eax, %ecx 2562; X86-NOBMI-NEXT: shrl %cl, %edi 2563; X86-NOBMI-NEXT: movl $-1, %esi 2564; X86-NOBMI-NEXT: movl %edx, %ecx 2565; X86-NOBMI-NEXT: shll %cl, %esi 2566; X86-NOBMI-NEXT: notl %esi 2567; X86-NOBMI-NEXT: andl %edi, %esi 2568; X86-NOBMI-NEXT: movl %eax, (%esp) 2569; X86-NOBMI-NEXT: calll use32@PLT 2570; X86-NOBMI-NEXT: movl %esi, %eax 2571; X86-NOBMI-NEXT: addl $4, %esp 2572; X86-NOBMI-NEXT: popl %esi 2573; X86-NOBMI-NEXT: popl %edi 2574; X86-NOBMI-NEXT: retl 2575; 2576; X86-BMI1-LABEL: bextr32_b5_skipextrauses: 2577; X86-BMI1: # %bb.0: 2578; X86-BMI1-NEXT: pushl %esi 2579; X86-BMI1-NEXT: subl $8, %esp 2580; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2581; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 2582; X86-BMI1-NEXT: shll $8, %ecx 2583; X86-BMI1-NEXT: movzbl %al, %edx 2584; X86-BMI1-NEXT: orl %ecx, %edx 2585; X86-BMI1-NEXT: bextrl %edx, {{[0-9]+}}(%esp), %esi 2586; X86-BMI1-NEXT: movl %eax, (%esp) 2587; X86-BMI1-NEXT: calll use32@PLT 2588; X86-BMI1-NEXT: movl %esi, %eax 2589; X86-BMI1-NEXT: addl $8, %esp 2590; X86-BMI1-NEXT: popl %esi 2591; X86-BMI1-NEXT: retl 2592; 2593; X86-BMI2-LABEL: bextr32_b5_skipextrauses: 2594; X86-BMI2: # %bb.0: 2595; X86-BMI2-NEXT: pushl %esi 2596; X86-BMI2-NEXT: subl $8, %esp 2597; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2598; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 2599; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %edx 2600; X86-BMI2-NEXT: bzhil %eax, %edx, %esi 2601; X86-BMI2-NEXT: movl %ecx, (%esp) 2602; X86-BMI2-NEXT: calll use32@PLT 2603; X86-BMI2-NEXT: movl %esi, %eax 2604; X86-BMI2-NEXT: addl $8, %esp 2605; X86-BMI2-NEXT: popl %esi 2606; X86-BMI2-NEXT: retl 2607; 2608; X64-NOBMI-LABEL: bextr32_b5_skipextrauses: 2609; X64-NOBMI: # %bb.0: 2610; X64-NOBMI-NEXT: pushq %rbx 2611; X64-NOBMI-NEXT: movl %esi, %ecx 2612; X64-NOBMI-NEXT: shrl %cl, %edi 2613; X64-NOBMI-NEXT: movl $-1, %ebx 2614; X64-NOBMI-NEXT: movl %edx, %ecx 2615; X64-NOBMI-NEXT: shll %cl, %ebx 2616; X64-NOBMI-NEXT: notl %ebx 2617; X64-NOBMI-NEXT: andl %edi, %ebx 2618; X64-NOBMI-NEXT: movl %esi, %edi 2619; X64-NOBMI-NEXT: callq use32@PLT 2620; X64-NOBMI-NEXT: movl %ebx, %eax 2621; X64-NOBMI-NEXT: popq %rbx 2622; X64-NOBMI-NEXT: retq 2623; 2624; X64-BMI1-LABEL: bextr32_b5_skipextrauses: 2625; X64-BMI1: # %bb.0: 2626; X64-BMI1-NEXT: pushq %rbx 2627; X64-BMI1-NEXT: shll $8, %edx 2628; X64-BMI1-NEXT: movzbl %sil, %eax 2629; X64-BMI1-NEXT: orl %edx, %eax 2630; X64-BMI1-NEXT: bextrl %eax, %edi, %ebx 2631; X64-BMI1-NEXT: movl %esi, %edi 2632; X64-BMI1-NEXT: callq use32@PLT 2633; X64-BMI1-NEXT: movl %ebx, %eax 2634; X64-BMI1-NEXT: popq %rbx 2635; X64-BMI1-NEXT: retq 2636; 2637; X64-BMI2-LABEL: bextr32_b5_skipextrauses: 2638; X64-BMI2: # %bb.0: 2639; X64-BMI2-NEXT: pushq %rbx 2640; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 2641; X64-BMI2-NEXT: bzhil %edx, %eax, %ebx 2642; X64-BMI2-NEXT: movl %esi, %edi 2643; X64-BMI2-NEXT: callq use32@PLT 2644; X64-BMI2-NEXT: movl %ebx, %eax 2645; X64-BMI2-NEXT: popq %rbx 2646; X64-BMI2-NEXT: retq 2647 %shifted = lshr i32 %val, %numskipbits 2648 %notmask = shl i32 -1, %numlowbits 2649 %mask = xor i32 %notmask, -1 2650 %masked = and i32 %mask, %shifted 2651 call void @use32(i32 %numskipbits) 2652 ret i32 %masked 2653} 2654 2655; 64-bit 2656 2657define i64 @bextr64_b0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 2658; X86-NOBMI-LABEL: bextr64_b0: 2659; X86-NOBMI: # %bb.0: 2660; X86-NOBMI-NEXT: pushl %ebx 2661; X86-NOBMI-NEXT: pushl %edi 2662; X86-NOBMI-NEXT: pushl %esi 2663; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 2664; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 2665; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 2666; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2667; X86-NOBMI-NEXT: movl %eax, %edi 2668; X86-NOBMI-NEXT: shrl %cl, %edi 2669; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 2670; X86-NOBMI-NEXT: xorl %eax, %eax 2671; X86-NOBMI-NEXT: testb $32, %cl 2672; X86-NOBMI-NEXT: je .LBB25_2 2673; X86-NOBMI-NEXT: # %bb.1: 2674; X86-NOBMI-NEXT: movl %edi, %esi 2675; X86-NOBMI-NEXT: xorl %edi, %edi 2676; X86-NOBMI-NEXT: .LBB25_2: 2677; X86-NOBMI-NEXT: movl $-1, %edx 2678; X86-NOBMI-NEXT: movl $-1, %ebx 2679; X86-NOBMI-NEXT: movb %ch, %cl 2680; X86-NOBMI-NEXT: shll %cl, %ebx 2681; X86-NOBMI-NEXT: testb $32, %ch 2682; X86-NOBMI-NEXT: jne .LBB25_3 2683; X86-NOBMI-NEXT: # %bb.4: 2684; X86-NOBMI-NEXT: movl %ebx, %eax 2685; X86-NOBMI-NEXT: jmp .LBB25_5 2686; X86-NOBMI-NEXT: .LBB25_3: 2687; X86-NOBMI-NEXT: movl %ebx, %edx 2688; X86-NOBMI-NEXT: .LBB25_5: 2689; X86-NOBMI-NEXT: notl %edx 2690; X86-NOBMI-NEXT: andl %edi, %edx 2691; X86-NOBMI-NEXT: notl %eax 2692; X86-NOBMI-NEXT: andl %esi, %eax 2693; X86-NOBMI-NEXT: popl %esi 2694; X86-NOBMI-NEXT: popl %edi 2695; X86-NOBMI-NEXT: popl %ebx 2696; X86-NOBMI-NEXT: retl 2697; 2698; X86-BMI1-LABEL: bextr64_b0: 2699; X86-BMI1: # %bb.0: 2700; X86-BMI1-NEXT: pushl %ebx 2701; X86-BMI1-NEXT: pushl %edi 2702; X86-BMI1-NEXT: pushl %esi 2703; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2704; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2705; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 2706; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 2707; X86-BMI1-NEXT: movl %edi, %edx 2708; X86-BMI1-NEXT: shrl %cl, %edx 2709; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 2710; X86-BMI1-NEXT: testb $32, %cl 2711; X86-BMI1-NEXT: je .LBB25_2 2712; X86-BMI1-NEXT: # %bb.1: 2713; X86-BMI1-NEXT: movl %edx, %esi 2714; X86-BMI1-NEXT: xorl %edx, %edx 2715; X86-BMI1-NEXT: .LBB25_2: 2716; X86-BMI1-NEXT: movl $-1, %edi 2717; X86-BMI1-NEXT: movl $-1, %ebx 2718; X86-BMI1-NEXT: movl %eax, %ecx 2719; X86-BMI1-NEXT: shll %cl, %ebx 2720; X86-BMI1-NEXT: testb $32, %al 2721; X86-BMI1-NEXT: je .LBB25_4 2722; X86-BMI1-NEXT: # %bb.3: 2723; X86-BMI1-NEXT: movl %ebx, %edi 2724; X86-BMI1-NEXT: xorl %ebx, %ebx 2725; X86-BMI1-NEXT: .LBB25_4: 2726; X86-BMI1-NEXT: andnl %edx, %edi, %edx 2727; X86-BMI1-NEXT: andnl %esi, %ebx, %eax 2728; X86-BMI1-NEXT: popl %esi 2729; X86-BMI1-NEXT: popl %edi 2730; X86-BMI1-NEXT: popl %ebx 2731; X86-BMI1-NEXT: retl 2732; 2733; X86-BMI2-LABEL: bextr64_b0: 2734; X86-BMI2: # %bb.0: 2735; X86-BMI2-NEXT: pushl %ebx 2736; X86-BMI2-NEXT: pushl %esi 2737; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 2738; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2739; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 2740; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 2741; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 2742; X86-BMI2-NEXT: shrxl %ecx, %edx, %edx 2743; X86-BMI2-NEXT: testb $32, %cl 2744; X86-BMI2-NEXT: je .LBB25_2 2745; X86-BMI2-NEXT: # %bb.1: 2746; X86-BMI2-NEXT: movl %edx, %eax 2747; X86-BMI2-NEXT: xorl %edx, %edx 2748; X86-BMI2-NEXT: .LBB25_2: 2749; X86-BMI2-NEXT: movl $-1, %esi 2750; X86-BMI2-NEXT: shlxl %ebx, %esi, %ecx 2751; X86-BMI2-NEXT: testb $32, %bl 2752; X86-BMI2-NEXT: je .LBB25_4 2753; X86-BMI2-NEXT: # %bb.3: 2754; X86-BMI2-NEXT: movl %ecx, %esi 2755; X86-BMI2-NEXT: xorl %ecx, %ecx 2756; X86-BMI2-NEXT: .LBB25_4: 2757; X86-BMI2-NEXT: andnl %edx, %esi, %edx 2758; X86-BMI2-NEXT: andnl %eax, %ecx, %eax 2759; X86-BMI2-NEXT: popl %esi 2760; X86-BMI2-NEXT: popl %ebx 2761; X86-BMI2-NEXT: retl 2762; 2763; X64-NOBMI-LABEL: bextr64_b0: 2764; X64-NOBMI: # %bb.0: 2765; X64-NOBMI-NEXT: movq %rsi, %rcx 2766; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 2767; X64-NOBMI-NEXT: shrq %cl, %rdi 2768; X64-NOBMI-NEXT: movq $-1, %rax 2769; X64-NOBMI-NEXT: movl %edx, %ecx 2770; X64-NOBMI-NEXT: shlq %cl, %rax 2771; X64-NOBMI-NEXT: notq %rax 2772; X64-NOBMI-NEXT: andq %rdi, %rax 2773; X64-NOBMI-NEXT: retq 2774; 2775; X64-BMI1-LABEL: bextr64_b0: 2776; X64-BMI1: # %bb.0: 2777; X64-BMI1-NEXT: shll $8, %edx 2778; X64-BMI1-NEXT: movzbl %sil, %eax 2779; X64-BMI1-NEXT: orl %edx, %eax 2780; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 2781; X64-BMI1-NEXT: retq 2782; 2783; X64-BMI2-LABEL: bextr64_b0: 2784; X64-BMI2: # %bb.0: 2785; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 2786; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 2787; X64-BMI2-NEXT: retq 2788 %shifted = lshr i64 %val, %numskipbits 2789 %notmask = shl i64 -1, %numlowbits 2790 %mask = xor i64 %notmask, -1 2791 %masked = and i64 %mask, %shifted 2792 ret i64 %masked 2793} 2794 2795define i64 @bextr64_b1_indexzext(i64 %val, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind { 2796; X86-NOBMI-LABEL: bextr64_b1_indexzext: 2797; X86-NOBMI: # %bb.0: 2798; X86-NOBMI-NEXT: pushl %ebx 2799; X86-NOBMI-NEXT: pushl %edi 2800; X86-NOBMI-NEXT: pushl %esi 2801; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 2802; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 2803; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 2804; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2805; X86-NOBMI-NEXT: movl %eax, %edi 2806; X86-NOBMI-NEXT: shrl %cl, %edi 2807; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 2808; X86-NOBMI-NEXT: xorl %eax, %eax 2809; X86-NOBMI-NEXT: testb $32, %cl 2810; X86-NOBMI-NEXT: je .LBB26_2 2811; X86-NOBMI-NEXT: # %bb.1: 2812; X86-NOBMI-NEXT: movl %edi, %esi 2813; X86-NOBMI-NEXT: xorl %edi, %edi 2814; X86-NOBMI-NEXT: .LBB26_2: 2815; X86-NOBMI-NEXT: movl $-1, %edx 2816; X86-NOBMI-NEXT: movl $-1, %ebx 2817; X86-NOBMI-NEXT: movb %ch, %cl 2818; X86-NOBMI-NEXT: shll %cl, %ebx 2819; X86-NOBMI-NEXT: testb $32, %ch 2820; X86-NOBMI-NEXT: jne .LBB26_3 2821; X86-NOBMI-NEXT: # %bb.4: 2822; X86-NOBMI-NEXT: movl %ebx, %eax 2823; X86-NOBMI-NEXT: jmp .LBB26_5 2824; X86-NOBMI-NEXT: .LBB26_3: 2825; X86-NOBMI-NEXT: movl %ebx, %edx 2826; X86-NOBMI-NEXT: .LBB26_5: 2827; X86-NOBMI-NEXT: notl %edx 2828; X86-NOBMI-NEXT: andl %edi, %edx 2829; X86-NOBMI-NEXT: notl %eax 2830; X86-NOBMI-NEXT: andl %esi, %eax 2831; X86-NOBMI-NEXT: popl %esi 2832; X86-NOBMI-NEXT: popl %edi 2833; X86-NOBMI-NEXT: popl %ebx 2834; X86-NOBMI-NEXT: retl 2835; 2836; X86-BMI1-LABEL: bextr64_b1_indexzext: 2837; X86-BMI1: # %bb.0: 2838; X86-BMI1-NEXT: pushl %ebx 2839; X86-BMI1-NEXT: pushl %edi 2840; X86-BMI1-NEXT: pushl %esi 2841; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2842; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2843; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 2844; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 2845; X86-BMI1-NEXT: movl %edi, %edx 2846; X86-BMI1-NEXT: shrl %cl, %edx 2847; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 2848; X86-BMI1-NEXT: testb $32, %cl 2849; X86-BMI1-NEXT: je .LBB26_2 2850; X86-BMI1-NEXT: # %bb.1: 2851; X86-BMI1-NEXT: movl %edx, %esi 2852; X86-BMI1-NEXT: xorl %edx, %edx 2853; X86-BMI1-NEXT: .LBB26_2: 2854; X86-BMI1-NEXT: movl $-1, %edi 2855; X86-BMI1-NEXT: movl $-1, %ebx 2856; X86-BMI1-NEXT: movl %eax, %ecx 2857; X86-BMI1-NEXT: shll %cl, %ebx 2858; X86-BMI1-NEXT: testb $32, %al 2859; X86-BMI1-NEXT: je .LBB26_4 2860; X86-BMI1-NEXT: # %bb.3: 2861; X86-BMI1-NEXT: movl %ebx, %edi 2862; X86-BMI1-NEXT: xorl %ebx, %ebx 2863; X86-BMI1-NEXT: .LBB26_4: 2864; X86-BMI1-NEXT: andnl %edx, %edi, %edx 2865; X86-BMI1-NEXT: andnl %esi, %ebx, %eax 2866; X86-BMI1-NEXT: popl %esi 2867; X86-BMI1-NEXT: popl %edi 2868; X86-BMI1-NEXT: popl %ebx 2869; X86-BMI1-NEXT: retl 2870; 2871; X86-BMI2-LABEL: bextr64_b1_indexzext: 2872; X86-BMI2: # %bb.0: 2873; X86-BMI2-NEXT: pushl %ebx 2874; X86-BMI2-NEXT: pushl %esi 2875; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 2876; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2877; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 2878; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 2879; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 2880; X86-BMI2-NEXT: shrxl %ecx, %edx, %edx 2881; X86-BMI2-NEXT: testb $32, %cl 2882; X86-BMI2-NEXT: je .LBB26_2 2883; X86-BMI2-NEXT: # %bb.1: 2884; X86-BMI2-NEXT: movl %edx, %eax 2885; X86-BMI2-NEXT: xorl %edx, %edx 2886; X86-BMI2-NEXT: .LBB26_2: 2887; X86-BMI2-NEXT: movl $-1, %esi 2888; X86-BMI2-NEXT: shlxl %ebx, %esi, %ecx 2889; X86-BMI2-NEXT: testb $32, %bl 2890; X86-BMI2-NEXT: je .LBB26_4 2891; X86-BMI2-NEXT: # %bb.3: 2892; X86-BMI2-NEXT: movl %ecx, %esi 2893; X86-BMI2-NEXT: xorl %ecx, %ecx 2894; X86-BMI2-NEXT: .LBB26_4: 2895; X86-BMI2-NEXT: andnl %edx, %esi, %edx 2896; X86-BMI2-NEXT: andnl %eax, %ecx, %eax 2897; X86-BMI2-NEXT: popl %esi 2898; X86-BMI2-NEXT: popl %ebx 2899; X86-BMI2-NEXT: retl 2900; 2901; X64-NOBMI-LABEL: bextr64_b1_indexzext: 2902; X64-NOBMI: # %bb.0: 2903; X64-NOBMI-NEXT: movl %esi, %ecx 2904; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 2905; X64-NOBMI-NEXT: shrq %cl, %rdi 2906; X64-NOBMI-NEXT: movq $-1, %rax 2907; X64-NOBMI-NEXT: movl %edx, %ecx 2908; X64-NOBMI-NEXT: shlq %cl, %rax 2909; X64-NOBMI-NEXT: notq %rax 2910; X64-NOBMI-NEXT: andq %rdi, %rax 2911; X64-NOBMI-NEXT: retq 2912; 2913; X64-BMI1-LABEL: bextr64_b1_indexzext: 2914; X64-BMI1: # %bb.0: 2915; X64-BMI1-NEXT: # kill: def $edx killed $edx def $rdx 2916; X64-BMI1-NEXT: shll $8, %edx 2917; X64-BMI1-NEXT: orl %esi, %edx 2918; X64-BMI1-NEXT: bextrq %rdx, %rdi, %rax 2919; X64-BMI1-NEXT: retq 2920; 2921; X64-BMI2-LABEL: bextr64_b1_indexzext: 2922; X64-BMI2: # %bb.0: 2923; X64-BMI2-NEXT: # kill: def $edx killed $edx def $rdx 2924; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 2925; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 2926; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 2927; X64-BMI2-NEXT: retq 2928 %skip = zext i8 %numskipbits to i64 2929 %shifted = lshr i64 %val, %skip 2930 %conv = zext i8 %numlowbits to i64 2931 %notmask = shl i64 -1, %conv 2932 %mask = xor i64 %notmask, -1 2933 %masked = and i64 %mask, %shifted 2934 ret i64 %masked 2935} 2936 2937define i64 @bextr64_b2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind { 2938; X86-NOBMI-LABEL: bextr64_b2_load: 2939; X86-NOBMI: # %bb.0: 2940; X86-NOBMI-NEXT: pushl %ebx 2941; X86-NOBMI-NEXT: pushl %edi 2942; X86-NOBMI-NEXT: pushl %esi 2943; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 2944; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 2945; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 2946; X86-NOBMI-NEXT: movl (%eax), %esi 2947; X86-NOBMI-NEXT: movl 4(%eax), %eax 2948; X86-NOBMI-NEXT: movl %eax, %edi 2949; X86-NOBMI-NEXT: shrl %cl, %edi 2950; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 2951; X86-NOBMI-NEXT: xorl %eax, %eax 2952; X86-NOBMI-NEXT: testb $32, %cl 2953; X86-NOBMI-NEXT: je .LBB27_2 2954; X86-NOBMI-NEXT: # %bb.1: 2955; X86-NOBMI-NEXT: movl %edi, %esi 2956; X86-NOBMI-NEXT: xorl %edi, %edi 2957; X86-NOBMI-NEXT: .LBB27_2: 2958; X86-NOBMI-NEXT: movl $-1, %edx 2959; X86-NOBMI-NEXT: movl $-1, %ebx 2960; X86-NOBMI-NEXT: movb %ch, %cl 2961; X86-NOBMI-NEXT: shll %cl, %ebx 2962; X86-NOBMI-NEXT: testb $32, %ch 2963; X86-NOBMI-NEXT: jne .LBB27_3 2964; X86-NOBMI-NEXT: # %bb.4: 2965; X86-NOBMI-NEXT: movl %ebx, %eax 2966; X86-NOBMI-NEXT: jmp .LBB27_5 2967; X86-NOBMI-NEXT: .LBB27_3: 2968; X86-NOBMI-NEXT: movl %ebx, %edx 2969; X86-NOBMI-NEXT: .LBB27_5: 2970; X86-NOBMI-NEXT: notl %edx 2971; X86-NOBMI-NEXT: andl %edi, %edx 2972; X86-NOBMI-NEXT: notl %eax 2973; X86-NOBMI-NEXT: andl %esi, %eax 2974; X86-NOBMI-NEXT: popl %esi 2975; X86-NOBMI-NEXT: popl %edi 2976; X86-NOBMI-NEXT: popl %ebx 2977; X86-NOBMI-NEXT: retl 2978; 2979; X86-BMI1-LABEL: bextr64_b2_load: 2980; X86-BMI1: # %bb.0: 2981; X86-BMI1-NEXT: pushl %ebx 2982; X86-BMI1-NEXT: pushl %edi 2983; X86-BMI1-NEXT: pushl %esi 2984; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 2985; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 2986; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edx 2987; X86-BMI1-NEXT: movl (%edx), %esi 2988; X86-BMI1-NEXT: movl 4(%edx), %edi 2989; X86-BMI1-NEXT: movl %edi, %edx 2990; X86-BMI1-NEXT: shrl %cl, %edx 2991; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 2992; X86-BMI1-NEXT: testb $32, %cl 2993; X86-BMI1-NEXT: je .LBB27_2 2994; X86-BMI1-NEXT: # %bb.1: 2995; X86-BMI1-NEXT: movl %edx, %esi 2996; X86-BMI1-NEXT: xorl %edx, %edx 2997; X86-BMI1-NEXT: .LBB27_2: 2998; X86-BMI1-NEXT: movl $-1, %edi 2999; X86-BMI1-NEXT: movl $-1, %ebx 3000; X86-BMI1-NEXT: movl %eax, %ecx 3001; X86-BMI1-NEXT: shll %cl, %ebx 3002; X86-BMI1-NEXT: testb $32, %al 3003; X86-BMI1-NEXT: je .LBB27_4 3004; X86-BMI1-NEXT: # %bb.3: 3005; X86-BMI1-NEXT: movl %ebx, %edi 3006; X86-BMI1-NEXT: xorl %ebx, %ebx 3007; X86-BMI1-NEXT: .LBB27_4: 3008; X86-BMI1-NEXT: andnl %edx, %edi, %edx 3009; X86-BMI1-NEXT: andnl %esi, %ebx, %eax 3010; X86-BMI1-NEXT: popl %esi 3011; X86-BMI1-NEXT: popl %edi 3012; X86-BMI1-NEXT: popl %ebx 3013; X86-BMI1-NEXT: retl 3014; 3015; X86-BMI2-LABEL: bextr64_b2_load: 3016; X86-BMI2: # %bb.0: 3017; X86-BMI2-NEXT: pushl %ebx 3018; X86-BMI2-NEXT: pushl %esi 3019; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 3020; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3021; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 3022; X86-BMI2-NEXT: movl (%edx), %eax 3023; X86-BMI2-NEXT: movl 4(%edx), %esi 3024; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 3025; X86-BMI2-NEXT: shrdl %cl, %esi, %eax 3026; X86-BMI2-NEXT: testb $32, %cl 3027; X86-BMI2-NEXT: je .LBB27_2 3028; X86-BMI2-NEXT: # %bb.1: 3029; X86-BMI2-NEXT: movl %edx, %eax 3030; X86-BMI2-NEXT: xorl %edx, %edx 3031; X86-BMI2-NEXT: .LBB27_2: 3032; X86-BMI2-NEXT: movl $-1, %esi 3033; X86-BMI2-NEXT: shlxl %ebx, %esi, %ecx 3034; X86-BMI2-NEXT: testb $32, %bl 3035; X86-BMI2-NEXT: je .LBB27_4 3036; X86-BMI2-NEXT: # %bb.3: 3037; X86-BMI2-NEXT: movl %ecx, %esi 3038; X86-BMI2-NEXT: xorl %ecx, %ecx 3039; X86-BMI2-NEXT: .LBB27_4: 3040; X86-BMI2-NEXT: andnl %edx, %esi, %edx 3041; X86-BMI2-NEXT: andnl %eax, %ecx, %eax 3042; X86-BMI2-NEXT: popl %esi 3043; X86-BMI2-NEXT: popl %ebx 3044; X86-BMI2-NEXT: retl 3045; 3046; X64-NOBMI-LABEL: bextr64_b2_load: 3047; X64-NOBMI: # %bb.0: 3048; X64-NOBMI-NEXT: movq %rsi, %rcx 3049; X64-NOBMI-NEXT: movq (%rdi), %rsi 3050; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 3051; X64-NOBMI-NEXT: shrq %cl, %rsi 3052; X64-NOBMI-NEXT: movq $-1, %rax 3053; X64-NOBMI-NEXT: movl %edx, %ecx 3054; X64-NOBMI-NEXT: shlq %cl, %rax 3055; X64-NOBMI-NEXT: notq %rax 3056; X64-NOBMI-NEXT: andq %rsi, %rax 3057; X64-NOBMI-NEXT: retq 3058; 3059; X64-BMI1-LABEL: bextr64_b2_load: 3060; X64-BMI1: # %bb.0: 3061; X64-BMI1-NEXT: shll $8, %edx 3062; X64-BMI1-NEXT: movzbl %sil, %eax 3063; X64-BMI1-NEXT: orl %edx, %eax 3064; X64-BMI1-NEXT: bextrq %rax, (%rdi), %rax 3065; X64-BMI1-NEXT: retq 3066; 3067; X64-BMI2-LABEL: bextr64_b2_load: 3068; X64-BMI2: # %bb.0: 3069; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 3070; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 3071; X64-BMI2-NEXT: retq 3072 %val = load i64, ptr %w 3073 %shifted = lshr i64 %val, %numskipbits 3074 %notmask = shl i64 -1, %numlowbits 3075 %mask = xor i64 %notmask, -1 3076 %masked = and i64 %mask, %shifted 3077 ret i64 %masked 3078} 3079 3080define i64 @bextr64_b3_load_indexzext(ptr %w, i8 zeroext %numskipbits, i8 zeroext %numlowbits) nounwind { 3081; X86-NOBMI-LABEL: bextr64_b3_load_indexzext: 3082; X86-NOBMI: # %bb.0: 3083; X86-NOBMI-NEXT: pushl %ebx 3084; X86-NOBMI-NEXT: pushl %edi 3085; X86-NOBMI-NEXT: pushl %esi 3086; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 3087; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 3088; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 3089; X86-NOBMI-NEXT: movl (%eax), %esi 3090; X86-NOBMI-NEXT: movl 4(%eax), %eax 3091; X86-NOBMI-NEXT: movl %eax, %edi 3092; X86-NOBMI-NEXT: shrl %cl, %edi 3093; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 3094; X86-NOBMI-NEXT: xorl %eax, %eax 3095; X86-NOBMI-NEXT: testb $32, %cl 3096; X86-NOBMI-NEXT: je .LBB28_2 3097; X86-NOBMI-NEXT: # %bb.1: 3098; X86-NOBMI-NEXT: movl %edi, %esi 3099; X86-NOBMI-NEXT: xorl %edi, %edi 3100; X86-NOBMI-NEXT: .LBB28_2: 3101; X86-NOBMI-NEXT: movl $-1, %edx 3102; X86-NOBMI-NEXT: movl $-1, %ebx 3103; X86-NOBMI-NEXT: movb %ch, %cl 3104; X86-NOBMI-NEXT: shll %cl, %ebx 3105; X86-NOBMI-NEXT: testb $32, %ch 3106; X86-NOBMI-NEXT: jne .LBB28_3 3107; X86-NOBMI-NEXT: # %bb.4: 3108; X86-NOBMI-NEXT: movl %ebx, %eax 3109; X86-NOBMI-NEXT: jmp .LBB28_5 3110; X86-NOBMI-NEXT: .LBB28_3: 3111; X86-NOBMI-NEXT: movl %ebx, %edx 3112; X86-NOBMI-NEXT: .LBB28_5: 3113; X86-NOBMI-NEXT: notl %edx 3114; X86-NOBMI-NEXT: andl %edi, %edx 3115; X86-NOBMI-NEXT: notl %eax 3116; X86-NOBMI-NEXT: andl %esi, %eax 3117; X86-NOBMI-NEXT: popl %esi 3118; X86-NOBMI-NEXT: popl %edi 3119; X86-NOBMI-NEXT: popl %ebx 3120; X86-NOBMI-NEXT: retl 3121; 3122; X86-BMI1-LABEL: bextr64_b3_load_indexzext: 3123; X86-BMI1: # %bb.0: 3124; X86-BMI1-NEXT: pushl %ebx 3125; X86-BMI1-NEXT: pushl %edi 3126; X86-BMI1-NEXT: pushl %esi 3127; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3128; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3129; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edx 3130; X86-BMI1-NEXT: movl (%edx), %esi 3131; X86-BMI1-NEXT: movl 4(%edx), %edi 3132; X86-BMI1-NEXT: movl %edi, %edx 3133; X86-BMI1-NEXT: shrl %cl, %edx 3134; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 3135; X86-BMI1-NEXT: testb $32, %cl 3136; X86-BMI1-NEXT: je .LBB28_2 3137; X86-BMI1-NEXT: # %bb.1: 3138; X86-BMI1-NEXT: movl %edx, %esi 3139; X86-BMI1-NEXT: xorl %edx, %edx 3140; X86-BMI1-NEXT: .LBB28_2: 3141; X86-BMI1-NEXT: movl $-1, %edi 3142; X86-BMI1-NEXT: movl $-1, %ebx 3143; X86-BMI1-NEXT: movl %eax, %ecx 3144; X86-BMI1-NEXT: shll %cl, %ebx 3145; X86-BMI1-NEXT: testb $32, %al 3146; X86-BMI1-NEXT: je .LBB28_4 3147; X86-BMI1-NEXT: # %bb.3: 3148; X86-BMI1-NEXT: movl %ebx, %edi 3149; X86-BMI1-NEXT: xorl %ebx, %ebx 3150; X86-BMI1-NEXT: .LBB28_4: 3151; X86-BMI1-NEXT: andnl %edx, %edi, %edx 3152; X86-BMI1-NEXT: andnl %esi, %ebx, %eax 3153; X86-BMI1-NEXT: popl %esi 3154; X86-BMI1-NEXT: popl %edi 3155; X86-BMI1-NEXT: popl %ebx 3156; X86-BMI1-NEXT: retl 3157; 3158; X86-BMI2-LABEL: bextr64_b3_load_indexzext: 3159; X86-BMI2: # %bb.0: 3160; X86-BMI2-NEXT: pushl %ebx 3161; X86-BMI2-NEXT: pushl %esi 3162; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 3163; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3164; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 3165; X86-BMI2-NEXT: movl (%edx), %eax 3166; X86-BMI2-NEXT: movl 4(%edx), %esi 3167; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 3168; X86-BMI2-NEXT: shrdl %cl, %esi, %eax 3169; X86-BMI2-NEXT: testb $32, %cl 3170; X86-BMI2-NEXT: je .LBB28_2 3171; X86-BMI2-NEXT: # %bb.1: 3172; X86-BMI2-NEXT: movl %edx, %eax 3173; X86-BMI2-NEXT: xorl %edx, %edx 3174; X86-BMI2-NEXT: .LBB28_2: 3175; X86-BMI2-NEXT: movl $-1, %esi 3176; X86-BMI2-NEXT: shlxl %ebx, %esi, %ecx 3177; X86-BMI2-NEXT: testb $32, %bl 3178; X86-BMI2-NEXT: je .LBB28_4 3179; X86-BMI2-NEXT: # %bb.3: 3180; X86-BMI2-NEXT: movl %ecx, %esi 3181; X86-BMI2-NEXT: xorl %ecx, %ecx 3182; X86-BMI2-NEXT: .LBB28_4: 3183; X86-BMI2-NEXT: andnl %edx, %esi, %edx 3184; X86-BMI2-NEXT: andnl %eax, %ecx, %eax 3185; X86-BMI2-NEXT: popl %esi 3186; X86-BMI2-NEXT: popl %ebx 3187; X86-BMI2-NEXT: retl 3188; 3189; X64-NOBMI-LABEL: bextr64_b3_load_indexzext: 3190; X64-NOBMI: # %bb.0: 3191; X64-NOBMI-NEXT: movl %esi, %ecx 3192; X64-NOBMI-NEXT: movq (%rdi), %rsi 3193; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 3194; X64-NOBMI-NEXT: shrq %cl, %rsi 3195; X64-NOBMI-NEXT: movq $-1, %rax 3196; X64-NOBMI-NEXT: movl %edx, %ecx 3197; X64-NOBMI-NEXT: shlq %cl, %rax 3198; X64-NOBMI-NEXT: notq %rax 3199; X64-NOBMI-NEXT: andq %rsi, %rax 3200; X64-NOBMI-NEXT: retq 3201; 3202; X64-BMI1-LABEL: bextr64_b3_load_indexzext: 3203; X64-BMI1: # %bb.0: 3204; X64-BMI1-NEXT: # kill: def $edx killed $edx def $rdx 3205; X64-BMI1-NEXT: shll $8, %edx 3206; X64-BMI1-NEXT: orl %esi, %edx 3207; X64-BMI1-NEXT: bextrq %rdx, (%rdi), %rax 3208; X64-BMI1-NEXT: retq 3209; 3210; X64-BMI2-LABEL: bextr64_b3_load_indexzext: 3211; X64-BMI2: # %bb.0: 3212; X64-BMI2-NEXT: # kill: def $edx killed $edx def $rdx 3213; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 3214; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 3215; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 3216; X64-BMI2-NEXT: retq 3217 %val = load i64, ptr %w 3218 %skip = zext i8 %numskipbits to i64 3219 %shifted = lshr i64 %val, %skip 3220 %conv = zext i8 %numlowbits to i64 3221 %notmask = shl i64 -1, %conv 3222 %mask = xor i64 %notmask, -1 3223 %masked = and i64 %mask, %shifted 3224 ret i64 %masked 3225} 3226 3227define i64 @bextr64_b4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 3228; X86-NOBMI-LABEL: bextr64_b4_commutative: 3229; X86-NOBMI: # %bb.0: 3230; X86-NOBMI-NEXT: pushl %ebx 3231; X86-NOBMI-NEXT: pushl %edi 3232; X86-NOBMI-NEXT: pushl %esi 3233; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 3234; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl 3235; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 3236; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 3237; X86-NOBMI-NEXT: movl %esi, %edx 3238; X86-NOBMI-NEXT: shrl %cl, %edx 3239; X86-NOBMI-NEXT: shrdl %cl, %esi, %eax 3240; X86-NOBMI-NEXT: xorl %esi, %esi 3241; X86-NOBMI-NEXT: testb $32, %cl 3242; X86-NOBMI-NEXT: je .LBB29_2 3243; X86-NOBMI-NEXT: # %bb.1: 3244; X86-NOBMI-NEXT: movl %edx, %eax 3245; X86-NOBMI-NEXT: xorl %edx, %edx 3246; X86-NOBMI-NEXT: .LBB29_2: 3247; X86-NOBMI-NEXT: movl $-1, %edi 3248; X86-NOBMI-NEXT: movl $-1, %ebx 3249; X86-NOBMI-NEXT: movb %ch, %cl 3250; X86-NOBMI-NEXT: shll %cl, %ebx 3251; X86-NOBMI-NEXT: testb $32, %ch 3252; X86-NOBMI-NEXT: jne .LBB29_3 3253; X86-NOBMI-NEXT: # %bb.4: 3254; X86-NOBMI-NEXT: movl %ebx, %esi 3255; X86-NOBMI-NEXT: jmp .LBB29_5 3256; X86-NOBMI-NEXT: .LBB29_3: 3257; X86-NOBMI-NEXT: movl %ebx, %edi 3258; X86-NOBMI-NEXT: .LBB29_5: 3259; X86-NOBMI-NEXT: notl %edi 3260; X86-NOBMI-NEXT: andl %edi, %edx 3261; X86-NOBMI-NEXT: notl %esi 3262; X86-NOBMI-NEXT: andl %esi, %eax 3263; X86-NOBMI-NEXT: popl %esi 3264; X86-NOBMI-NEXT: popl %edi 3265; X86-NOBMI-NEXT: popl %ebx 3266; X86-NOBMI-NEXT: retl 3267; 3268; X86-BMI1-LABEL: bextr64_b4_commutative: 3269; X86-BMI1: # %bb.0: 3270; X86-BMI1-NEXT: pushl %ebx 3271; X86-BMI1-NEXT: pushl %edi 3272; X86-BMI1-NEXT: pushl %esi 3273; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3274; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3275; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 3276; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 3277; X86-BMI1-NEXT: movl %edi, %edx 3278; X86-BMI1-NEXT: shrl %cl, %edx 3279; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 3280; X86-BMI1-NEXT: testb $32, %cl 3281; X86-BMI1-NEXT: je .LBB29_2 3282; X86-BMI1-NEXT: # %bb.1: 3283; X86-BMI1-NEXT: movl %edx, %esi 3284; X86-BMI1-NEXT: xorl %edx, %edx 3285; X86-BMI1-NEXT: .LBB29_2: 3286; X86-BMI1-NEXT: movl $-1, %edi 3287; X86-BMI1-NEXT: movl $-1, %ebx 3288; X86-BMI1-NEXT: movl %eax, %ecx 3289; X86-BMI1-NEXT: shll %cl, %ebx 3290; X86-BMI1-NEXT: testb $32, %al 3291; X86-BMI1-NEXT: je .LBB29_4 3292; X86-BMI1-NEXT: # %bb.3: 3293; X86-BMI1-NEXT: movl %ebx, %edi 3294; X86-BMI1-NEXT: xorl %ebx, %ebx 3295; X86-BMI1-NEXT: .LBB29_4: 3296; X86-BMI1-NEXT: andnl %edx, %edi, %edx 3297; X86-BMI1-NEXT: andnl %esi, %ebx, %eax 3298; X86-BMI1-NEXT: popl %esi 3299; X86-BMI1-NEXT: popl %edi 3300; X86-BMI1-NEXT: popl %ebx 3301; X86-BMI1-NEXT: retl 3302; 3303; X86-BMI2-LABEL: bextr64_b4_commutative: 3304; X86-BMI2: # %bb.0: 3305; X86-BMI2-NEXT: pushl %ebx 3306; X86-BMI2-NEXT: pushl %esi 3307; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 3308; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3309; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 3310; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 3311; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 3312; X86-BMI2-NEXT: shrxl %ecx, %edx, %edx 3313; X86-BMI2-NEXT: testb $32, %cl 3314; X86-BMI2-NEXT: je .LBB29_2 3315; X86-BMI2-NEXT: # %bb.1: 3316; X86-BMI2-NEXT: movl %edx, %eax 3317; X86-BMI2-NEXT: xorl %edx, %edx 3318; X86-BMI2-NEXT: .LBB29_2: 3319; X86-BMI2-NEXT: movl $-1, %esi 3320; X86-BMI2-NEXT: shlxl %ebx, %esi, %ecx 3321; X86-BMI2-NEXT: testb $32, %bl 3322; X86-BMI2-NEXT: je .LBB29_4 3323; X86-BMI2-NEXT: # %bb.3: 3324; X86-BMI2-NEXT: movl %ecx, %esi 3325; X86-BMI2-NEXT: xorl %ecx, %ecx 3326; X86-BMI2-NEXT: .LBB29_4: 3327; X86-BMI2-NEXT: andnl %edx, %esi, %edx 3328; X86-BMI2-NEXT: andnl %eax, %ecx, %eax 3329; X86-BMI2-NEXT: popl %esi 3330; X86-BMI2-NEXT: popl %ebx 3331; X86-BMI2-NEXT: retl 3332; 3333; X64-NOBMI-LABEL: bextr64_b4_commutative: 3334; X64-NOBMI: # %bb.0: 3335; X64-NOBMI-NEXT: movq %rsi, %rcx 3336; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 3337; X64-NOBMI-NEXT: shrq %cl, %rdi 3338; X64-NOBMI-NEXT: movq $-1, %rax 3339; X64-NOBMI-NEXT: movl %edx, %ecx 3340; X64-NOBMI-NEXT: shlq %cl, %rax 3341; X64-NOBMI-NEXT: notq %rax 3342; X64-NOBMI-NEXT: andq %rdi, %rax 3343; X64-NOBMI-NEXT: retq 3344; 3345; X64-BMI1-LABEL: bextr64_b4_commutative: 3346; X64-BMI1: # %bb.0: 3347; X64-BMI1-NEXT: shll $8, %edx 3348; X64-BMI1-NEXT: movzbl %sil, %eax 3349; X64-BMI1-NEXT: orl %edx, %eax 3350; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 3351; X64-BMI1-NEXT: retq 3352; 3353; X64-BMI2-LABEL: bextr64_b4_commutative: 3354; X64-BMI2: # %bb.0: 3355; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 3356; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 3357; X64-BMI2-NEXT: retq 3358 %shifted = lshr i64 %val, %numskipbits 3359 %notmask = shl i64 -1, %numlowbits 3360 %mask = xor i64 %notmask, -1 3361 %masked = and i64 %shifted, %mask ; swapped order 3362 ret i64 %masked 3363} 3364 3365define i64 @bextr64_b5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 3366; X86-NOBMI-LABEL: bextr64_b5_skipextrauses: 3367; X86-NOBMI: # %bb.0: 3368; X86-NOBMI-NEXT: pushl %ebp 3369; X86-NOBMI-NEXT: pushl %ebx 3370; X86-NOBMI-NEXT: pushl %edi 3371; X86-NOBMI-NEXT: pushl %esi 3372; X86-NOBMI-NEXT: subl $12, %esp 3373; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %ch 3374; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 3375; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 3376; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 3377; X86-NOBMI-NEXT: movl %esi, %ebp 3378; X86-NOBMI-NEXT: movb %al, %cl 3379; X86-NOBMI-NEXT: shrl %cl, %ebp 3380; X86-NOBMI-NEXT: shrdl %cl, %esi, %edx 3381; X86-NOBMI-NEXT: xorl %ebx, %ebx 3382; X86-NOBMI-NEXT: testb $32, %al 3383; X86-NOBMI-NEXT: je .LBB30_2 3384; X86-NOBMI-NEXT: # %bb.1: 3385; X86-NOBMI-NEXT: movl %ebp, %edx 3386; X86-NOBMI-NEXT: xorl %ebp, %ebp 3387; X86-NOBMI-NEXT: .LBB30_2: 3388; X86-NOBMI-NEXT: movl $-1, %edi 3389; X86-NOBMI-NEXT: movl $-1, %esi 3390; X86-NOBMI-NEXT: movb %ch, %cl 3391; X86-NOBMI-NEXT: shll %cl, %esi 3392; X86-NOBMI-NEXT: testb $32, %ch 3393; X86-NOBMI-NEXT: jne .LBB30_3 3394; X86-NOBMI-NEXT: # %bb.4: 3395; X86-NOBMI-NEXT: movl %esi, %ebx 3396; X86-NOBMI-NEXT: jmp .LBB30_5 3397; X86-NOBMI-NEXT: .LBB30_3: 3398; X86-NOBMI-NEXT: movl %esi, %edi 3399; X86-NOBMI-NEXT: .LBB30_5: 3400; X86-NOBMI-NEXT: notl %edi 3401; X86-NOBMI-NEXT: andl %ebp, %edi 3402; X86-NOBMI-NEXT: notl %ebx 3403; X86-NOBMI-NEXT: andl %edx, %ebx 3404; X86-NOBMI-NEXT: subl $8, %esp 3405; X86-NOBMI-NEXT: pushl {{[0-9]+}}(%esp) 3406; X86-NOBMI-NEXT: pushl %eax 3407; X86-NOBMI-NEXT: calll use64@PLT 3408; X86-NOBMI-NEXT: addl $16, %esp 3409; X86-NOBMI-NEXT: movl %ebx, %eax 3410; X86-NOBMI-NEXT: movl %edi, %edx 3411; X86-NOBMI-NEXT: addl $12, %esp 3412; X86-NOBMI-NEXT: popl %esi 3413; X86-NOBMI-NEXT: popl %edi 3414; X86-NOBMI-NEXT: popl %ebx 3415; X86-NOBMI-NEXT: popl %ebp 3416; X86-NOBMI-NEXT: retl 3417; 3418; X86-BMI1-LABEL: bextr64_b5_skipextrauses: 3419; X86-BMI1: # %bb.0: 3420; X86-BMI1-NEXT: pushl %ebp 3421; X86-BMI1-NEXT: pushl %ebx 3422; X86-BMI1-NEXT: pushl %edi 3423; X86-BMI1-NEXT: pushl %esi 3424; X86-BMI1-NEXT: subl $12, %esp 3425; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 3426; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 3427; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %ebx 3428; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 3429; X86-BMI1-NEXT: movl %ebx, %esi 3430; X86-BMI1-NEXT: movl %eax, %ecx 3431; X86-BMI1-NEXT: shrl %cl, %esi 3432; X86-BMI1-NEXT: shrdl %cl, %ebx, %edi 3433; X86-BMI1-NEXT: testb $32, %al 3434; X86-BMI1-NEXT: je .LBB30_2 3435; X86-BMI1-NEXT: # %bb.1: 3436; X86-BMI1-NEXT: movl %esi, %edi 3437; X86-BMI1-NEXT: xorl %esi, %esi 3438; X86-BMI1-NEXT: .LBB30_2: 3439; X86-BMI1-NEXT: movl $-1, %ebx 3440; X86-BMI1-NEXT: movl $-1, %ebp 3441; X86-BMI1-NEXT: movl %edx, %ecx 3442; X86-BMI1-NEXT: shll %cl, %ebp 3443; X86-BMI1-NEXT: testb $32, %dl 3444; X86-BMI1-NEXT: je .LBB30_4 3445; X86-BMI1-NEXT: # %bb.3: 3446; X86-BMI1-NEXT: movl %ebp, %ebx 3447; X86-BMI1-NEXT: xorl %ebp, %ebp 3448; X86-BMI1-NEXT: .LBB30_4: 3449; X86-BMI1-NEXT: andnl %esi, %ebx, %esi 3450; X86-BMI1-NEXT: andnl %edi, %ebp, %edi 3451; X86-BMI1-NEXT: subl $8, %esp 3452; X86-BMI1-NEXT: pushl {{[0-9]+}}(%esp) 3453; X86-BMI1-NEXT: pushl %eax 3454; X86-BMI1-NEXT: calll use64@PLT 3455; X86-BMI1-NEXT: addl $16, %esp 3456; X86-BMI1-NEXT: movl %edi, %eax 3457; X86-BMI1-NEXT: movl %esi, %edx 3458; X86-BMI1-NEXT: addl $12, %esp 3459; X86-BMI1-NEXT: popl %esi 3460; X86-BMI1-NEXT: popl %edi 3461; X86-BMI1-NEXT: popl %ebx 3462; X86-BMI1-NEXT: popl %ebp 3463; X86-BMI1-NEXT: retl 3464; 3465; X86-BMI2-LABEL: bextr64_b5_skipextrauses: 3466; X86-BMI2: # %bb.0: 3467; X86-BMI2-NEXT: pushl %ebp 3468; X86-BMI2-NEXT: pushl %ebx 3469; X86-BMI2-NEXT: pushl %edi 3470; X86-BMI2-NEXT: pushl %esi 3471; X86-BMI2-NEXT: subl $12, %esp 3472; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 3473; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 3474; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 3475; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 3476; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 3477; X86-BMI2-NEXT: shrxl %ecx, %edx, %edx 3478; X86-BMI2-NEXT: testb $32, %cl 3479; X86-BMI2-NEXT: je .LBB30_2 3480; X86-BMI2-NEXT: # %bb.1: 3481; X86-BMI2-NEXT: movl %edx, %eax 3482; X86-BMI2-NEXT: xorl %edx, %edx 3483; X86-BMI2-NEXT: .LBB30_2: 3484; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ebp 3485; X86-BMI2-NEXT: movl $-1, %esi 3486; X86-BMI2-NEXT: shlxl %ebx, %esi, %edi 3487; X86-BMI2-NEXT: testb $32, %bl 3488; X86-BMI2-NEXT: je .LBB30_4 3489; X86-BMI2-NEXT: # %bb.3: 3490; X86-BMI2-NEXT: movl %edi, %esi 3491; X86-BMI2-NEXT: xorl %edi, %edi 3492; X86-BMI2-NEXT: .LBB30_4: 3493; X86-BMI2-NEXT: andnl %edx, %esi, %esi 3494; X86-BMI2-NEXT: andnl %eax, %edi, %edi 3495; X86-BMI2-NEXT: subl $8, %esp 3496; X86-BMI2-NEXT: pushl %ebp 3497; X86-BMI2-NEXT: pushl %ecx 3498; X86-BMI2-NEXT: calll use64@PLT 3499; X86-BMI2-NEXT: addl $16, %esp 3500; X86-BMI2-NEXT: movl %edi, %eax 3501; X86-BMI2-NEXT: movl %esi, %edx 3502; X86-BMI2-NEXT: addl $12, %esp 3503; X86-BMI2-NEXT: popl %esi 3504; X86-BMI2-NEXT: popl %edi 3505; X86-BMI2-NEXT: popl %ebx 3506; X86-BMI2-NEXT: popl %ebp 3507; X86-BMI2-NEXT: retl 3508; 3509; X64-NOBMI-LABEL: bextr64_b5_skipextrauses: 3510; X64-NOBMI: # %bb.0: 3511; X64-NOBMI-NEXT: pushq %rbx 3512; X64-NOBMI-NEXT: movl %esi, %ecx 3513; X64-NOBMI-NEXT: shrq %cl, %rdi 3514; X64-NOBMI-NEXT: movq $-1, %rbx 3515; X64-NOBMI-NEXT: movl %edx, %ecx 3516; X64-NOBMI-NEXT: shlq %cl, %rbx 3517; X64-NOBMI-NEXT: notq %rbx 3518; X64-NOBMI-NEXT: andq %rdi, %rbx 3519; X64-NOBMI-NEXT: movq %rsi, %rdi 3520; X64-NOBMI-NEXT: callq use64@PLT 3521; X64-NOBMI-NEXT: movq %rbx, %rax 3522; X64-NOBMI-NEXT: popq %rbx 3523; X64-NOBMI-NEXT: retq 3524; 3525; X64-BMI1-LABEL: bextr64_b5_skipextrauses: 3526; X64-BMI1: # %bb.0: 3527; X64-BMI1-NEXT: pushq %rbx 3528; X64-BMI1-NEXT: shll $8, %edx 3529; X64-BMI1-NEXT: movzbl %sil, %eax 3530; X64-BMI1-NEXT: orl %edx, %eax 3531; X64-BMI1-NEXT: bextrq %rax, %rdi, %rbx 3532; X64-BMI1-NEXT: movq %rsi, %rdi 3533; X64-BMI1-NEXT: callq use64@PLT 3534; X64-BMI1-NEXT: movq %rbx, %rax 3535; X64-BMI1-NEXT: popq %rbx 3536; X64-BMI1-NEXT: retq 3537; 3538; X64-BMI2-LABEL: bextr64_b5_skipextrauses: 3539; X64-BMI2: # %bb.0: 3540; X64-BMI2-NEXT: pushq %rbx 3541; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 3542; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rbx 3543; X64-BMI2-NEXT: movq %rsi, %rdi 3544; X64-BMI2-NEXT: callq use64@PLT 3545; X64-BMI2-NEXT: movq %rbx, %rax 3546; X64-BMI2-NEXT: popq %rbx 3547; X64-BMI2-NEXT: retq 3548 %shifted = lshr i64 %val, %numskipbits 3549 %notmask = shl i64 -1, %numlowbits 3550 %mask = xor i64 %notmask, -1 3551 %masked = and i64 %mask, %shifted 3552 call void @use64(i64 %numskipbits) 3553 ret i64 %masked 3554} 3555 3556; 64-bit, but with 32-bit output 3557 3558; Everything done in 64-bit, truncation happens last. 3559define i32 @bextr64_32_b0(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind { 3560; X86-NOBMI-LABEL: bextr64_32_b0: 3561; X86-NOBMI: # %bb.0: 3562; X86-NOBMI-NEXT: pushl %edi 3563; X86-NOBMI-NEXT: pushl %esi 3564; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 3565; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3566; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 3567; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 3568; X86-NOBMI-NEXT: movl %edi, %eax 3569; X86-NOBMI-NEXT: shrl %cl, %eax 3570; X86-NOBMI-NEXT: shrdl %cl, %edi, %esi 3571; X86-NOBMI-NEXT: testb $32, %cl 3572; X86-NOBMI-NEXT: jne .LBB31_2 3573; X86-NOBMI-NEXT: # %bb.1: 3574; X86-NOBMI-NEXT: movl %esi, %eax 3575; X86-NOBMI-NEXT: .LBB31_2: 3576; X86-NOBMI-NEXT: movl $-1, %esi 3577; X86-NOBMI-NEXT: movl %edx, %ecx 3578; X86-NOBMI-NEXT: shll %cl, %esi 3579; X86-NOBMI-NEXT: xorl %ecx, %ecx 3580; X86-NOBMI-NEXT: testb $32, %dl 3581; X86-NOBMI-NEXT: jne .LBB31_4 3582; X86-NOBMI-NEXT: # %bb.3: 3583; X86-NOBMI-NEXT: movl %esi, %ecx 3584; X86-NOBMI-NEXT: .LBB31_4: 3585; X86-NOBMI-NEXT: notl %ecx 3586; X86-NOBMI-NEXT: andl %ecx, %eax 3587; X86-NOBMI-NEXT: popl %esi 3588; X86-NOBMI-NEXT: popl %edi 3589; X86-NOBMI-NEXT: retl 3590; 3591; X86-BMI1-LABEL: bextr64_32_b0: 3592; X86-BMI1: # %bb.0: 3593; X86-BMI1-NEXT: pushl %edi 3594; X86-BMI1-NEXT: pushl %esi 3595; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3596; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3597; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 3598; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 3599; X86-BMI1-NEXT: movl %edi, %edx 3600; X86-BMI1-NEXT: shrl %cl, %edx 3601; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 3602; X86-BMI1-NEXT: testb $32, %cl 3603; X86-BMI1-NEXT: jne .LBB31_2 3604; X86-BMI1-NEXT: # %bb.1: 3605; X86-BMI1-NEXT: movl %esi, %edx 3606; X86-BMI1-NEXT: .LBB31_2: 3607; X86-BMI1-NEXT: movl $-1, %esi 3608; X86-BMI1-NEXT: movl %eax, %ecx 3609; X86-BMI1-NEXT: shll %cl, %esi 3610; X86-BMI1-NEXT: xorl %ecx, %ecx 3611; X86-BMI1-NEXT: testb $32, %al 3612; X86-BMI1-NEXT: jne .LBB31_4 3613; X86-BMI1-NEXT: # %bb.3: 3614; X86-BMI1-NEXT: movl %esi, %ecx 3615; X86-BMI1-NEXT: .LBB31_4: 3616; X86-BMI1-NEXT: andnl %edx, %ecx, %eax 3617; X86-BMI1-NEXT: popl %esi 3618; X86-BMI1-NEXT: popl %edi 3619; X86-BMI1-NEXT: retl 3620; 3621; X86-BMI2-LABEL: bextr64_32_b0: 3622; X86-BMI2: # %bb.0: 3623; X86-BMI2-NEXT: pushl %esi 3624; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3625; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3626; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 3627; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 3628; X86-BMI2-NEXT: shrdl %cl, %esi, %edx 3629; X86-BMI2-NEXT: testb $32, %cl 3630; X86-BMI2-NEXT: je .LBB31_2 3631; X86-BMI2-NEXT: # %bb.1: 3632; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 3633; X86-BMI2-NEXT: .LBB31_2: 3634; X86-BMI2-NEXT: xorl %ecx, %ecx 3635; X86-BMI2-NEXT: testb $32, %al 3636; X86-BMI2-NEXT: jne .LBB31_4 3637; X86-BMI2-NEXT: # %bb.3: 3638; X86-BMI2-NEXT: movl $-1, %ecx 3639; X86-BMI2-NEXT: shlxl %eax, %ecx, %ecx 3640; X86-BMI2-NEXT: .LBB31_4: 3641; X86-BMI2-NEXT: andnl %edx, %ecx, %eax 3642; X86-BMI2-NEXT: popl %esi 3643; X86-BMI2-NEXT: retl 3644; 3645; X64-NOBMI-LABEL: bextr64_32_b0: 3646; X64-NOBMI: # %bb.0: 3647; X64-NOBMI-NEXT: movq %rsi, %rcx 3648; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 3649; X64-NOBMI-NEXT: shrq %cl, %rdi 3650; X64-NOBMI-NEXT: movq $-1, %rax 3651; X64-NOBMI-NEXT: movl %edx, %ecx 3652; X64-NOBMI-NEXT: shlq %cl, %rax 3653; X64-NOBMI-NEXT: notl %eax 3654; X64-NOBMI-NEXT: andl %edi, %eax 3655; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 3656; X64-NOBMI-NEXT: retq 3657; 3658; X64-BMI1-LABEL: bextr64_32_b0: 3659; X64-BMI1: # %bb.0: 3660; X64-BMI1-NEXT: shll $8, %edx 3661; X64-BMI1-NEXT: movzbl %sil, %eax 3662; X64-BMI1-NEXT: orl %edx, %eax 3663; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 3664; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 3665; X64-BMI1-NEXT: retq 3666; 3667; X64-BMI2-LABEL: bextr64_32_b0: 3668; X64-BMI2: # %bb.0: 3669; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 3670; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 3671; X64-BMI2-NEXT: retq 3672 %shiftedval = lshr i64 %val, %numskipbits 3673 %widenumlowbits = zext i8 %numlowbits to i64 3674 %notmask = shl nsw i64 -1, %widenumlowbits 3675 %mask = xor i64 %notmask, -1 3676 %wideres = and i64 %shiftedval, %mask 3677 %res = trunc i64 %wideres to i32 3678 ret i32 %res 3679} 3680 3681; Shifting happens in 64-bit, then truncation. Masking is 32-bit. 3682define i32 @bextr64_32_b1(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind { 3683; X86-NOBMI-LABEL: bextr64_32_b1: 3684; X86-NOBMI: # %bb.0: 3685; X86-NOBMI-NEXT: pushl %edi 3686; X86-NOBMI-NEXT: pushl %esi 3687; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 3688; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3689; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 3690; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 3691; X86-NOBMI-NEXT: movl %edi, %esi 3692; X86-NOBMI-NEXT: shrl %cl, %esi 3693; X86-NOBMI-NEXT: shrdl %cl, %edi, %eax 3694; X86-NOBMI-NEXT: testb $32, %cl 3695; X86-NOBMI-NEXT: jne .LBB32_2 3696; X86-NOBMI-NEXT: # %bb.1: 3697; X86-NOBMI-NEXT: movl %eax, %esi 3698; X86-NOBMI-NEXT: .LBB32_2: 3699; X86-NOBMI-NEXT: movl $-1, %eax 3700; X86-NOBMI-NEXT: movl %edx, %ecx 3701; X86-NOBMI-NEXT: shll %cl, %eax 3702; X86-NOBMI-NEXT: notl %eax 3703; X86-NOBMI-NEXT: andl %esi, %eax 3704; X86-NOBMI-NEXT: popl %esi 3705; X86-NOBMI-NEXT: popl %edi 3706; X86-NOBMI-NEXT: retl 3707; 3708; X86-BMI1-LABEL: bextr64_32_b1: 3709; X86-BMI1: # %bb.0: 3710; X86-BMI1-NEXT: pushl %edi 3711; X86-BMI1-NEXT: pushl %esi 3712; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3713; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3714; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 3715; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 3716; X86-BMI1-NEXT: movl %edi, %edx 3717; X86-BMI1-NEXT: shrl %cl, %edx 3718; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 3719; X86-BMI1-NEXT: testb $32, %cl 3720; X86-BMI1-NEXT: jne .LBB32_2 3721; X86-BMI1-NEXT: # %bb.1: 3722; X86-BMI1-NEXT: movl %esi, %edx 3723; X86-BMI1-NEXT: .LBB32_2: 3724; X86-BMI1-NEXT: shll $8, %eax 3725; X86-BMI1-NEXT: bextrl %eax, %edx, %eax 3726; X86-BMI1-NEXT: popl %esi 3727; X86-BMI1-NEXT: popl %edi 3728; X86-BMI1-NEXT: retl 3729; 3730; X86-BMI2-LABEL: bextr64_32_b1: 3731; X86-BMI2: # %bb.0: 3732; X86-BMI2-NEXT: pushl %esi 3733; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3734; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3735; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 3736; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 3737; X86-BMI2-NEXT: shrdl %cl, %esi, %edx 3738; X86-BMI2-NEXT: testb $32, %cl 3739; X86-BMI2-NEXT: je .LBB32_2 3740; X86-BMI2-NEXT: # %bb.1: 3741; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 3742; X86-BMI2-NEXT: .LBB32_2: 3743; X86-BMI2-NEXT: bzhil %eax, %edx, %eax 3744; X86-BMI2-NEXT: popl %esi 3745; X86-BMI2-NEXT: retl 3746; 3747; X64-NOBMI-LABEL: bextr64_32_b1: 3748; X64-NOBMI: # %bb.0: 3749; X64-NOBMI-NEXT: movq %rsi, %rcx 3750; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 3751; X64-NOBMI-NEXT: shrq %cl, %rdi 3752; X64-NOBMI-NEXT: movl $-1, %eax 3753; X64-NOBMI-NEXT: movl %edx, %ecx 3754; X64-NOBMI-NEXT: shll %cl, %eax 3755; X64-NOBMI-NEXT: notl %eax 3756; X64-NOBMI-NEXT: andl %edi, %eax 3757; X64-NOBMI-NEXT: retq 3758; 3759; X64-BMI1-LABEL: bextr64_32_b1: 3760; X64-BMI1: # %bb.0: 3761; X64-BMI1-NEXT: shll $8, %edx 3762; X64-BMI1-NEXT: movzbl %sil, %eax 3763; X64-BMI1-NEXT: orl %edx, %eax 3764; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 3765; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 3766; X64-BMI1-NEXT: retq 3767; 3768; X64-BMI2-LABEL: bextr64_32_b1: 3769; X64-BMI2: # %bb.0: 3770; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 3771; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 3772; X64-BMI2-NEXT: retq 3773 %shiftedval = lshr i64 %val, %numskipbits 3774 %truncshiftedval = trunc i64 %shiftedval to i32 3775 %widenumlowbits = zext i8 %numlowbits to i32 3776 %notmask = shl nsw i32 -1, %widenumlowbits 3777 %mask = xor i32 %notmask, -1 3778 %res = and i32 %truncshiftedval, %mask 3779 ret i32 %res 3780} 3781 3782; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit. 3783; Masking is 64-bit. Then truncation. 3784define i32 @bextr64_32_b2(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind { 3785; X86-NOBMI-LABEL: bextr64_32_b2: 3786; X86-NOBMI: # %bb.0: 3787; X86-NOBMI-NEXT: pushl %edi 3788; X86-NOBMI-NEXT: pushl %esi 3789; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 3790; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3791; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 3792; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 3793; X86-NOBMI-NEXT: movl %edi, %esi 3794; X86-NOBMI-NEXT: shrl %cl, %esi 3795; X86-NOBMI-NEXT: shrdl %cl, %edi, %eax 3796; X86-NOBMI-NEXT: testb $32, %cl 3797; X86-NOBMI-NEXT: jne .LBB33_2 3798; X86-NOBMI-NEXT: # %bb.1: 3799; X86-NOBMI-NEXT: movl %eax, %esi 3800; X86-NOBMI-NEXT: .LBB33_2: 3801; X86-NOBMI-NEXT: movl $-1, %eax 3802; X86-NOBMI-NEXT: movl %edx, %ecx 3803; X86-NOBMI-NEXT: shll %cl, %eax 3804; X86-NOBMI-NEXT: notl %eax 3805; X86-NOBMI-NEXT: andl %esi, %eax 3806; X86-NOBMI-NEXT: popl %esi 3807; X86-NOBMI-NEXT: popl %edi 3808; X86-NOBMI-NEXT: retl 3809; 3810; X86-BMI1-LABEL: bextr64_32_b2: 3811; X86-BMI1: # %bb.0: 3812; X86-BMI1-NEXT: pushl %edi 3813; X86-BMI1-NEXT: pushl %esi 3814; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3815; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3816; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 3817; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 3818; X86-BMI1-NEXT: movl %edi, %edx 3819; X86-BMI1-NEXT: shrl %cl, %edx 3820; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 3821; X86-BMI1-NEXT: testb $32, %cl 3822; X86-BMI1-NEXT: jne .LBB33_2 3823; X86-BMI1-NEXT: # %bb.1: 3824; X86-BMI1-NEXT: movl %esi, %edx 3825; X86-BMI1-NEXT: .LBB33_2: 3826; X86-BMI1-NEXT: shll $8, %eax 3827; X86-BMI1-NEXT: bextrl %eax, %edx, %eax 3828; X86-BMI1-NEXT: popl %esi 3829; X86-BMI1-NEXT: popl %edi 3830; X86-BMI1-NEXT: retl 3831; 3832; X86-BMI2-LABEL: bextr64_32_b2: 3833; X86-BMI2: # %bb.0: 3834; X86-BMI2-NEXT: pushl %esi 3835; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3836; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3837; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 3838; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 3839; X86-BMI2-NEXT: shrdl %cl, %esi, %edx 3840; X86-BMI2-NEXT: testb $32, %cl 3841; X86-BMI2-NEXT: je .LBB33_2 3842; X86-BMI2-NEXT: # %bb.1: 3843; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 3844; X86-BMI2-NEXT: .LBB33_2: 3845; X86-BMI2-NEXT: bzhil %eax, %edx, %eax 3846; X86-BMI2-NEXT: popl %esi 3847; X86-BMI2-NEXT: retl 3848; 3849; X64-NOBMI-LABEL: bextr64_32_b2: 3850; X64-NOBMI: # %bb.0: 3851; X64-NOBMI-NEXT: movq %rsi, %rcx 3852; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 3853; X64-NOBMI-NEXT: shrq %cl, %rdi 3854; X64-NOBMI-NEXT: movl $-1, %eax 3855; X64-NOBMI-NEXT: movl %edx, %ecx 3856; X64-NOBMI-NEXT: shll %cl, %eax 3857; X64-NOBMI-NEXT: notl %eax 3858; X64-NOBMI-NEXT: andl %edi, %eax 3859; X64-NOBMI-NEXT: retq 3860; 3861; X64-BMI1-LABEL: bextr64_32_b2: 3862; X64-BMI1: # %bb.0: 3863; X64-BMI1-NEXT: shll $8, %edx 3864; X64-BMI1-NEXT: movzbl %sil, %eax 3865; X64-BMI1-NEXT: orl %edx, %eax 3866; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 3867; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 3868; X64-BMI1-NEXT: retq 3869; 3870; X64-BMI2-LABEL: bextr64_32_b2: 3871; X64-BMI2: # %bb.0: 3872; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 3873; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 3874; X64-BMI2-NEXT: retq 3875 %shiftedval = lshr i64 %val, %numskipbits 3876 %widenumlowbits = zext i8 %numlowbits to i32 3877 %notmask = shl nsw i32 -1, %widenumlowbits 3878 %mask = xor i32 %notmask, -1 3879 %zextmask = zext i32 %mask to i64 3880 %wideres = and i64 %shiftedval, %zextmask 3881 %res = trunc i64 %wideres to i32 3882 ret i32 %res 3883} 3884 3885; Shifting happens in 64-bit. Mask is 32-bit, but calculated in 64-bit. 3886; Masking is 64-bit. Then truncation. 3887define i32 @bextr64_32_b3(i64 %val, i64 %numskipbits, i8 %numlowbits) nounwind { 3888; X86-NOBMI-LABEL: bextr64_32_b3: 3889; X86-NOBMI: # %bb.0: 3890; X86-NOBMI-NEXT: pushl %edi 3891; X86-NOBMI-NEXT: pushl %esi 3892; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %edx 3893; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3894; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 3895; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 3896; X86-NOBMI-NEXT: movl %edi, %eax 3897; X86-NOBMI-NEXT: shrl %cl, %eax 3898; X86-NOBMI-NEXT: shrdl %cl, %edi, %esi 3899; X86-NOBMI-NEXT: testb $32, %cl 3900; X86-NOBMI-NEXT: jne .LBB34_2 3901; X86-NOBMI-NEXT: # %bb.1: 3902; X86-NOBMI-NEXT: movl %esi, %eax 3903; X86-NOBMI-NEXT: .LBB34_2: 3904; X86-NOBMI-NEXT: movl $-1, %esi 3905; X86-NOBMI-NEXT: movl %edx, %ecx 3906; X86-NOBMI-NEXT: shll %cl, %esi 3907; X86-NOBMI-NEXT: xorl %ecx, %ecx 3908; X86-NOBMI-NEXT: testb $32, %dl 3909; X86-NOBMI-NEXT: jne .LBB34_4 3910; X86-NOBMI-NEXT: # %bb.3: 3911; X86-NOBMI-NEXT: movl %esi, %ecx 3912; X86-NOBMI-NEXT: .LBB34_4: 3913; X86-NOBMI-NEXT: notl %ecx 3914; X86-NOBMI-NEXT: andl %ecx, %eax 3915; X86-NOBMI-NEXT: popl %esi 3916; X86-NOBMI-NEXT: popl %edi 3917; X86-NOBMI-NEXT: retl 3918; 3919; X86-BMI1-LABEL: bextr64_32_b3: 3920; X86-BMI1: # %bb.0: 3921; X86-BMI1-NEXT: pushl %edi 3922; X86-BMI1-NEXT: pushl %esi 3923; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3924; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3925; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 3926; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 3927; X86-BMI1-NEXT: movl %edi, %edx 3928; X86-BMI1-NEXT: shrl %cl, %edx 3929; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 3930; X86-BMI1-NEXT: testb $32, %cl 3931; X86-BMI1-NEXT: jne .LBB34_2 3932; X86-BMI1-NEXT: # %bb.1: 3933; X86-BMI1-NEXT: movl %esi, %edx 3934; X86-BMI1-NEXT: .LBB34_2: 3935; X86-BMI1-NEXT: movl $-1, %esi 3936; X86-BMI1-NEXT: movl %eax, %ecx 3937; X86-BMI1-NEXT: shll %cl, %esi 3938; X86-BMI1-NEXT: xorl %ecx, %ecx 3939; X86-BMI1-NEXT: testb $32, %al 3940; X86-BMI1-NEXT: jne .LBB34_4 3941; X86-BMI1-NEXT: # %bb.3: 3942; X86-BMI1-NEXT: movl %esi, %ecx 3943; X86-BMI1-NEXT: .LBB34_4: 3944; X86-BMI1-NEXT: andnl %edx, %ecx, %eax 3945; X86-BMI1-NEXT: popl %esi 3946; X86-BMI1-NEXT: popl %edi 3947; X86-BMI1-NEXT: retl 3948; 3949; X86-BMI2-LABEL: bextr64_32_b3: 3950; X86-BMI2: # %bb.0: 3951; X86-BMI2-NEXT: pushl %esi 3952; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 3953; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 3954; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 3955; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 3956; X86-BMI2-NEXT: shrdl %cl, %esi, %edx 3957; X86-BMI2-NEXT: testb $32, %cl 3958; X86-BMI2-NEXT: je .LBB34_2 3959; X86-BMI2-NEXT: # %bb.1: 3960; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 3961; X86-BMI2-NEXT: .LBB34_2: 3962; X86-BMI2-NEXT: xorl %ecx, %ecx 3963; X86-BMI2-NEXT: testb $32, %al 3964; X86-BMI2-NEXT: jne .LBB34_4 3965; X86-BMI2-NEXT: # %bb.3: 3966; X86-BMI2-NEXT: movl $-1, %ecx 3967; X86-BMI2-NEXT: shlxl %eax, %ecx, %ecx 3968; X86-BMI2-NEXT: .LBB34_4: 3969; X86-BMI2-NEXT: andnl %edx, %ecx, %eax 3970; X86-BMI2-NEXT: popl %esi 3971; X86-BMI2-NEXT: retl 3972; 3973; X64-NOBMI-LABEL: bextr64_32_b3: 3974; X64-NOBMI: # %bb.0: 3975; X64-NOBMI-NEXT: movq %rsi, %rcx 3976; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 3977; X64-NOBMI-NEXT: shrq %cl, %rdi 3978; X64-NOBMI-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 3979; X64-NOBMI-NEXT: movl $4294967295, %esi # imm = 0xFFFFFFFF 3980; X64-NOBMI-NEXT: movl %edx, %ecx 3981; X64-NOBMI-NEXT: shlq %cl, %rsi 3982; X64-NOBMI-NEXT: xorl %esi, %eax 3983; X64-NOBMI-NEXT: andl %edi, %eax 3984; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 3985; X64-NOBMI-NEXT: retq 3986; 3987; X64-BMI1-LABEL: bextr64_32_b3: 3988; X64-BMI1: # %bb.0: 3989; X64-BMI1-NEXT: shll $8, %edx 3990; X64-BMI1-NEXT: movzbl %sil, %eax 3991; X64-BMI1-NEXT: orl %edx, %eax 3992; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 3993; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 3994; X64-BMI1-NEXT: retq 3995; 3996; X64-BMI2-LABEL: bextr64_32_b3: 3997; X64-BMI2: # %bb.0: 3998; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 3999; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 4000; X64-BMI2-NEXT: retq 4001 %shiftedval = lshr i64 %val, %numskipbits 4002 %widenumlowbits = zext i8 %numlowbits to i64 4003 %notmask = shl nsw i64 4294967295, %widenumlowbits 4004 %mask = xor i64 %notmask, 4294967295 4005 %wideres = and i64 %shiftedval, %mask 4006 %res = trunc i64 %wideres to i32 4007 ret i32 %res 4008} 4009 4010; ---------------------------------------------------------------------------- ; 4011; Pattern c. 32-bit 4012; ---------------------------------------------------------------------------- ; 4013 4014define i32 @bextr32_c0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 4015; X86-NOBMI-LABEL: bextr32_c0: 4016; X86-NOBMI: # %bb.0: 4017; X86-NOBMI-NEXT: pushl %edi 4018; X86-NOBMI-NEXT: pushl %esi 4019; X86-NOBMI-NEXT: pushl %eax 4020; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4021; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 4022; X86-NOBMI-NEXT: shrl %cl, %edi 4023; X86-NOBMI-NEXT: xorl %ecx, %ecx 4024; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 4025; X86-NOBMI-NEXT: movl $-1, %esi 4026; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4027; X86-NOBMI-NEXT: shrl %cl, %esi 4028; X86-NOBMI-NEXT: movl %esi, (%esp) 4029; X86-NOBMI-NEXT: calll use32@PLT 4030; X86-NOBMI-NEXT: andl %edi, %esi 4031; X86-NOBMI-NEXT: movl %esi, %eax 4032; X86-NOBMI-NEXT: addl $4, %esp 4033; X86-NOBMI-NEXT: popl %esi 4034; X86-NOBMI-NEXT: popl %edi 4035; X86-NOBMI-NEXT: retl 4036; 4037; X86-BMI1-LABEL: bextr32_c0: 4038; X86-BMI1: # %bb.0: 4039; X86-BMI1-NEXT: pushl %edi 4040; X86-BMI1-NEXT: pushl %esi 4041; X86-BMI1-NEXT: pushl %eax 4042; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4043; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 4044; X86-BMI1-NEXT: shrl %cl, %edi 4045; X86-BMI1-NEXT: xorl %ecx, %ecx 4046; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 4047; X86-BMI1-NEXT: movl $-1, %esi 4048; X86-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4049; X86-BMI1-NEXT: shrl %cl, %esi 4050; X86-BMI1-NEXT: movl %esi, (%esp) 4051; X86-BMI1-NEXT: calll use32@PLT 4052; X86-BMI1-NEXT: andl %edi, %esi 4053; X86-BMI1-NEXT: movl %esi, %eax 4054; X86-BMI1-NEXT: addl $4, %esp 4055; X86-BMI1-NEXT: popl %esi 4056; X86-BMI1-NEXT: popl %edi 4057; X86-BMI1-NEXT: retl 4058; 4059; X86-BMI2-LABEL: bextr32_c0: 4060; X86-BMI2: # %bb.0: 4061; X86-BMI2-NEXT: pushl %ebx 4062; X86-BMI2-NEXT: pushl %esi 4063; X86-BMI2-NEXT: pushl %eax 4064; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 4065; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 4066; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %esi 4067; X86-BMI2-NEXT: movl $-1, %eax 4068; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax 4069; X86-BMI2-NEXT: movl %eax, (%esp) 4070; X86-BMI2-NEXT: calll use32@PLT 4071; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax 4072; X86-BMI2-NEXT: addl $4, %esp 4073; X86-BMI2-NEXT: popl %esi 4074; X86-BMI2-NEXT: popl %ebx 4075; X86-BMI2-NEXT: retl 4076; 4077; X64-NOBMI-LABEL: bextr32_c0: 4078; X64-NOBMI: # %bb.0: 4079; X64-NOBMI-NEXT: pushq %rbp 4080; X64-NOBMI-NEXT: pushq %rbx 4081; X64-NOBMI-NEXT: pushq %rax 4082; X64-NOBMI-NEXT: movl %esi, %ecx 4083; X64-NOBMI-NEXT: movl %edi, %ebx 4084; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4085; X64-NOBMI-NEXT: shrl %cl, %ebx 4086; X64-NOBMI-NEXT: negb %dl 4087; X64-NOBMI-NEXT: movl $-1, %ebp 4088; X64-NOBMI-NEXT: movl %edx, %ecx 4089; X64-NOBMI-NEXT: shrl %cl, %ebp 4090; X64-NOBMI-NEXT: movl %ebp, %edi 4091; X64-NOBMI-NEXT: callq use32@PLT 4092; X64-NOBMI-NEXT: andl %ebx, %ebp 4093; X64-NOBMI-NEXT: movl %ebp, %eax 4094; X64-NOBMI-NEXT: addq $8, %rsp 4095; X64-NOBMI-NEXT: popq %rbx 4096; X64-NOBMI-NEXT: popq %rbp 4097; X64-NOBMI-NEXT: retq 4098; 4099; X64-BMI1-LABEL: bextr32_c0: 4100; X64-BMI1: # %bb.0: 4101; X64-BMI1-NEXT: pushq %rbp 4102; X64-BMI1-NEXT: pushq %rbx 4103; X64-BMI1-NEXT: pushq %rax 4104; X64-BMI1-NEXT: movl %esi, %ecx 4105; X64-BMI1-NEXT: movl %edi, %ebx 4106; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4107; X64-BMI1-NEXT: shrl %cl, %ebx 4108; X64-BMI1-NEXT: negb %dl 4109; X64-BMI1-NEXT: movl $-1, %ebp 4110; X64-BMI1-NEXT: movl %edx, %ecx 4111; X64-BMI1-NEXT: shrl %cl, %ebp 4112; X64-BMI1-NEXT: movl %ebp, %edi 4113; X64-BMI1-NEXT: callq use32@PLT 4114; X64-BMI1-NEXT: andl %ebx, %ebp 4115; X64-BMI1-NEXT: movl %ebp, %eax 4116; X64-BMI1-NEXT: addq $8, %rsp 4117; X64-BMI1-NEXT: popq %rbx 4118; X64-BMI1-NEXT: popq %rbp 4119; X64-BMI1-NEXT: retq 4120; 4121; X64-BMI2-LABEL: bextr32_c0: 4122; X64-BMI2: # %bb.0: 4123; X64-BMI2-NEXT: pushq %rbp 4124; X64-BMI2-NEXT: pushq %rbx 4125; X64-BMI2-NEXT: pushq %rax 4126; X64-BMI2-NEXT: movl %edx, %ebx 4127; X64-BMI2-NEXT: shrxl %esi, %edi, %ebp 4128; X64-BMI2-NEXT: movl $-1, %eax 4129; X64-BMI2-NEXT: bzhil %edx, %eax, %edi 4130; X64-BMI2-NEXT: callq use32@PLT 4131; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax 4132; X64-BMI2-NEXT: addq $8, %rsp 4133; X64-BMI2-NEXT: popq %rbx 4134; X64-BMI2-NEXT: popq %rbp 4135; X64-BMI2-NEXT: retq 4136 %shifted = lshr i32 %val, %numskipbits 4137 %numhighbits = sub i32 32, %numlowbits 4138 %mask = lshr i32 -1, %numhighbits 4139 call void @use32(i32 %mask) 4140 %masked = and i32 %mask, %shifted 4141 ret i32 %masked 4142} 4143 4144define i32 @bextr32_c1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind { 4145; X86-NOBMI-LABEL: bextr32_c1_indexzext: 4146; X86-NOBMI: # %bb.0: 4147; X86-NOBMI-NEXT: pushl %edi 4148; X86-NOBMI-NEXT: pushl %esi 4149; X86-NOBMI-NEXT: pushl %eax 4150; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4151; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 4152; X86-NOBMI-NEXT: shrl %cl, %edi 4153; X86-NOBMI-NEXT: xorl %ecx, %ecx 4154; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 4155; X86-NOBMI-NEXT: movl $-1, %esi 4156; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4157; X86-NOBMI-NEXT: shrl %cl, %esi 4158; X86-NOBMI-NEXT: movl %esi, (%esp) 4159; X86-NOBMI-NEXT: calll use32@PLT 4160; X86-NOBMI-NEXT: andl %edi, %esi 4161; X86-NOBMI-NEXT: movl %esi, %eax 4162; X86-NOBMI-NEXT: addl $4, %esp 4163; X86-NOBMI-NEXT: popl %esi 4164; X86-NOBMI-NEXT: popl %edi 4165; X86-NOBMI-NEXT: retl 4166; 4167; X86-BMI1-LABEL: bextr32_c1_indexzext: 4168; X86-BMI1: # %bb.0: 4169; X86-BMI1-NEXT: pushl %edi 4170; X86-BMI1-NEXT: pushl %esi 4171; X86-BMI1-NEXT: pushl %eax 4172; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4173; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 4174; X86-BMI1-NEXT: shrl %cl, %edi 4175; X86-BMI1-NEXT: xorl %ecx, %ecx 4176; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 4177; X86-BMI1-NEXT: movl $-1, %esi 4178; X86-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4179; X86-BMI1-NEXT: shrl %cl, %esi 4180; X86-BMI1-NEXT: movl %esi, (%esp) 4181; X86-BMI1-NEXT: calll use32@PLT 4182; X86-BMI1-NEXT: andl %edi, %esi 4183; X86-BMI1-NEXT: movl %esi, %eax 4184; X86-BMI1-NEXT: addl $4, %esp 4185; X86-BMI1-NEXT: popl %esi 4186; X86-BMI1-NEXT: popl %edi 4187; X86-BMI1-NEXT: retl 4188; 4189; X86-BMI2-LABEL: bextr32_c1_indexzext: 4190; X86-BMI2: # %bb.0: 4191; X86-BMI2-NEXT: pushl %ebx 4192; X86-BMI2-NEXT: pushl %esi 4193; X86-BMI2-NEXT: pushl %eax 4194; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 4195; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 4196; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %esi 4197; X86-BMI2-NEXT: movl $-1, %eax 4198; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax 4199; X86-BMI2-NEXT: movl %eax, (%esp) 4200; X86-BMI2-NEXT: calll use32@PLT 4201; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax 4202; X86-BMI2-NEXT: addl $4, %esp 4203; X86-BMI2-NEXT: popl %esi 4204; X86-BMI2-NEXT: popl %ebx 4205; X86-BMI2-NEXT: retl 4206; 4207; X64-NOBMI-LABEL: bextr32_c1_indexzext: 4208; X64-NOBMI: # %bb.0: 4209; X64-NOBMI-NEXT: pushq %rbp 4210; X64-NOBMI-NEXT: pushq %rbx 4211; X64-NOBMI-NEXT: pushq %rax 4212; X64-NOBMI-NEXT: movl %esi, %ecx 4213; X64-NOBMI-NEXT: movl %edi, %ebx 4214; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4215; X64-NOBMI-NEXT: shrl %cl, %ebx 4216; X64-NOBMI-NEXT: negb %dl 4217; X64-NOBMI-NEXT: movl $-1, %ebp 4218; X64-NOBMI-NEXT: movl %edx, %ecx 4219; X64-NOBMI-NEXT: shrl %cl, %ebp 4220; X64-NOBMI-NEXT: movl %ebp, %edi 4221; X64-NOBMI-NEXT: callq use32@PLT 4222; X64-NOBMI-NEXT: andl %ebx, %ebp 4223; X64-NOBMI-NEXT: movl %ebp, %eax 4224; X64-NOBMI-NEXT: addq $8, %rsp 4225; X64-NOBMI-NEXT: popq %rbx 4226; X64-NOBMI-NEXT: popq %rbp 4227; X64-NOBMI-NEXT: retq 4228; 4229; X64-BMI1-LABEL: bextr32_c1_indexzext: 4230; X64-BMI1: # %bb.0: 4231; X64-BMI1-NEXT: pushq %rbp 4232; X64-BMI1-NEXT: pushq %rbx 4233; X64-BMI1-NEXT: pushq %rax 4234; X64-BMI1-NEXT: movl %esi, %ecx 4235; X64-BMI1-NEXT: movl %edi, %ebx 4236; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4237; X64-BMI1-NEXT: shrl %cl, %ebx 4238; X64-BMI1-NEXT: negb %dl 4239; X64-BMI1-NEXT: movl $-1, %ebp 4240; X64-BMI1-NEXT: movl %edx, %ecx 4241; X64-BMI1-NEXT: shrl %cl, %ebp 4242; X64-BMI1-NEXT: movl %ebp, %edi 4243; X64-BMI1-NEXT: callq use32@PLT 4244; X64-BMI1-NEXT: andl %ebx, %ebp 4245; X64-BMI1-NEXT: movl %ebp, %eax 4246; X64-BMI1-NEXT: addq $8, %rsp 4247; X64-BMI1-NEXT: popq %rbx 4248; X64-BMI1-NEXT: popq %rbp 4249; X64-BMI1-NEXT: retq 4250; 4251; X64-BMI2-LABEL: bextr32_c1_indexzext: 4252; X64-BMI2: # %bb.0: 4253; X64-BMI2-NEXT: pushq %rbp 4254; X64-BMI2-NEXT: pushq %rbx 4255; X64-BMI2-NEXT: pushq %rax 4256; X64-BMI2-NEXT: movl %edx, %ebx 4257; X64-BMI2-NEXT: shrxl %esi, %edi, %ebp 4258; X64-BMI2-NEXT: movl $-1, %eax 4259; X64-BMI2-NEXT: bzhil %edx, %eax, %edi 4260; X64-BMI2-NEXT: callq use32@PLT 4261; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax 4262; X64-BMI2-NEXT: addq $8, %rsp 4263; X64-BMI2-NEXT: popq %rbx 4264; X64-BMI2-NEXT: popq %rbp 4265; X64-BMI2-NEXT: retq 4266 %skip = zext i8 %numskipbits to i32 4267 %shifted = lshr i32 %val, %skip 4268 %numhighbits = sub i8 32, %numlowbits 4269 %sh_prom = zext i8 %numhighbits to i32 4270 %mask = lshr i32 -1, %sh_prom 4271 call void @use32(i32 %mask) 4272 %masked = and i32 %mask, %shifted 4273 ret i32 %masked 4274} 4275 4276define i32 @bextr32_c2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind { 4277; X86-NOBMI-LABEL: bextr32_c2_load: 4278; X86-NOBMI: # %bb.0: 4279; X86-NOBMI-NEXT: pushl %edi 4280; X86-NOBMI-NEXT: pushl %esi 4281; X86-NOBMI-NEXT: pushl %eax 4282; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4283; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 4284; X86-NOBMI-NEXT: movl (%eax), %edi 4285; X86-NOBMI-NEXT: shrl %cl, %edi 4286; X86-NOBMI-NEXT: xorl %ecx, %ecx 4287; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 4288; X86-NOBMI-NEXT: movl $-1, %esi 4289; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4290; X86-NOBMI-NEXT: shrl %cl, %esi 4291; X86-NOBMI-NEXT: movl %esi, (%esp) 4292; X86-NOBMI-NEXT: calll use32@PLT 4293; X86-NOBMI-NEXT: andl %edi, %esi 4294; X86-NOBMI-NEXT: movl %esi, %eax 4295; X86-NOBMI-NEXT: addl $4, %esp 4296; X86-NOBMI-NEXT: popl %esi 4297; X86-NOBMI-NEXT: popl %edi 4298; X86-NOBMI-NEXT: retl 4299; 4300; X86-BMI1-LABEL: bextr32_c2_load: 4301; X86-BMI1: # %bb.0: 4302; X86-BMI1-NEXT: pushl %edi 4303; X86-BMI1-NEXT: pushl %esi 4304; X86-BMI1-NEXT: pushl %eax 4305; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4306; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 4307; X86-BMI1-NEXT: movl (%eax), %edi 4308; X86-BMI1-NEXT: shrl %cl, %edi 4309; X86-BMI1-NEXT: xorl %ecx, %ecx 4310; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 4311; X86-BMI1-NEXT: movl $-1, %esi 4312; X86-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4313; X86-BMI1-NEXT: shrl %cl, %esi 4314; X86-BMI1-NEXT: movl %esi, (%esp) 4315; X86-BMI1-NEXT: calll use32@PLT 4316; X86-BMI1-NEXT: andl %edi, %esi 4317; X86-BMI1-NEXT: movl %esi, %eax 4318; X86-BMI1-NEXT: addl $4, %esp 4319; X86-BMI1-NEXT: popl %esi 4320; X86-BMI1-NEXT: popl %edi 4321; X86-BMI1-NEXT: retl 4322; 4323; X86-BMI2-LABEL: bextr32_c2_load: 4324; X86-BMI2: # %bb.0: 4325; X86-BMI2-NEXT: pushl %ebx 4326; X86-BMI2-NEXT: pushl %esi 4327; X86-BMI2-NEXT: pushl %eax 4328; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 4329; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 4330; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4331; X86-BMI2-NEXT: shrxl %ecx, (%eax), %esi 4332; X86-BMI2-NEXT: movl $-1, %eax 4333; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax 4334; X86-BMI2-NEXT: movl %eax, (%esp) 4335; X86-BMI2-NEXT: calll use32@PLT 4336; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax 4337; X86-BMI2-NEXT: addl $4, %esp 4338; X86-BMI2-NEXT: popl %esi 4339; X86-BMI2-NEXT: popl %ebx 4340; X86-BMI2-NEXT: retl 4341; 4342; X64-NOBMI-LABEL: bextr32_c2_load: 4343; X64-NOBMI: # %bb.0: 4344; X64-NOBMI-NEXT: pushq %rbp 4345; X64-NOBMI-NEXT: pushq %rbx 4346; X64-NOBMI-NEXT: pushq %rax 4347; X64-NOBMI-NEXT: movl %esi, %ecx 4348; X64-NOBMI-NEXT: movl (%rdi), %ebp 4349; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4350; X64-NOBMI-NEXT: shrl %cl, %ebp 4351; X64-NOBMI-NEXT: negb %dl 4352; X64-NOBMI-NEXT: movl $-1, %ebx 4353; X64-NOBMI-NEXT: movl %edx, %ecx 4354; X64-NOBMI-NEXT: shrl %cl, %ebx 4355; X64-NOBMI-NEXT: movl %ebx, %edi 4356; X64-NOBMI-NEXT: callq use32@PLT 4357; X64-NOBMI-NEXT: andl %ebp, %ebx 4358; X64-NOBMI-NEXT: movl %ebx, %eax 4359; X64-NOBMI-NEXT: addq $8, %rsp 4360; X64-NOBMI-NEXT: popq %rbx 4361; X64-NOBMI-NEXT: popq %rbp 4362; X64-NOBMI-NEXT: retq 4363; 4364; X64-BMI1-LABEL: bextr32_c2_load: 4365; X64-BMI1: # %bb.0: 4366; X64-BMI1-NEXT: pushq %rbp 4367; X64-BMI1-NEXT: pushq %rbx 4368; X64-BMI1-NEXT: pushq %rax 4369; X64-BMI1-NEXT: movl %esi, %ecx 4370; X64-BMI1-NEXT: movl (%rdi), %ebp 4371; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4372; X64-BMI1-NEXT: shrl %cl, %ebp 4373; X64-BMI1-NEXT: negb %dl 4374; X64-BMI1-NEXT: movl $-1, %ebx 4375; X64-BMI1-NEXT: movl %edx, %ecx 4376; X64-BMI1-NEXT: shrl %cl, %ebx 4377; X64-BMI1-NEXT: movl %ebx, %edi 4378; X64-BMI1-NEXT: callq use32@PLT 4379; X64-BMI1-NEXT: andl %ebp, %ebx 4380; X64-BMI1-NEXT: movl %ebx, %eax 4381; X64-BMI1-NEXT: addq $8, %rsp 4382; X64-BMI1-NEXT: popq %rbx 4383; X64-BMI1-NEXT: popq %rbp 4384; X64-BMI1-NEXT: retq 4385; 4386; X64-BMI2-LABEL: bextr32_c2_load: 4387; X64-BMI2: # %bb.0: 4388; X64-BMI2-NEXT: pushq %rbp 4389; X64-BMI2-NEXT: pushq %rbx 4390; X64-BMI2-NEXT: pushq %rax 4391; X64-BMI2-NEXT: movl %edx, %ebx 4392; X64-BMI2-NEXT: shrxl %esi, (%rdi), %ebp 4393; X64-BMI2-NEXT: movl $-1, %eax 4394; X64-BMI2-NEXT: bzhil %edx, %eax, %edi 4395; X64-BMI2-NEXT: callq use32@PLT 4396; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax 4397; X64-BMI2-NEXT: addq $8, %rsp 4398; X64-BMI2-NEXT: popq %rbx 4399; X64-BMI2-NEXT: popq %rbp 4400; X64-BMI2-NEXT: retq 4401 %val = load i32, ptr %w 4402 %shifted = lshr i32 %val, %numskipbits 4403 %numhighbits = sub i32 32, %numlowbits 4404 %mask = lshr i32 -1, %numhighbits 4405 call void @use32(i32 %mask) 4406 %masked = and i32 %mask, %shifted 4407 ret i32 %masked 4408} 4409 4410define i32 @bextr32_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind { 4411; X86-NOBMI-LABEL: bextr32_c3_load_indexzext: 4412; X86-NOBMI: # %bb.0: 4413; X86-NOBMI-NEXT: pushl %edi 4414; X86-NOBMI-NEXT: pushl %esi 4415; X86-NOBMI-NEXT: pushl %eax 4416; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4417; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 4418; X86-NOBMI-NEXT: movl (%eax), %edi 4419; X86-NOBMI-NEXT: shrl %cl, %edi 4420; X86-NOBMI-NEXT: xorl %ecx, %ecx 4421; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 4422; X86-NOBMI-NEXT: movl $-1, %esi 4423; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4424; X86-NOBMI-NEXT: shrl %cl, %esi 4425; X86-NOBMI-NEXT: movl %esi, (%esp) 4426; X86-NOBMI-NEXT: calll use32@PLT 4427; X86-NOBMI-NEXT: andl %edi, %esi 4428; X86-NOBMI-NEXT: movl %esi, %eax 4429; X86-NOBMI-NEXT: addl $4, %esp 4430; X86-NOBMI-NEXT: popl %esi 4431; X86-NOBMI-NEXT: popl %edi 4432; X86-NOBMI-NEXT: retl 4433; 4434; X86-BMI1-LABEL: bextr32_c3_load_indexzext: 4435; X86-BMI1: # %bb.0: 4436; X86-BMI1-NEXT: pushl %edi 4437; X86-BMI1-NEXT: pushl %esi 4438; X86-BMI1-NEXT: pushl %eax 4439; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4440; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 4441; X86-BMI1-NEXT: movl (%eax), %edi 4442; X86-BMI1-NEXT: shrl %cl, %edi 4443; X86-BMI1-NEXT: xorl %ecx, %ecx 4444; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 4445; X86-BMI1-NEXT: movl $-1, %esi 4446; X86-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4447; X86-BMI1-NEXT: shrl %cl, %esi 4448; X86-BMI1-NEXT: movl %esi, (%esp) 4449; X86-BMI1-NEXT: calll use32@PLT 4450; X86-BMI1-NEXT: andl %edi, %esi 4451; X86-BMI1-NEXT: movl %esi, %eax 4452; X86-BMI1-NEXT: addl $4, %esp 4453; X86-BMI1-NEXT: popl %esi 4454; X86-BMI1-NEXT: popl %edi 4455; X86-BMI1-NEXT: retl 4456; 4457; X86-BMI2-LABEL: bextr32_c3_load_indexzext: 4458; X86-BMI2: # %bb.0: 4459; X86-BMI2-NEXT: pushl %ebx 4460; X86-BMI2-NEXT: pushl %esi 4461; X86-BMI2-NEXT: pushl %eax 4462; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 4463; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 4464; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4465; X86-BMI2-NEXT: shrxl %ecx, (%eax), %esi 4466; X86-BMI2-NEXT: movl $-1, %eax 4467; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax 4468; X86-BMI2-NEXT: movl %eax, (%esp) 4469; X86-BMI2-NEXT: calll use32@PLT 4470; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax 4471; X86-BMI2-NEXT: addl $4, %esp 4472; X86-BMI2-NEXT: popl %esi 4473; X86-BMI2-NEXT: popl %ebx 4474; X86-BMI2-NEXT: retl 4475; 4476; X64-NOBMI-LABEL: bextr32_c3_load_indexzext: 4477; X64-NOBMI: # %bb.0: 4478; X64-NOBMI-NEXT: pushq %rbp 4479; X64-NOBMI-NEXT: pushq %rbx 4480; X64-NOBMI-NEXT: pushq %rax 4481; X64-NOBMI-NEXT: movl %esi, %ecx 4482; X64-NOBMI-NEXT: movl (%rdi), %ebp 4483; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4484; X64-NOBMI-NEXT: shrl %cl, %ebp 4485; X64-NOBMI-NEXT: negb %dl 4486; X64-NOBMI-NEXT: movl $-1, %ebx 4487; X64-NOBMI-NEXT: movl %edx, %ecx 4488; X64-NOBMI-NEXT: shrl %cl, %ebx 4489; X64-NOBMI-NEXT: movl %ebx, %edi 4490; X64-NOBMI-NEXT: callq use32@PLT 4491; X64-NOBMI-NEXT: andl %ebp, %ebx 4492; X64-NOBMI-NEXT: movl %ebx, %eax 4493; X64-NOBMI-NEXT: addq $8, %rsp 4494; X64-NOBMI-NEXT: popq %rbx 4495; X64-NOBMI-NEXT: popq %rbp 4496; X64-NOBMI-NEXT: retq 4497; 4498; X64-BMI1-LABEL: bextr32_c3_load_indexzext: 4499; X64-BMI1: # %bb.0: 4500; X64-BMI1-NEXT: pushq %rbp 4501; X64-BMI1-NEXT: pushq %rbx 4502; X64-BMI1-NEXT: pushq %rax 4503; X64-BMI1-NEXT: movl %esi, %ecx 4504; X64-BMI1-NEXT: movl (%rdi), %ebp 4505; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4506; X64-BMI1-NEXT: shrl %cl, %ebp 4507; X64-BMI1-NEXT: negb %dl 4508; X64-BMI1-NEXT: movl $-1, %ebx 4509; X64-BMI1-NEXT: movl %edx, %ecx 4510; X64-BMI1-NEXT: shrl %cl, %ebx 4511; X64-BMI1-NEXT: movl %ebx, %edi 4512; X64-BMI1-NEXT: callq use32@PLT 4513; X64-BMI1-NEXT: andl %ebp, %ebx 4514; X64-BMI1-NEXT: movl %ebx, %eax 4515; X64-BMI1-NEXT: addq $8, %rsp 4516; X64-BMI1-NEXT: popq %rbx 4517; X64-BMI1-NEXT: popq %rbp 4518; X64-BMI1-NEXT: retq 4519; 4520; X64-BMI2-LABEL: bextr32_c3_load_indexzext: 4521; X64-BMI2: # %bb.0: 4522; X64-BMI2-NEXT: pushq %rbp 4523; X64-BMI2-NEXT: pushq %rbx 4524; X64-BMI2-NEXT: pushq %rax 4525; X64-BMI2-NEXT: movl %edx, %ebx 4526; X64-BMI2-NEXT: shrxl %esi, (%rdi), %ebp 4527; X64-BMI2-NEXT: movl $-1, %eax 4528; X64-BMI2-NEXT: bzhil %edx, %eax, %edi 4529; X64-BMI2-NEXT: callq use32@PLT 4530; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax 4531; X64-BMI2-NEXT: addq $8, %rsp 4532; X64-BMI2-NEXT: popq %rbx 4533; X64-BMI2-NEXT: popq %rbp 4534; X64-BMI2-NEXT: retq 4535 %val = load i32, ptr %w 4536 %skip = zext i8 %numskipbits to i32 4537 %shifted = lshr i32 %val, %skip 4538 %numhighbits = sub i8 32, %numlowbits 4539 %sh_prom = zext i8 %numhighbits to i32 4540 %mask = lshr i32 -1, %sh_prom 4541 call void @use32(i32 %mask) 4542 %masked = and i32 %mask, %shifted 4543 ret i32 %masked 4544} 4545 4546define i32 @bextr32_c4_commutative(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 4547; X86-NOBMI-LABEL: bextr32_c4_commutative: 4548; X86-NOBMI: # %bb.0: 4549; X86-NOBMI-NEXT: pushl %edi 4550; X86-NOBMI-NEXT: pushl %esi 4551; X86-NOBMI-NEXT: pushl %eax 4552; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4553; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 4554; X86-NOBMI-NEXT: shrl %cl, %edi 4555; X86-NOBMI-NEXT: xorl %ecx, %ecx 4556; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 4557; X86-NOBMI-NEXT: movl $-1, %esi 4558; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4559; X86-NOBMI-NEXT: shrl %cl, %esi 4560; X86-NOBMI-NEXT: movl %esi, (%esp) 4561; X86-NOBMI-NEXT: calll use32@PLT 4562; X86-NOBMI-NEXT: andl %edi, %esi 4563; X86-NOBMI-NEXT: movl %esi, %eax 4564; X86-NOBMI-NEXT: addl $4, %esp 4565; X86-NOBMI-NEXT: popl %esi 4566; X86-NOBMI-NEXT: popl %edi 4567; X86-NOBMI-NEXT: retl 4568; 4569; X86-BMI1-LABEL: bextr32_c4_commutative: 4570; X86-BMI1: # %bb.0: 4571; X86-BMI1-NEXT: pushl %edi 4572; X86-BMI1-NEXT: pushl %esi 4573; X86-BMI1-NEXT: pushl %eax 4574; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4575; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 4576; X86-BMI1-NEXT: shrl %cl, %edi 4577; X86-BMI1-NEXT: xorl %ecx, %ecx 4578; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 4579; X86-BMI1-NEXT: movl $-1, %esi 4580; X86-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4581; X86-BMI1-NEXT: shrl %cl, %esi 4582; X86-BMI1-NEXT: movl %esi, (%esp) 4583; X86-BMI1-NEXT: calll use32@PLT 4584; X86-BMI1-NEXT: andl %edi, %esi 4585; X86-BMI1-NEXT: movl %esi, %eax 4586; X86-BMI1-NEXT: addl $4, %esp 4587; X86-BMI1-NEXT: popl %esi 4588; X86-BMI1-NEXT: popl %edi 4589; X86-BMI1-NEXT: retl 4590; 4591; X86-BMI2-LABEL: bextr32_c4_commutative: 4592; X86-BMI2: # %bb.0: 4593; X86-BMI2-NEXT: pushl %ebx 4594; X86-BMI2-NEXT: pushl %esi 4595; X86-BMI2-NEXT: pushl %eax 4596; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 4597; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 4598; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %esi 4599; X86-BMI2-NEXT: movl $-1, %eax 4600; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax 4601; X86-BMI2-NEXT: movl %eax, (%esp) 4602; X86-BMI2-NEXT: calll use32@PLT 4603; X86-BMI2-NEXT: bzhil %ebx, %esi, %eax 4604; X86-BMI2-NEXT: addl $4, %esp 4605; X86-BMI2-NEXT: popl %esi 4606; X86-BMI2-NEXT: popl %ebx 4607; X86-BMI2-NEXT: retl 4608; 4609; X64-NOBMI-LABEL: bextr32_c4_commutative: 4610; X64-NOBMI: # %bb.0: 4611; X64-NOBMI-NEXT: pushq %rbp 4612; X64-NOBMI-NEXT: pushq %rbx 4613; X64-NOBMI-NEXT: pushq %rax 4614; X64-NOBMI-NEXT: movl %esi, %ecx 4615; X64-NOBMI-NEXT: movl %edi, %ebx 4616; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4617; X64-NOBMI-NEXT: shrl %cl, %ebx 4618; X64-NOBMI-NEXT: negb %dl 4619; X64-NOBMI-NEXT: movl $-1, %ebp 4620; X64-NOBMI-NEXT: movl %edx, %ecx 4621; X64-NOBMI-NEXT: shrl %cl, %ebp 4622; X64-NOBMI-NEXT: movl %ebp, %edi 4623; X64-NOBMI-NEXT: callq use32@PLT 4624; X64-NOBMI-NEXT: andl %ebx, %ebp 4625; X64-NOBMI-NEXT: movl %ebp, %eax 4626; X64-NOBMI-NEXT: addq $8, %rsp 4627; X64-NOBMI-NEXT: popq %rbx 4628; X64-NOBMI-NEXT: popq %rbp 4629; X64-NOBMI-NEXT: retq 4630; 4631; X64-BMI1-LABEL: bextr32_c4_commutative: 4632; X64-BMI1: # %bb.0: 4633; X64-BMI1-NEXT: pushq %rbp 4634; X64-BMI1-NEXT: pushq %rbx 4635; X64-BMI1-NEXT: pushq %rax 4636; X64-BMI1-NEXT: movl %esi, %ecx 4637; X64-BMI1-NEXT: movl %edi, %ebx 4638; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4639; X64-BMI1-NEXT: shrl %cl, %ebx 4640; X64-BMI1-NEXT: negb %dl 4641; X64-BMI1-NEXT: movl $-1, %ebp 4642; X64-BMI1-NEXT: movl %edx, %ecx 4643; X64-BMI1-NEXT: shrl %cl, %ebp 4644; X64-BMI1-NEXT: movl %ebp, %edi 4645; X64-BMI1-NEXT: callq use32@PLT 4646; X64-BMI1-NEXT: andl %ebx, %ebp 4647; X64-BMI1-NEXT: movl %ebp, %eax 4648; X64-BMI1-NEXT: addq $8, %rsp 4649; X64-BMI1-NEXT: popq %rbx 4650; X64-BMI1-NEXT: popq %rbp 4651; X64-BMI1-NEXT: retq 4652; 4653; X64-BMI2-LABEL: bextr32_c4_commutative: 4654; X64-BMI2: # %bb.0: 4655; X64-BMI2-NEXT: pushq %rbp 4656; X64-BMI2-NEXT: pushq %rbx 4657; X64-BMI2-NEXT: pushq %rax 4658; X64-BMI2-NEXT: movl %edx, %ebx 4659; X64-BMI2-NEXT: shrxl %esi, %edi, %ebp 4660; X64-BMI2-NEXT: movl $-1, %eax 4661; X64-BMI2-NEXT: bzhil %edx, %eax, %edi 4662; X64-BMI2-NEXT: callq use32@PLT 4663; X64-BMI2-NEXT: bzhil %ebx, %ebp, %eax 4664; X64-BMI2-NEXT: addq $8, %rsp 4665; X64-BMI2-NEXT: popq %rbx 4666; X64-BMI2-NEXT: popq %rbp 4667; X64-BMI2-NEXT: retq 4668 %shifted = lshr i32 %val, %numskipbits 4669 %numhighbits = sub i32 32, %numlowbits 4670 %mask = lshr i32 -1, %numhighbits 4671 call void @use32(i32 %mask) 4672 %masked = and i32 %shifted, %mask ; swapped order 4673 ret i32 %masked 4674} 4675 4676define i32 @bextr32_c5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 4677; X86-NOBMI-LABEL: bextr32_c5_skipextrauses: 4678; X86-NOBMI: # %bb.0: 4679; X86-NOBMI-NEXT: pushl %ebx 4680; X86-NOBMI-NEXT: pushl %edi 4681; X86-NOBMI-NEXT: pushl %esi 4682; X86-NOBMI-NEXT: subl $16, %esp 4683; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 4684; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ebx 4685; X86-NOBMI-NEXT: movl %ebx, %ecx 4686; X86-NOBMI-NEXT: shrl %cl, %edi 4687; X86-NOBMI-NEXT: xorl %ecx, %ecx 4688; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 4689; X86-NOBMI-NEXT: movl $-1, %esi 4690; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 4691; X86-NOBMI-NEXT: shrl %cl, %esi 4692; X86-NOBMI-NEXT: movl %esi, (%esp) 4693; X86-NOBMI-NEXT: calll use32@PLT 4694; X86-NOBMI-NEXT: andl %edi, %esi 4695; X86-NOBMI-NEXT: movl %ebx, (%esp) 4696; X86-NOBMI-NEXT: calll use32@PLT 4697; X86-NOBMI-NEXT: movl %esi, %eax 4698; X86-NOBMI-NEXT: addl $16, %esp 4699; X86-NOBMI-NEXT: popl %esi 4700; X86-NOBMI-NEXT: popl %edi 4701; X86-NOBMI-NEXT: popl %ebx 4702; X86-NOBMI-NEXT: retl 4703; 4704; X86-BMI1-LABEL: bextr32_c5_skipextrauses: 4705; X86-BMI1: # %bb.0: 4706; X86-BMI1-NEXT: pushl %ebx 4707; X86-BMI1-NEXT: pushl %edi 4708; X86-BMI1-NEXT: pushl %esi 4709; X86-BMI1-NEXT: subl $16, %esp 4710; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 4711; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %ebx 4712; X86-BMI1-NEXT: movl %ebx, %ecx 4713; X86-BMI1-NEXT: shrl %cl, %edi 4714; X86-BMI1-NEXT: xorl %ecx, %ecx 4715; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 4716; X86-BMI1-NEXT: movl $-1, %esi 4717; X86-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 4718; X86-BMI1-NEXT: shrl %cl, %esi 4719; X86-BMI1-NEXT: movl %esi, (%esp) 4720; X86-BMI1-NEXT: calll use32@PLT 4721; X86-BMI1-NEXT: andl %edi, %esi 4722; X86-BMI1-NEXT: movl %ebx, (%esp) 4723; X86-BMI1-NEXT: calll use32@PLT 4724; X86-BMI1-NEXT: movl %esi, %eax 4725; X86-BMI1-NEXT: addl $16, %esp 4726; X86-BMI1-NEXT: popl %esi 4727; X86-BMI1-NEXT: popl %edi 4728; X86-BMI1-NEXT: popl %ebx 4729; X86-BMI1-NEXT: retl 4730; 4731; X86-BMI2-LABEL: bextr32_c5_skipextrauses: 4732; X86-BMI2: # %bb.0: 4733; X86-BMI2-NEXT: pushl %ebx 4734; X86-BMI2-NEXT: pushl %edi 4735; X86-BMI2-NEXT: pushl %esi 4736; X86-BMI2-NEXT: subl $16, %esp 4737; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ebx 4738; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edi 4739; X86-BMI2-NEXT: shrxl %edi, {{[0-9]+}}(%esp), %esi 4740; X86-BMI2-NEXT: movl $-1, %eax 4741; X86-BMI2-NEXT: bzhil %ebx, %eax, %eax 4742; X86-BMI2-NEXT: movl %eax, (%esp) 4743; X86-BMI2-NEXT: calll use32@PLT 4744; X86-BMI2-NEXT: bzhil %ebx, %esi, %esi 4745; X86-BMI2-NEXT: movl %edi, (%esp) 4746; X86-BMI2-NEXT: calll use32@PLT 4747; X86-BMI2-NEXT: movl %esi, %eax 4748; X86-BMI2-NEXT: addl $16, %esp 4749; X86-BMI2-NEXT: popl %esi 4750; X86-BMI2-NEXT: popl %edi 4751; X86-BMI2-NEXT: popl %ebx 4752; X86-BMI2-NEXT: retl 4753; 4754; X64-NOBMI-LABEL: bextr32_c5_skipextrauses: 4755; X64-NOBMI: # %bb.0: 4756; X64-NOBMI-NEXT: pushq %rbp 4757; X64-NOBMI-NEXT: pushq %r14 4758; X64-NOBMI-NEXT: pushq %rbx 4759; X64-NOBMI-NEXT: movl %esi, %ebx 4760; X64-NOBMI-NEXT: movl %edi, %ebp 4761; X64-NOBMI-NEXT: movl %ebx, %ecx 4762; X64-NOBMI-NEXT: shrl %cl, %ebp 4763; X64-NOBMI-NEXT: negb %dl 4764; X64-NOBMI-NEXT: movl $-1, %r14d 4765; X64-NOBMI-NEXT: movl %edx, %ecx 4766; X64-NOBMI-NEXT: shrl %cl, %r14d 4767; X64-NOBMI-NEXT: movl %r14d, %edi 4768; X64-NOBMI-NEXT: callq use32@PLT 4769; X64-NOBMI-NEXT: andl %ebp, %r14d 4770; X64-NOBMI-NEXT: movl %ebx, %edi 4771; X64-NOBMI-NEXT: callq use32@PLT 4772; X64-NOBMI-NEXT: movl %r14d, %eax 4773; X64-NOBMI-NEXT: popq %rbx 4774; X64-NOBMI-NEXT: popq %r14 4775; X64-NOBMI-NEXT: popq %rbp 4776; X64-NOBMI-NEXT: retq 4777; 4778; X64-BMI1-LABEL: bextr32_c5_skipextrauses: 4779; X64-BMI1: # %bb.0: 4780; X64-BMI1-NEXT: pushq %rbp 4781; X64-BMI1-NEXT: pushq %r14 4782; X64-BMI1-NEXT: pushq %rbx 4783; X64-BMI1-NEXT: movl %esi, %ebx 4784; X64-BMI1-NEXT: movl %edi, %ebp 4785; X64-BMI1-NEXT: movl %ebx, %ecx 4786; X64-BMI1-NEXT: shrl %cl, %ebp 4787; X64-BMI1-NEXT: negb %dl 4788; X64-BMI1-NEXT: movl $-1, %r14d 4789; X64-BMI1-NEXT: movl %edx, %ecx 4790; X64-BMI1-NEXT: shrl %cl, %r14d 4791; X64-BMI1-NEXT: movl %r14d, %edi 4792; X64-BMI1-NEXT: callq use32@PLT 4793; X64-BMI1-NEXT: andl %ebp, %r14d 4794; X64-BMI1-NEXT: movl %ebx, %edi 4795; X64-BMI1-NEXT: callq use32@PLT 4796; X64-BMI1-NEXT: movl %r14d, %eax 4797; X64-BMI1-NEXT: popq %rbx 4798; X64-BMI1-NEXT: popq %r14 4799; X64-BMI1-NEXT: popq %rbp 4800; X64-BMI1-NEXT: retq 4801; 4802; X64-BMI2-LABEL: bextr32_c5_skipextrauses: 4803; X64-BMI2: # %bb.0: 4804; X64-BMI2-NEXT: pushq %rbp 4805; X64-BMI2-NEXT: pushq %r14 4806; X64-BMI2-NEXT: pushq %rbx 4807; X64-BMI2-NEXT: movl %edx, %ebx 4808; X64-BMI2-NEXT: movl %esi, %ebp 4809; X64-BMI2-NEXT: shrxl %esi, %edi, %r14d 4810; X64-BMI2-NEXT: movl $-1, %eax 4811; X64-BMI2-NEXT: bzhil %edx, %eax, %edi 4812; X64-BMI2-NEXT: callq use32@PLT 4813; X64-BMI2-NEXT: bzhil %ebx, %r14d, %ebx 4814; X64-BMI2-NEXT: movl %ebp, %edi 4815; X64-BMI2-NEXT: callq use32@PLT 4816; X64-BMI2-NEXT: movl %ebx, %eax 4817; X64-BMI2-NEXT: popq %rbx 4818; X64-BMI2-NEXT: popq %r14 4819; X64-BMI2-NEXT: popq %rbp 4820; X64-BMI2-NEXT: retq 4821 %shifted = lshr i32 %val, %numskipbits 4822 %numhighbits = sub i32 32, %numlowbits 4823 %mask = lshr i32 -1, %numhighbits 4824 call void @use32(i32 %mask) 4825 %masked = and i32 %mask, %shifted 4826 call void @use32(i32 %numskipbits) 4827 ret i32 %masked 4828} 4829 4830; 64-bit 4831 4832define i64 @bextr64_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 4833; X86-NOBMI-LABEL: bextr64_c0: 4834; X86-NOBMI: # %bb.0: 4835; X86-NOBMI-NEXT: pushl %ebp 4836; X86-NOBMI-NEXT: pushl %ebx 4837; X86-NOBMI-NEXT: pushl %edi 4838; X86-NOBMI-NEXT: pushl %esi 4839; X86-NOBMI-NEXT: subl $12, %esp 4840; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4841; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 4842; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 4843; X86-NOBMI-NEXT: movl %eax, %edi 4844; X86-NOBMI-NEXT: shrl %cl, %edi 4845; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 4846; X86-NOBMI-NEXT: testb $32, %cl 4847; X86-NOBMI-NEXT: je .LBB41_2 4848; X86-NOBMI-NEXT: # %bb.1: 4849; X86-NOBMI-NEXT: movl %edi, %esi 4850; X86-NOBMI-NEXT: xorl %edi, %edi 4851; X86-NOBMI-NEXT: .LBB41_2: 4852; X86-NOBMI-NEXT: movb $64, %cl 4853; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 4854; X86-NOBMI-NEXT: movl $-1, %ebp 4855; X86-NOBMI-NEXT: movl $-1, %ebx 4856; X86-NOBMI-NEXT: shrl %cl, %ebx 4857; X86-NOBMI-NEXT: testb $32, %cl 4858; X86-NOBMI-NEXT: je .LBB41_4 4859; X86-NOBMI-NEXT: # %bb.3: 4860; X86-NOBMI-NEXT: movl %ebx, %ebp 4861; X86-NOBMI-NEXT: xorl %ebx, %ebx 4862; X86-NOBMI-NEXT: .LBB41_4: 4863; X86-NOBMI-NEXT: subl $8, %esp 4864; X86-NOBMI-NEXT: pushl %ebx 4865; X86-NOBMI-NEXT: pushl %ebp 4866; X86-NOBMI-NEXT: calll use64@PLT 4867; X86-NOBMI-NEXT: addl $16, %esp 4868; X86-NOBMI-NEXT: andl %ebp, %esi 4869; X86-NOBMI-NEXT: andl %ebx, %edi 4870; X86-NOBMI-NEXT: movl %esi, %eax 4871; X86-NOBMI-NEXT: movl %edi, %edx 4872; X86-NOBMI-NEXT: addl $12, %esp 4873; X86-NOBMI-NEXT: popl %esi 4874; X86-NOBMI-NEXT: popl %edi 4875; X86-NOBMI-NEXT: popl %ebx 4876; X86-NOBMI-NEXT: popl %ebp 4877; X86-NOBMI-NEXT: retl 4878; 4879; X86-BMI1-LABEL: bextr64_c0: 4880; X86-BMI1: # %bb.0: 4881; X86-BMI1-NEXT: pushl %ebp 4882; X86-BMI1-NEXT: pushl %ebx 4883; X86-BMI1-NEXT: pushl %edi 4884; X86-BMI1-NEXT: pushl %esi 4885; X86-BMI1-NEXT: subl $12, %esp 4886; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4887; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 4888; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 4889; X86-BMI1-NEXT: movl %eax, %edi 4890; X86-BMI1-NEXT: shrl %cl, %edi 4891; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 4892; X86-BMI1-NEXT: testb $32, %cl 4893; X86-BMI1-NEXT: je .LBB41_2 4894; X86-BMI1-NEXT: # %bb.1: 4895; X86-BMI1-NEXT: movl %edi, %esi 4896; X86-BMI1-NEXT: xorl %edi, %edi 4897; X86-BMI1-NEXT: .LBB41_2: 4898; X86-BMI1-NEXT: movb $64, %cl 4899; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 4900; X86-BMI1-NEXT: movl $-1, %ebp 4901; X86-BMI1-NEXT: movl $-1, %ebx 4902; X86-BMI1-NEXT: shrl %cl, %ebx 4903; X86-BMI1-NEXT: testb $32, %cl 4904; X86-BMI1-NEXT: je .LBB41_4 4905; X86-BMI1-NEXT: # %bb.3: 4906; X86-BMI1-NEXT: movl %ebx, %ebp 4907; X86-BMI1-NEXT: xorl %ebx, %ebx 4908; X86-BMI1-NEXT: .LBB41_4: 4909; X86-BMI1-NEXT: subl $8, %esp 4910; X86-BMI1-NEXT: pushl %ebx 4911; X86-BMI1-NEXT: pushl %ebp 4912; X86-BMI1-NEXT: calll use64@PLT 4913; X86-BMI1-NEXT: addl $16, %esp 4914; X86-BMI1-NEXT: andl %ebp, %esi 4915; X86-BMI1-NEXT: andl %ebx, %edi 4916; X86-BMI1-NEXT: movl %esi, %eax 4917; X86-BMI1-NEXT: movl %edi, %edx 4918; X86-BMI1-NEXT: addl $12, %esp 4919; X86-BMI1-NEXT: popl %esi 4920; X86-BMI1-NEXT: popl %edi 4921; X86-BMI1-NEXT: popl %ebx 4922; X86-BMI1-NEXT: popl %ebp 4923; X86-BMI1-NEXT: retl 4924; 4925; X86-BMI2-LABEL: bextr64_c0: 4926; X86-BMI2: # %bb.0: 4927; X86-BMI2-NEXT: pushl %ebp 4928; X86-BMI2-NEXT: pushl %ebx 4929; X86-BMI2-NEXT: pushl %edi 4930; X86-BMI2-NEXT: pushl %esi 4931; X86-BMI2-NEXT: subl $12, %esp 4932; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 4933; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 4934; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 4935; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 4936; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 4937; X86-BMI2-NEXT: testb $32, %cl 4938; X86-BMI2-NEXT: je .LBB41_2 4939; X86-BMI2-NEXT: # %bb.1: 4940; X86-BMI2-NEXT: movl %edi, %esi 4941; X86-BMI2-NEXT: xorl %edi, %edi 4942; X86-BMI2-NEXT: .LBB41_2: 4943; X86-BMI2-NEXT: movb $64, %al 4944; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al 4945; X86-BMI2-NEXT: movl $-1, %ebp 4946; X86-BMI2-NEXT: shrxl %eax, %ebp, %ebx 4947; X86-BMI2-NEXT: testb $32, %al 4948; X86-BMI2-NEXT: je .LBB41_4 4949; X86-BMI2-NEXT: # %bb.3: 4950; X86-BMI2-NEXT: movl %ebx, %ebp 4951; X86-BMI2-NEXT: xorl %ebx, %ebx 4952; X86-BMI2-NEXT: .LBB41_4: 4953; X86-BMI2-NEXT: subl $8, %esp 4954; X86-BMI2-NEXT: pushl %ebx 4955; X86-BMI2-NEXT: pushl %ebp 4956; X86-BMI2-NEXT: calll use64@PLT 4957; X86-BMI2-NEXT: addl $16, %esp 4958; X86-BMI2-NEXT: andl %ebp, %esi 4959; X86-BMI2-NEXT: andl %ebx, %edi 4960; X86-BMI2-NEXT: movl %esi, %eax 4961; X86-BMI2-NEXT: movl %edi, %edx 4962; X86-BMI2-NEXT: addl $12, %esp 4963; X86-BMI2-NEXT: popl %esi 4964; X86-BMI2-NEXT: popl %edi 4965; X86-BMI2-NEXT: popl %ebx 4966; X86-BMI2-NEXT: popl %ebp 4967; X86-BMI2-NEXT: retl 4968; 4969; X64-NOBMI-LABEL: bextr64_c0: 4970; X64-NOBMI: # %bb.0: 4971; X64-NOBMI-NEXT: pushq %r14 4972; X64-NOBMI-NEXT: pushq %rbx 4973; X64-NOBMI-NEXT: pushq %rax 4974; X64-NOBMI-NEXT: movq %rsi, %rcx 4975; X64-NOBMI-NEXT: movq %rdi, %rbx 4976; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 4977; X64-NOBMI-NEXT: shrq %cl, %rbx 4978; X64-NOBMI-NEXT: negb %dl 4979; X64-NOBMI-NEXT: movq $-1, %r14 4980; X64-NOBMI-NEXT: movl %edx, %ecx 4981; X64-NOBMI-NEXT: shrq %cl, %r14 4982; X64-NOBMI-NEXT: movq %r14, %rdi 4983; X64-NOBMI-NEXT: callq use64@PLT 4984; X64-NOBMI-NEXT: andq %rbx, %r14 4985; X64-NOBMI-NEXT: movq %r14, %rax 4986; X64-NOBMI-NEXT: addq $8, %rsp 4987; X64-NOBMI-NEXT: popq %rbx 4988; X64-NOBMI-NEXT: popq %r14 4989; X64-NOBMI-NEXT: retq 4990; 4991; X64-BMI1-LABEL: bextr64_c0: 4992; X64-BMI1: # %bb.0: 4993; X64-BMI1-NEXT: pushq %r14 4994; X64-BMI1-NEXT: pushq %rbx 4995; X64-BMI1-NEXT: pushq %rax 4996; X64-BMI1-NEXT: movq %rsi, %rcx 4997; X64-BMI1-NEXT: movq %rdi, %rbx 4998; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $rcx 4999; X64-BMI1-NEXT: shrq %cl, %rbx 5000; X64-BMI1-NEXT: negb %dl 5001; X64-BMI1-NEXT: movq $-1, %r14 5002; X64-BMI1-NEXT: movl %edx, %ecx 5003; X64-BMI1-NEXT: shrq %cl, %r14 5004; X64-BMI1-NEXT: movq %r14, %rdi 5005; X64-BMI1-NEXT: callq use64@PLT 5006; X64-BMI1-NEXT: andq %rbx, %r14 5007; X64-BMI1-NEXT: movq %r14, %rax 5008; X64-BMI1-NEXT: addq $8, %rsp 5009; X64-BMI1-NEXT: popq %rbx 5010; X64-BMI1-NEXT: popq %r14 5011; X64-BMI1-NEXT: retq 5012; 5013; X64-BMI2-LABEL: bextr64_c0: 5014; X64-BMI2: # %bb.0: 5015; X64-BMI2-NEXT: pushq %r14 5016; X64-BMI2-NEXT: pushq %rbx 5017; X64-BMI2-NEXT: pushq %rax 5018; X64-BMI2-NEXT: movq %rdx, %rbx 5019; X64-BMI2-NEXT: shrxq %rsi, %rdi, %r14 5020; X64-BMI2-NEXT: movq $-1, %rax 5021; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rdi 5022; X64-BMI2-NEXT: callq use64@PLT 5023; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax 5024; X64-BMI2-NEXT: addq $8, %rsp 5025; X64-BMI2-NEXT: popq %rbx 5026; X64-BMI2-NEXT: popq %r14 5027; X64-BMI2-NEXT: retq 5028 %shifted = lshr i64 %val, %numskipbits 5029 %numhighbits = sub i64 64, %numlowbits 5030 %mask = lshr i64 -1, %numhighbits 5031 call void @use64(i64 %mask) 5032 %masked = and i64 %mask, %shifted 5033 ret i64 %masked 5034} 5035 5036define i64 @bextr64_c1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind { 5037; X86-NOBMI-LABEL: bextr64_c1_indexzext: 5038; X86-NOBMI: # %bb.0: 5039; X86-NOBMI-NEXT: pushl %ebp 5040; X86-NOBMI-NEXT: pushl %ebx 5041; X86-NOBMI-NEXT: pushl %edi 5042; X86-NOBMI-NEXT: pushl %esi 5043; X86-NOBMI-NEXT: subl $12, %esp 5044; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5045; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 5046; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 5047; X86-NOBMI-NEXT: movl %eax, %edi 5048; X86-NOBMI-NEXT: shrl %cl, %edi 5049; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 5050; X86-NOBMI-NEXT: testb $32, %cl 5051; X86-NOBMI-NEXT: je .LBB42_2 5052; X86-NOBMI-NEXT: # %bb.1: 5053; X86-NOBMI-NEXT: movl %edi, %esi 5054; X86-NOBMI-NEXT: xorl %edi, %edi 5055; X86-NOBMI-NEXT: .LBB42_2: 5056; X86-NOBMI-NEXT: movb $64, %cl 5057; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 5058; X86-NOBMI-NEXT: movl $-1, %ebp 5059; X86-NOBMI-NEXT: movl $-1, %ebx 5060; X86-NOBMI-NEXT: shrl %cl, %ebx 5061; X86-NOBMI-NEXT: testb $32, %cl 5062; X86-NOBMI-NEXT: je .LBB42_4 5063; X86-NOBMI-NEXT: # %bb.3: 5064; X86-NOBMI-NEXT: movl %ebx, %ebp 5065; X86-NOBMI-NEXT: xorl %ebx, %ebx 5066; X86-NOBMI-NEXT: .LBB42_4: 5067; X86-NOBMI-NEXT: subl $8, %esp 5068; X86-NOBMI-NEXT: pushl %ebx 5069; X86-NOBMI-NEXT: pushl %ebp 5070; X86-NOBMI-NEXT: calll use64@PLT 5071; X86-NOBMI-NEXT: addl $16, %esp 5072; X86-NOBMI-NEXT: andl %ebp, %esi 5073; X86-NOBMI-NEXT: andl %ebx, %edi 5074; X86-NOBMI-NEXT: movl %esi, %eax 5075; X86-NOBMI-NEXT: movl %edi, %edx 5076; X86-NOBMI-NEXT: addl $12, %esp 5077; X86-NOBMI-NEXT: popl %esi 5078; X86-NOBMI-NEXT: popl %edi 5079; X86-NOBMI-NEXT: popl %ebx 5080; X86-NOBMI-NEXT: popl %ebp 5081; X86-NOBMI-NEXT: retl 5082; 5083; X86-BMI1-LABEL: bextr64_c1_indexzext: 5084; X86-BMI1: # %bb.0: 5085; X86-BMI1-NEXT: pushl %ebp 5086; X86-BMI1-NEXT: pushl %ebx 5087; X86-BMI1-NEXT: pushl %edi 5088; X86-BMI1-NEXT: pushl %esi 5089; X86-BMI1-NEXT: subl $12, %esp 5090; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5091; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 5092; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 5093; X86-BMI1-NEXT: movl %eax, %edi 5094; X86-BMI1-NEXT: shrl %cl, %edi 5095; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 5096; X86-BMI1-NEXT: testb $32, %cl 5097; X86-BMI1-NEXT: je .LBB42_2 5098; X86-BMI1-NEXT: # %bb.1: 5099; X86-BMI1-NEXT: movl %edi, %esi 5100; X86-BMI1-NEXT: xorl %edi, %edi 5101; X86-BMI1-NEXT: .LBB42_2: 5102; X86-BMI1-NEXT: movb $64, %cl 5103; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 5104; X86-BMI1-NEXT: movl $-1, %ebp 5105; X86-BMI1-NEXT: movl $-1, %ebx 5106; X86-BMI1-NEXT: shrl %cl, %ebx 5107; X86-BMI1-NEXT: testb $32, %cl 5108; X86-BMI1-NEXT: je .LBB42_4 5109; X86-BMI1-NEXT: # %bb.3: 5110; X86-BMI1-NEXT: movl %ebx, %ebp 5111; X86-BMI1-NEXT: xorl %ebx, %ebx 5112; X86-BMI1-NEXT: .LBB42_4: 5113; X86-BMI1-NEXT: subl $8, %esp 5114; X86-BMI1-NEXT: pushl %ebx 5115; X86-BMI1-NEXT: pushl %ebp 5116; X86-BMI1-NEXT: calll use64@PLT 5117; X86-BMI1-NEXT: addl $16, %esp 5118; X86-BMI1-NEXT: andl %ebp, %esi 5119; X86-BMI1-NEXT: andl %ebx, %edi 5120; X86-BMI1-NEXT: movl %esi, %eax 5121; X86-BMI1-NEXT: movl %edi, %edx 5122; X86-BMI1-NEXT: addl $12, %esp 5123; X86-BMI1-NEXT: popl %esi 5124; X86-BMI1-NEXT: popl %edi 5125; X86-BMI1-NEXT: popl %ebx 5126; X86-BMI1-NEXT: popl %ebp 5127; X86-BMI1-NEXT: retl 5128; 5129; X86-BMI2-LABEL: bextr64_c1_indexzext: 5130; X86-BMI2: # %bb.0: 5131; X86-BMI2-NEXT: pushl %ebp 5132; X86-BMI2-NEXT: pushl %ebx 5133; X86-BMI2-NEXT: pushl %edi 5134; X86-BMI2-NEXT: pushl %esi 5135; X86-BMI2-NEXT: subl $12, %esp 5136; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5137; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 5138; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 5139; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 5140; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 5141; X86-BMI2-NEXT: testb $32, %cl 5142; X86-BMI2-NEXT: je .LBB42_2 5143; X86-BMI2-NEXT: # %bb.1: 5144; X86-BMI2-NEXT: movl %edi, %esi 5145; X86-BMI2-NEXT: xorl %edi, %edi 5146; X86-BMI2-NEXT: .LBB42_2: 5147; X86-BMI2-NEXT: movb $64, %al 5148; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al 5149; X86-BMI2-NEXT: movl $-1, %ebp 5150; X86-BMI2-NEXT: shrxl %eax, %ebp, %ebx 5151; X86-BMI2-NEXT: testb $32, %al 5152; X86-BMI2-NEXT: je .LBB42_4 5153; X86-BMI2-NEXT: # %bb.3: 5154; X86-BMI2-NEXT: movl %ebx, %ebp 5155; X86-BMI2-NEXT: xorl %ebx, %ebx 5156; X86-BMI2-NEXT: .LBB42_4: 5157; X86-BMI2-NEXT: subl $8, %esp 5158; X86-BMI2-NEXT: pushl %ebx 5159; X86-BMI2-NEXT: pushl %ebp 5160; X86-BMI2-NEXT: calll use64@PLT 5161; X86-BMI2-NEXT: addl $16, %esp 5162; X86-BMI2-NEXT: andl %ebp, %esi 5163; X86-BMI2-NEXT: andl %ebx, %edi 5164; X86-BMI2-NEXT: movl %esi, %eax 5165; X86-BMI2-NEXT: movl %edi, %edx 5166; X86-BMI2-NEXT: addl $12, %esp 5167; X86-BMI2-NEXT: popl %esi 5168; X86-BMI2-NEXT: popl %edi 5169; X86-BMI2-NEXT: popl %ebx 5170; X86-BMI2-NEXT: popl %ebp 5171; X86-BMI2-NEXT: retl 5172; 5173; X64-NOBMI-LABEL: bextr64_c1_indexzext: 5174; X64-NOBMI: # %bb.0: 5175; X64-NOBMI-NEXT: pushq %r14 5176; X64-NOBMI-NEXT: pushq %rbx 5177; X64-NOBMI-NEXT: pushq %rax 5178; X64-NOBMI-NEXT: movl %esi, %ecx 5179; X64-NOBMI-NEXT: movq %rdi, %rbx 5180; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 5181; X64-NOBMI-NEXT: shrq %cl, %rbx 5182; X64-NOBMI-NEXT: negb %dl 5183; X64-NOBMI-NEXT: movq $-1, %r14 5184; X64-NOBMI-NEXT: movl %edx, %ecx 5185; X64-NOBMI-NEXT: shrq %cl, %r14 5186; X64-NOBMI-NEXT: movq %r14, %rdi 5187; X64-NOBMI-NEXT: callq use64@PLT 5188; X64-NOBMI-NEXT: andq %rbx, %r14 5189; X64-NOBMI-NEXT: movq %r14, %rax 5190; X64-NOBMI-NEXT: addq $8, %rsp 5191; X64-NOBMI-NEXT: popq %rbx 5192; X64-NOBMI-NEXT: popq %r14 5193; X64-NOBMI-NEXT: retq 5194; 5195; X64-BMI1-LABEL: bextr64_c1_indexzext: 5196; X64-BMI1: # %bb.0: 5197; X64-BMI1-NEXT: pushq %r14 5198; X64-BMI1-NEXT: pushq %rbx 5199; X64-BMI1-NEXT: pushq %rax 5200; X64-BMI1-NEXT: movl %esi, %ecx 5201; X64-BMI1-NEXT: movq %rdi, %rbx 5202; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 5203; X64-BMI1-NEXT: shrq %cl, %rbx 5204; X64-BMI1-NEXT: negb %dl 5205; X64-BMI1-NEXT: movq $-1, %r14 5206; X64-BMI1-NEXT: movl %edx, %ecx 5207; X64-BMI1-NEXT: shrq %cl, %r14 5208; X64-BMI1-NEXT: movq %r14, %rdi 5209; X64-BMI1-NEXT: callq use64@PLT 5210; X64-BMI1-NEXT: andq %rbx, %r14 5211; X64-BMI1-NEXT: movq %r14, %rax 5212; X64-BMI1-NEXT: addq $8, %rsp 5213; X64-BMI1-NEXT: popq %rbx 5214; X64-BMI1-NEXT: popq %r14 5215; X64-BMI1-NEXT: retq 5216; 5217; X64-BMI2-LABEL: bextr64_c1_indexzext: 5218; X64-BMI2: # %bb.0: 5219; X64-BMI2-NEXT: pushq %r14 5220; X64-BMI2-NEXT: pushq %rbx 5221; X64-BMI2-NEXT: pushq %rax 5222; X64-BMI2-NEXT: movl %edx, %ebx 5223; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 5224; X64-BMI2-NEXT: shrxq %rsi, %rdi, %r14 5225; X64-BMI2-NEXT: movq $-1, %rax 5226; X64-BMI2-NEXT: bzhiq %rbx, %rax, %rdi 5227; X64-BMI2-NEXT: callq use64@PLT 5228; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax 5229; X64-BMI2-NEXT: addq $8, %rsp 5230; X64-BMI2-NEXT: popq %rbx 5231; X64-BMI2-NEXT: popq %r14 5232; X64-BMI2-NEXT: retq 5233 %skip = zext i8 %numskipbits to i64 5234 %shifted = lshr i64 %val, %skip 5235 %numhighbits = sub i8 64, %numlowbits 5236 %sh_prom = zext i8 %numhighbits to i64 5237 %mask = lshr i64 -1, %sh_prom 5238 call void @use64(i64 %mask) 5239 %masked = and i64 %mask, %shifted 5240 ret i64 %masked 5241} 5242 5243define i64 @bextr64_c2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind { 5244; X86-NOBMI-LABEL: bextr64_c2_load: 5245; X86-NOBMI: # %bb.0: 5246; X86-NOBMI-NEXT: pushl %ebp 5247; X86-NOBMI-NEXT: pushl %ebx 5248; X86-NOBMI-NEXT: pushl %edi 5249; X86-NOBMI-NEXT: pushl %esi 5250; X86-NOBMI-NEXT: subl $12, %esp 5251; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5252; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 5253; X86-NOBMI-NEXT: movl (%eax), %esi 5254; X86-NOBMI-NEXT: movl 4(%eax), %eax 5255; X86-NOBMI-NEXT: movl %eax, %edi 5256; X86-NOBMI-NEXT: shrl %cl, %edi 5257; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 5258; X86-NOBMI-NEXT: testb $32, %cl 5259; X86-NOBMI-NEXT: je .LBB43_2 5260; X86-NOBMI-NEXT: # %bb.1: 5261; X86-NOBMI-NEXT: movl %edi, %esi 5262; X86-NOBMI-NEXT: xorl %edi, %edi 5263; X86-NOBMI-NEXT: .LBB43_2: 5264; X86-NOBMI-NEXT: movb $64, %cl 5265; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 5266; X86-NOBMI-NEXT: movl $-1, %ebp 5267; X86-NOBMI-NEXT: movl $-1, %ebx 5268; X86-NOBMI-NEXT: shrl %cl, %ebx 5269; X86-NOBMI-NEXT: testb $32, %cl 5270; X86-NOBMI-NEXT: je .LBB43_4 5271; X86-NOBMI-NEXT: # %bb.3: 5272; X86-NOBMI-NEXT: movl %ebx, %ebp 5273; X86-NOBMI-NEXT: xorl %ebx, %ebx 5274; X86-NOBMI-NEXT: .LBB43_4: 5275; X86-NOBMI-NEXT: subl $8, %esp 5276; X86-NOBMI-NEXT: pushl %ebx 5277; X86-NOBMI-NEXT: pushl %ebp 5278; X86-NOBMI-NEXT: calll use64@PLT 5279; X86-NOBMI-NEXT: addl $16, %esp 5280; X86-NOBMI-NEXT: andl %ebp, %esi 5281; X86-NOBMI-NEXT: andl %ebx, %edi 5282; X86-NOBMI-NEXT: movl %esi, %eax 5283; X86-NOBMI-NEXT: movl %edi, %edx 5284; X86-NOBMI-NEXT: addl $12, %esp 5285; X86-NOBMI-NEXT: popl %esi 5286; X86-NOBMI-NEXT: popl %edi 5287; X86-NOBMI-NEXT: popl %ebx 5288; X86-NOBMI-NEXT: popl %ebp 5289; X86-NOBMI-NEXT: retl 5290; 5291; X86-BMI1-LABEL: bextr64_c2_load: 5292; X86-BMI1: # %bb.0: 5293; X86-BMI1-NEXT: pushl %ebp 5294; X86-BMI1-NEXT: pushl %ebx 5295; X86-BMI1-NEXT: pushl %edi 5296; X86-BMI1-NEXT: pushl %esi 5297; X86-BMI1-NEXT: subl $12, %esp 5298; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5299; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 5300; X86-BMI1-NEXT: movl (%eax), %esi 5301; X86-BMI1-NEXT: movl 4(%eax), %eax 5302; X86-BMI1-NEXT: movl %eax, %edi 5303; X86-BMI1-NEXT: shrl %cl, %edi 5304; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 5305; X86-BMI1-NEXT: testb $32, %cl 5306; X86-BMI1-NEXT: je .LBB43_2 5307; X86-BMI1-NEXT: # %bb.1: 5308; X86-BMI1-NEXT: movl %edi, %esi 5309; X86-BMI1-NEXT: xorl %edi, %edi 5310; X86-BMI1-NEXT: .LBB43_2: 5311; X86-BMI1-NEXT: movb $64, %cl 5312; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 5313; X86-BMI1-NEXT: movl $-1, %ebp 5314; X86-BMI1-NEXT: movl $-1, %ebx 5315; X86-BMI1-NEXT: shrl %cl, %ebx 5316; X86-BMI1-NEXT: testb $32, %cl 5317; X86-BMI1-NEXT: je .LBB43_4 5318; X86-BMI1-NEXT: # %bb.3: 5319; X86-BMI1-NEXT: movl %ebx, %ebp 5320; X86-BMI1-NEXT: xorl %ebx, %ebx 5321; X86-BMI1-NEXT: .LBB43_4: 5322; X86-BMI1-NEXT: subl $8, %esp 5323; X86-BMI1-NEXT: pushl %ebx 5324; X86-BMI1-NEXT: pushl %ebp 5325; X86-BMI1-NEXT: calll use64@PLT 5326; X86-BMI1-NEXT: addl $16, %esp 5327; X86-BMI1-NEXT: andl %ebp, %esi 5328; X86-BMI1-NEXT: andl %ebx, %edi 5329; X86-BMI1-NEXT: movl %esi, %eax 5330; X86-BMI1-NEXT: movl %edi, %edx 5331; X86-BMI1-NEXT: addl $12, %esp 5332; X86-BMI1-NEXT: popl %esi 5333; X86-BMI1-NEXT: popl %edi 5334; X86-BMI1-NEXT: popl %ebx 5335; X86-BMI1-NEXT: popl %ebp 5336; X86-BMI1-NEXT: retl 5337; 5338; X86-BMI2-LABEL: bextr64_c2_load: 5339; X86-BMI2: # %bb.0: 5340; X86-BMI2-NEXT: pushl %ebp 5341; X86-BMI2-NEXT: pushl %ebx 5342; X86-BMI2-NEXT: pushl %edi 5343; X86-BMI2-NEXT: pushl %esi 5344; X86-BMI2-NEXT: subl $12, %esp 5345; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5346; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 5347; X86-BMI2-NEXT: movl (%eax), %esi 5348; X86-BMI2-NEXT: movl 4(%eax), %eax 5349; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 5350; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 5351; X86-BMI2-NEXT: testb $32, %cl 5352; X86-BMI2-NEXT: je .LBB43_2 5353; X86-BMI2-NEXT: # %bb.1: 5354; X86-BMI2-NEXT: movl %edi, %esi 5355; X86-BMI2-NEXT: xorl %edi, %edi 5356; X86-BMI2-NEXT: .LBB43_2: 5357; X86-BMI2-NEXT: movb $64, %al 5358; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al 5359; X86-BMI2-NEXT: movl $-1, %ebp 5360; X86-BMI2-NEXT: shrxl %eax, %ebp, %ebx 5361; X86-BMI2-NEXT: testb $32, %al 5362; X86-BMI2-NEXT: je .LBB43_4 5363; X86-BMI2-NEXT: # %bb.3: 5364; X86-BMI2-NEXT: movl %ebx, %ebp 5365; X86-BMI2-NEXT: xorl %ebx, %ebx 5366; X86-BMI2-NEXT: .LBB43_4: 5367; X86-BMI2-NEXT: subl $8, %esp 5368; X86-BMI2-NEXT: pushl %ebx 5369; X86-BMI2-NEXT: pushl %ebp 5370; X86-BMI2-NEXT: calll use64@PLT 5371; X86-BMI2-NEXT: addl $16, %esp 5372; X86-BMI2-NEXT: andl %ebp, %esi 5373; X86-BMI2-NEXT: andl %ebx, %edi 5374; X86-BMI2-NEXT: movl %esi, %eax 5375; X86-BMI2-NEXT: movl %edi, %edx 5376; X86-BMI2-NEXT: addl $12, %esp 5377; X86-BMI2-NEXT: popl %esi 5378; X86-BMI2-NEXT: popl %edi 5379; X86-BMI2-NEXT: popl %ebx 5380; X86-BMI2-NEXT: popl %ebp 5381; X86-BMI2-NEXT: retl 5382; 5383; X64-NOBMI-LABEL: bextr64_c2_load: 5384; X64-NOBMI: # %bb.0: 5385; X64-NOBMI-NEXT: pushq %r14 5386; X64-NOBMI-NEXT: pushq %rbx 5387; X64-NOBMI-NEXT: pushq %rax 5388; X64-NOBMI-NEXT: movq %rsi, %rcx 5389; X64-NOBMI-NEXT: movq (%rdi), %r14 5390; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 5391; X64-NOBMI-NEXT: shrq %cl, %r14 5392; X64-NOBMI-NEXT: negb %dl 5393; X64-NOBMI-NEXT: movq $-1, %rbx 5394; X64-NOBMI-NEXT: movl %edx, %ecx 5395; X64-NOBMI-NEXT: shrq %cl, %rbx 5396; X64-NOBMI-NEXT: movq %rbx, %rdi 5397; X64-NOBMI-NEXT: callq use64@PLT 5398; X64-NOBMI-NEXT: andq %r14, %rbx 5399; X64-NOBMI-NEXT: movq %rbx, %rax 5400; X64-NOBMI-NEXT: addq $8, %rsp 5401; X64-NOBMI-NEXT: popq %rbx 5402; X64-NOBMI-NEXT: popq %r14 5403; X64-NOBMI-NEXT: retq 5404; 5405; X64-BMI1-LABEL: bextr64_c2_load: 5406; X64-BMI1: # %bb.0: 5407; X64-BMI1-NEXT: pushq %r14 5408; X64-BMI1-NEXT: pushq %rbx 5409; X64-BMI1-NEXT: pushq %rax 5410; X64-BMI1-NEXT: movq %rsi, %rcx 5411; X64-BMI1-NEXT: movq (%rdi), %r14 5412; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $rcx 5413; X64-BMI1-NEXT: shrq %cl, %r14 5414; X64-BMI1-NEXT: negb %dl 5415; X64-BMI1-NEXT: movq $-1, %rbx 5416; X64-BMI1-NEXT: movl %edx, %ecx 5417; X64-BMI1-NEXT: shrq %cl, %rbx 5418; X64-BMI1-NEXT: movq %rbx, %rdi 5419; X64-BMI1-NEXT: callq use64@PLT 5420; X64-BMI1-NEXT: andq %r14, %rbx 5421; X64-BMI1-NEXT: movq %rbx, %rax 5422; X64-BMI1-NEXT: addq $8, %rsp 5423; X64-BMI1-NEXT: popq %rbx 5424; X64-BMI1-NEXT: popq %r14 5425; X64-BMI1-NEXT: retq 5426; 5427; X64-BMI2-LABEL: bextr64_c2_load: 5428; X64-BMI2: # %bb.0: 5429; X64-BMI2-NEXT: pushq %r14 5430; X64-BMI2-NEXT: pushq %rbx 5431; X64-BMI2-NEXT: pushq %rax 5432; X64-BMI2-NEXT: movq %rdx, %rbx 5433; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %r14 5434; X64-BMI2-NEXT: movq $-1, %rax 5435; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rdi 5436; X64-BMI2-NEXT: callq use64@PLT 5437; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax 5438; X64-BMI2-NEXT: addq $8, %rsp 5439; X64-BMI2-NEXT: popq %rbx 5440; X64-BMI2-NEXT: popq %r14 5441; X64-BMI2-NEXT: retq 5442 %val = load i64, ptr %w 5443 %shifted = lshr i64 %val, %numskipbits 5444 %numhighbits = sub i64 64, %numlowbits 5445 %mask = lshr i64 -1, %numhighbits 5446 call void @use64(i64 %mask) 5447 %masked = and i64 %mask, %shifted 5448 ret i64 %masked 5449} 5450 5451define i64 @bextr64_c3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind { 5452; X86-NOBMI-LABEL: bextr64_c3_load_indexzext: 5453; X86-NOBMI: # %bb.0: 5454; X86-NOBMI-NEXT: pushl %ebp 5455; X86-NOBMI-NEXT: pushl %ebx 5456; X86-NOBMI-NEXT: pushl %edi 5457; X86-NOBMI-NEXT: pushl %esi 5458; X86-NOBMI-NEXT: subl $12, %esp 5459; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5460; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 5461; X86-NOBMI-NEXT: movl (%eax), %esi 5462; X86-NOBMI-NEXT: movl 4(%eax), %eax 5463; X86-NOBMI-NEXT: movl %eax, %edi 5464; X86-NOBMI-NEXT: shrl %cl, %edi 5465; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 5466; X86-NOBMI-NEXT: testb $32, %cl 5467; X86-NOBMI-NEXT: je .LBB44_2 5468; X86-NOBMI-NEXT: # %bb.1: 5469; X86-NOBMI-NEXT: movl %edi, %esi 5470; X86-NOBMI-NEXT: xorl %edi, %edi 5471; X86-NOBMI-NEXT: .LBB44_2: 5472; X86-NOBMI-NEXT: movb $64, %cl 5473; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 5474; X86-NOBMI-NEXT: movl $-1, %ebp 5475; X86-NOBMI-NEXT: movl $-1, %ebx 5476; X86-NOBMI-NEXT: shrl %cl, %ebx 5477; X86-NOBMI-NEXT: testb $32, %cl 5478; X86-NOBMI-NEXT: je .LBB44_4 5479; X86-NOBMI-NEXT: # %bb.3: 5480; X86-NOBMI-NEXT: movl %ebx, %ebp 5481; X86-NOBMI-NEXT: xorl %ebx, %ebx 5482; X86-NOBMI-NEXT: .LBB44_4: 5483; X86-NOBMI-NEXT: subl $8, %esp 5484; X86-NOBMI-NEXT: pushl %ebx 5485; X86-NOBMI-NEXT: pushl %ebp 5486; X86-NOBMI-NEXT: calll use64@PLT 5487; X86-NOBMI-NEXT: addl $16, %esp 5488; X86-NOBMI-NEXT: andl %ebp, %esi 5489; X86-NOBMI-NEXT: andl %ebx, %edi 5490; X86-NOBMI-NEXT: movl %esi, %eax 5491; X86-NOBMI-NEXT: movl %edi, %edx 5492; X86-NOBMI-NEXT: addl $12, %esp 5493; X86-NOBMI-NEXT: popl %esi 5494; X86-NOBMI-NEXT: popl %edi 5495; X86-NOBMI-NEXT: popl %ebx 5496; X86-NOBMI-NEXT: popl %ebp 5497; X86-NOBMI-NEXT: retl 5498; 5499; X86-BMI1-LABEL: bextr64_c3_load_indexzext: 5500; X86-BMI1: # %bb.0: 5501; X86-BMI1-NEXT: pushl %ebp 5502; X86-BMI1-NEXT: pushl %ebx 5503; X86-BMI1-NEXT: pushl %edi 5504; X86-BMI1-NEXT: pushl %esi 5505; X86-BMI1-NEXT: subl $12, %esp 5506; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5507; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 5508; X86-BMI1-NEXT: movl (%eax), %esi 5509; X86-BMI1-NEXT: movl 4(%eax), %eax 5510; X86-BMI1-NEXT: movl %eax, %edi 5511; X86-BMI1-NEXT: shrl %cl, %edi 5512; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 5513; X86-BMI1-NEXT: testb $32, %cl 5514; X86-BMI1-NEXT: je .LBB44_2 5515; X86-BMI1-NEXT: # %bb.1: 5516; X86-BMI1-NEXT: movl %edi, %esi 5517; X86-BMI1-NEXT: xorl %edi, %edi 5518; X86-BMI1-NEXT: .LBB44_2: 5519; X86-BMI1-NEXT: movb $64, %cl 5520; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 5521; X86-BMI1-NEXT: movl $-1, %ebp 5522; X86-BMI1-NEXT: movl $-1, %ebx 5523; X86-BMI1-NEXT: shrl %cl, %ebx 5524; X86-BMI1-NEXT: testb $32, %cl 5525; X86-BMI1-NEXT: je .LBB44_4 5526; X86-BMI1-NEXT: # %bb.3: 5527; X86-BMI1-NEXT: movl %ebx, %ebp 5528; X86-BMI1-NEXT: xorl %ebx, %ebx 5529; X86-BMI1-NEXT: .LBB44_4: 5530; X86-BMI1-NEXT: subl $8, %esp 5531; X86-BMI1-NEXT: pushl %ebx 5532; X86-BMI1-NEXT: pushl %ebp 5533; X86-BMI1-NEXT: calll use64@PLT 5534; X86-BMI1-NEXT: addl $16, %esp 5535; X86-BMI1-NEXT: andl %ebp, %esi 5536; X86-BMI1-NEXT: andl %ebx, %edi 5537; X86-BMI1-NEXT: movl %esi, %eax 5538; X86-BMI1-NEXT: movl %edi, %edx 5539; X86-BMI1-NEXT: addl $12, %esp 5540; X86-BMI1-NEXT: popl %esi 5541; X86-BMI1-NEXT: popl %edi 5542; X86-BMI1-NEXT: popl %ebx 5543; X86-BMI1-NEXT: popl %ebp 5544; X86-BMI1-NEXT: retl 5545; 5546; X86-BMI2-LABEL: bextr64_c3_load_indexzext: 5547; X86-BMI2: # %bb.0: 5548; X86-BMI2-NEXT: pushl %ebp 5549; X86-BMI2-NEXT: pushl %ebx 5550; X86-BMI2-NEXT: pushl %edi 5551; X86-BMI2-NEXT: pushl %esi 5552; X86-BMI2-NEXT: subl $12, %esp 5553; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5554; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 5555; X86-BMI2-NEXT: movl (%eax), %esi 5556; X86-BMI2-NEXT: movl 4(%eax), %eax 5557; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 5558; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 5559; X86-BMI2-NEXT: testb $32, %cl 5560; X86-BMI2-NEXT: je .LBB44_2 5561; X86-BMI2-NEXT: # %bb.1: 5562; X86-BMI2-NEXT: movl %edi, %esi 5563; X86-BMI2-NEXT: xorl %edi, %edi 5564; X86-BMI2-NEXT: .LBB44_2: 5565; X86-BMI2-NEXT: movb $64, %al 5566; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al 5567; X86-BMI2-NEXT: movl $-1, %ebp 5568; X86-BMI2-NEXT: shrxl %eax, %ebp, %ebx 5569; X86-BMI2-NEXT: testb $32, %al 5570; X86-BMI2-NEXT: je .LBB44_4 5571; X86-BMI2-NEXT: # %bb.3: 5572; X86-BMI2-NEXT: movl %ebx, %ebp 5573; X86-BMI2-NEXT: xorl %ebx, %ebx 5574; X86-BMI2-NEXT: .LBB44_4: 5575; X86-BMI2-NEXT: subl $8, %esp 5576; X86-BMI2-NEXT: pushl %ebx 5577; X86-BMI2-NEXT: pushl %ebp 5578; X86-BMI2-NEXT: calll use64@PLT 5579; X86-BMI2-NEXT: addl $16, %esp 5580; X86-BMI2-NEXT: andl %ebp, %esi 5581; X86-BMI2-NEXT: andl %ebx, %edi 5582; X86-BMI2-NEXT: movl %esi, %eax 5583; X86-BMI2-NEXT: movl %edi, %edx 5584; X86-BMI2-NEXT: addl $12, %esp 5585; X86-BMI2-NEXT: popl %esi 5586; X86-BMI2-NEXT: popl %edi 5587; X86-BMI2-NEXT: popl %ebx 5588; X86-BMI2-NEXT: popl %ebp 5589; X86-BMI2-NEXT: retl 5590; 5591; X64-NOBMI-LABEL: bextr64_c3_load_indexzext: 5592; X64-NOBMI: # %bb.0: 5593; X64-NOBMI-NEXT: pushq %r14 5594; X64-NOBMI-NEXT: pushq %rbx 5595; X64-NOBMI-NEXT: pushq %rax 5596; X64-NOBMI-NEXT: movl %esi, %ecx 5597; X64-NOBMI-NEXT: movq (%rdi), %r14 5598; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 5599; X64-NOBMI-NEXT: shrq %cl, %r14 5600; X64-NOBMI-NEXT: negb %dl 5601; X64-NOBMI-NEXT: movq $-1, %rbx 5602; X64-NOBMI-NEXT: movl %edx, %ecx 5603; X64-NOBMI-NEXT: shrq %cl, %rbx 5604; X64-NOBMI-NEXT: movq %rbx, %rdi 5605; X64-NOBMI-NEXT: callq use64@PLT 5606; X64-NOBMI-NEXT: andq %r14, %rbx 5607; X64-NOBMI-NEXT: movq %rbx, %rax 5608; X64-NOBMI-NEXT: addq $8, %rsp 5609; X64-NOBMI-NEXT: popq %rbx 5610; X64-NOBMI-NEXT: popq %r14 5611; X64-NOBMI-NEXT: retq 5612; 5613; X64-BMI1-LABEL: bextr64_c3_load_indexzext: 5614; X64-BMI1: # %bb.0: 5615; X64-BMI1-NEXT: pushq %r14 5616; X64-BMI1-NEXT: pushq %rbx 5617; X64-BMI1-NEXT: pushq %rax 5618; X64-BMI1-NEXT: movl %esi, %ecx 5619; X64-BMI1-NEXT: movq (%rdi), %r14 5620; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx 5621; X64-BMI1-NEXT: shrq %cl, %r14 5622; X64-BMI1-NEXT: negb %dl 5623; X64-BMI1-NEXT: movq $-1, %rbx 5624; X64-BMI1-NEXT: movl %edx, %ecx 5625; X64-BMI1-NEXT: shrq %cl, %rbx 5626; X64-BMI1-NEXT: movq %rbx, %rdi 5627; X64-BMI1-NEXT: callq use64@PLT 5628; X64-BMI1-NEXT: andq %r14, %rbx 5629; X64-BMI1-NEXT: movq %rbx, %rax 5630; X64-BMI1-NEXT: addq $8, %rsp 5631; X64-BMI1-NEXT: popq %rbx 5632; X64-BMI1-NEXT: popq %r14 5633; X64-BMI1-NEXT: retq 5634; 5635; X64-BMI2-LABEL: bextr64_c3_load_indexzext: 5636; X64-BMI2: # %bb.0: 5637; X64-BMI2-NEXT: pushq %r14 5638; X64-BMI2-NEXT: pushq %rbx 5639; X64-BMI2-NEXT: pushq %rax 5640; X64-BMI2-NEXT: movl %edx, %ebx 5641; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 5642; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %r14 5643; X64-BMI2-NEXT: movq $-1, %rax 5644; X64-BMI2-NEXT: bzhiq %rbx, %rax, %rdi 5645; X64-BMI2-NEXT: callq use64@PLT 5646; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax 5647; X64-BMI2-NEXT: addq $8, %rsp 5648; X64-BMI2-NEXT: popq %rbx 5649; X64-BMI2-NEXT: popq %r14 5650; X64-BMI2-NEXT: retq 5651 %val = load i64, ptr %w 5652 %skip = zext i8 %numskipbits to i64 5653 %shifted = lshr i64 %val, %skip 5654 %numhighbits = sub i8 64, %numlowbits 5655 %sh_prom = zext i8 %numhighbits to i64 5656 %mask = lshr i64 -1, %sh_prom 5657 call void @use64(i64 %mask) 5658 %masked = and i64 %mask, %shifted 5659 ret i64 %masked 5660} 5661 5662define i64 @bextr64_c4_commutative(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 5663; X86-NOBMI-LABEL: bextr64_c4_commutative: 5664; X86-NOBMI: # %bb.0: 5665; X86-NOBMI-NEXT: pushl %ebp 5666; X86-NOBMI-NEXT: pushl %ebx 5667; X86-NOBMI-NEXT: pushl %edi 5668; X86-NOBMI-NEXT: pushl %esi 5669; X86-NOBMI-NEXT: subl $12, %esp 5670; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5671; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 5672; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 5673; X86-NOBMI-NEXT: movl %eax, %edi 5674; X86-NOBMI-NEXT: shrl %cl, %edi 5675; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 5676; X86-NOBMI-NEXT: testb $32, %cl 5677; X86-NOBMI-NEXT: je .LBB45_2 5678; X86-NOBMI-NEXT: # %bb.1: 5679; X86-NOBMI-NEXT: movl %edi, %esi 5680; X86-NOBMI-NEXT: xorl %edi, %edi 5681; X86-NOBMI-NEXT: .LBB45_2: 5682; X86-NOBMI-NEXT: movb $64, %cl 5683; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 5684; X86-NOBMI-NEXT: movl $-1, %ebp 5685; X86-NOBMI-NEXT: movl $-1, %ebx 5686; X86-NOBMI-NEXT: shrl %cl, %ebx 5687; X86-NOBMI-NEXT: testb $32, %cl 5688; X86-NOBMI-NEXT: je .LBB45_4 5689; X86-NOBMI-NEXT: # %bb.3: 5690; X86-NOBMI-NEXT: movl %ebx, %ebp 5691; X86-NOBMI-NEXT: xorl %ebx, %ebx 5692; X86-NOBMI-NEXT: .LBB45_4: 5693; X86-NOBMI-NEXT: subl $8, %esp 5694; X86-NOBMI-NEXT: pushl %ebx 5695; X86-NOBMI-NEXT: pushl %ebp 5696; X86-NOBMI-NEXT: calll use64@PLT 5697; X86-NOBMI-NEXT: addl $16, %esp 5698; X86-NOBMI-NEXT: andl %ebp, %esi 5699; X86-NOBMI-NEXT: andl %ebx, %edi 5700; X86-NOBMI-NEXT: movl %esi, %eax 5701; X86-NOBMI-NEXT: movl %edi, %edx 5702; X86-NOBMI-NEXT: addl $12, %esp 5703; X86-NOBMI-NEXT: popl %esi 5704; X86-NOBMI-NEXT: popl %edi 5705; X86-NOBMI-NEXT: popl %ebx 5706; X86-NOBMI-NEXT: popl %ebp 5707; X86-NOBMI-NEXT: retl 5708; 5709; X86-BMI1-LABEL: bextr64_c4_commutative: 5710; X86-BMI1: # %bb.0: 5711; X86-BMI1-NEXT: pushl %ebp 5712; X86-BMI1-NEXT: pushl %ebx 5713; X86-BMI1-NEXT: pushl %edi 5714; X86-BMI1-NEXT: pushl %esi 5715; X86-BMI1-NEXT: subl $12, %esp 5716; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5717; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 5718; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 5719; X86-BMI1-NEXT: movl %eax, %edi 5720; X86-BMI1-NEXT: shrl %cl, %edi 5721; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 5722; X86-BMI1-NEXT: testb $32, %cl 5723; X86-BMI1-NEXT: je .LBB45_2 5724; X86-BMI1-NEXT: # %bb.1: 5725; X86-BMI1-NEXT: movl %edi, %esi 5726; X86-BMI1-NEXT: xorl %edi, %edi 5727; X86-BMI1-NEXT: .LBB45_2: 5728; X86-BMI1-NEXT: movb $64, %cl 5729; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 5730; X86-BMI1-NEXT: movl $-1, %ebp 5731; X86-BMI1-NEXT: movl $-1, %ebx 5732; X86-BMI1-NEXT: shrl %cl, %ebx 5733; X86-BMI1-NEXT: testb $32, %cl 5734; X86-BMI1-NEXT: je .LBB45_4 5735; X86-BMI1-NEXT: # %bb.3: 5736; X86-BMI1-NEXT: movl %ebx, %ebp 5737; X86-BMI1-NEXT: xorl %ebx, %ebx 5738; X86-BMI1-NEXT: .LBB45_4: 5739; X86-BMI1-NEXT: subl $8, %esp 5740; X86-BMI1-NEXT: pushl %ebx 5741; X86-BMI1-NEXT: pushl %ebp 5742; X86-BMI1-NEXT: calll use64@PLT 5743; X86-BMI1-NEXT: addl $16, %esp 5744; X86-BMI1-NEXT: andl %ebp, %esi 5745; X86-BMI1-NEXT: andl %ebx, %edi 5746; X86-BMI1-NEXT: movl %esi, %eax 5747; X86-BMI1-NEXT: movl %edi, %edx 5748; X86-BMI1-NEXT: addl $12, %esp 5749; X86-BMI1-NEXT: popl %esi 5750; X86-BMI1-NEXT: popl %edi 5751; X86-BMI1-NEXT: popl %ebx 5752; X86-BMI1-NEXT: popl %ebp 5753; X86-BMI1-NEXT: retl 5754; 5755; X86-BMI2-LABEL: bextr64_c4_commutative: 5756; X86-BMI2: # %bb.0: 5757; X86-BMI2-NEXT: pushl %ebp 5758; X86-BMI2-NEXT: pushl %ebx 5759; X86-BMI2-NEXT: pushl %edi 5760; X86-BMI2-NEXT: pushl %esi 5761; X86-BMI2-NEXT: subl $12, %esp 5762; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 5763; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 5764; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 5765; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 5766; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 5767; X86-BMI2-NEXT: testb $32, %cl 5768; X86-BMI2-NEXT: je .LBB45_2 5769; X86-BMI2-NEXT: # %bb.1: 5770; X86-BMI2-NEXT: movl %edi, %esi 5771; X86-BMI2-NEXT: xorl %edi, %edi 5772; X86-BMI2-NEXT: .LBB45_2: 5773; X86-BMI2-NEXT: movb $64, %al 5774; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al 5775; X86-BMI2-NEXT: movl $-1, %ebp 5776; X86-BMI2-NEXT: shrxl %eax, %ebp, %ebx 5777; X86-BMI2-NEXT: testb $32, %al 5778; X86-BMI2-NEXT: je .LBB45_4 5779; X86-BMI2-NEXT: # %bb.3: 5780; X86-BMI2-NEXT: movl %ebx, %ebp 5781; X86-BMI2-NEXT: xorl %ebx, %ebx 5782; X86-BMI2-NEXT: .LBB45_4: 5783; X86-BMI2-NEXT: subl $8, %esp 5784; X86-BMI2-NEXT: pushl %ebx 5785; X86-BMI2-NEXT: pushl %ebp 5786; X86-BMI2-NEXT: calll use64@PLT 5787; X86-BMI2-NEXT: addl $16, %esp 5788; X86-BMI2-NEXT: andl %ebp, %esi 5789; X86-BMI2-NEXT: andl %ebx, %edi 5790; X86-BMI2-NEXT: movl %esi, %eax 5791; X86-BMI2-NEXT: movl %edi, %edx 5792; X86-BMI2-NEXT: addl $12, %esp 5793; X86-BMI2-NEXT: popl %esi 5794; X86-BMI2-NEXT: popl %edi 5795; X86-BMI2-NEXT: popl %ebx 5796; X86-BMI2-NEXT: popl %ebp 5797; X86-BMI2-NEXT: retl 5798; 5799; X64-NOBMI-LABEL: bextr64_c4_commutative: 5800; X64-NOBMI: # %bb.0: 5801; X64-NOBMI-NEXT: pushq %r14 5802; X64-NOBMI-NEXT: pushq %rbx 5803; X64-NOBMI-NEXT: pushq %rax 5804; X64-NOBMI-NEXT: movq %rsi, %rcx 5805; X64-NOBMI-NEXT: movq %rdi, %rbx 5806; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 5807; X64-NOBMI-NEXT: shrq %cl, %rbx 5808; X64-NOBMI-NEXT: negb %dl 5809; X64-NOBMI-NEXT: movq $-1, %r14 5810; X64-NOBMI-NEXT: movl %edx, %ecx 5811; X64-NOBMI-NEXT: shrq %cl, %r14 5812; X64-NOBMI-NEXT: movq %r14, %rdi 5813; X64-NOBMI-NEXT: callq use64@PLT 5814; X64-NOBMI-NEXT: andq %rbx, %r14 5815; X64-NOBMI-NEXT: movq %r14, %rax 5816; X64-NOBMI-NEXT: addq $8, %rsp 5817; X64-NOBMI-NEXT: popq %rbx 5818; X64-NOBMI-NEXT: popq %r14 5819; X64-NOBMI-NEXT: retq 5820; 5821; X64-BMI1-LABEL: bextr64_c4_commutative: 5822; X64-BMI1: # %bb.0: 5823; X64-BMI1-NEXT: pushq %r14 5824; X64-BMI1-NEXT: pushq %rbx 5825; X64-BMI1-NEXT: pushq %rax 5826; X64-BMI1-NEXT: movq %rsi, %rcx 5827; X64-BMI1-NEXT: movq %rdi, %rbx 5828; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $rcx 5829; X64-BMI1-NEXT: shrq %cl, %rbx 5830; X64-BMI1-NEXT: negb %dl 5831; X64-BMI1-NEXT: movq $-1, %r14 5832; X64-BMI1-NEXT: movl %edx, %ecx 5833; X64-BMI1-NEXT: shrq %cl, %r14 5834; X64-BMI1-NEXT: movq %r14, %rdi 5835; X64-BMI1-NEXT: callq use64@PLT 5836; X64-BMI1-NEXT: andq %rbx, %r14 5837; X64-BMI1-NEXT: movq %r14, %rax 5838; X64-BMI1-NEXT: addq $8, %rsp 5839; X64-BMI1-NEXT: popq %rbx 5840; X64-BMI1-NEXT: popq %r14 5841; X64-BMI1-NEXT: retq 5842; 5843; X64-BMI2-LABEL: bextr64_c4_commutative: 5844; X64-BMI2: # %bb.0: 5845; X64-BMI2-NEXT: pushq %r14 5846; X64-BMI2-NEXT: pushq %rbx 5847; X64-BMI2-NEXT: pushq %rax 5848; X64-BMI2-NEXT: movq %rdx, %rbx 5849; X64-BMI2-NEXT: shrxq %rsi, %rdi, %r14 5850; X64-BMI2-NEXT: movq $-1, %rax 5851; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rdi 5852; X64-BMI2-NEXT: callq use64@PLT 5853; X64-BMI2-NEXT: bzhiq %rbx, %r14, %rax 5854; X64-BMI2-NEXT: addq $8, %rsp 5855; X64-BMI2-NEXT: popq %rbx 5856; X64-BMI2-NEXT: popq %r14 5857; X64-BMI2-NEXT: retq 5858 %shifted = lshr i64 %val, %numskipbits 5859 %numhighbits = sub i64 64, %numlowbits 5860 %mask = lshr i64 -1, %numhighbits 5861 call void @use64(i64 %mask) 5862 %masked = and i64 %shifted, %mask ; swapped order 5863 ret i64 %masked 5864} 5865 5866define i64 @bextr64_c5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 5867; X86-NOBMI-LABEL: bextr64_c5_skipextrauses: 5868; X86-NOBMI: # %bb.0: 5869; X86-NOBMI-NEXT: pushl %ebp 5870; X86-NOBMI-NEXT: pushl %ebx 5871; X86-NOBMI-NEXT: pushl %edi 5872; X86-NOBMI-NEXT: pushl %esi 5873; X86-NOBMI-NEXT: subl $12, %esp 5874; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 5875; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 5876; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx 5877; X86-NOBMI-NEXT: movl %eax, %edi 5878; X86-NOBMI-NEXT: shrl %cl, %edi 5879; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 5880; X86-NOBMI-NEXT: testb $32, %cl 5881; X86-NOBMI-NEXT: je .LBB46_2 5882; X86-NOBMI-NEXT: # %bb.1: 5883; X86-NOBMI-NEXT: movl %edi, %esi 5884; X86-NOBMI-NEXT: xorl %edi, %edi 5885; X86-NOBMI-NEXT: .LBB46_2: 5886; X86-NOBMI-NEXT: movb $64, %cl 5887; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 5888; X86-NOBMI-NEXT: movl $-1, %ebx 5889; X86-NOBMI-NEXT: movl $-1, %ebp 5890; X86-NOBMI-NEXT: shrl %cl, %ebp 5891; X86-NOBMI-NEXT: testb $32, %cl 5892; X86-NOBMI-NEXT: je .LBB46_4 5893; X86-NOBMI-NEXT: # %bb.3: 5894; X86-NOBMI-NEXT: movl %ebp, %ebx 5895; X86-NOBMI-NEXT: xorl %ebp, %ebp 5896; X86-NOBMI-NEXT: .LBB46_4: 5897; X86-NOBMI-NEXT: subl $8, %esp 5898; X86-NOBMI-NEXT: pushl %ebp 5899; X86-NOBMI-NEXT: pushl %ebx 5900; X86-NOBMI-NEXT: calll use64@PLT 5901; X86-NOBMI-NEXT: addl $16, %esp 5902; X86-NOBMI-NEXT: andl %ebx, %esi 5903; X86-NOBMI-NEXT: andl %ebp, %edi 5904; X86-NOBMI-NEXT: subl $8, %esp 5905; X86-NOBMI-NEXT: pushl {{[0-9]+}}(%esp) 5906; X86-NOBMI-NEXT: pushl {{[0-9]+}}(%esp) 5907; X86-NOBMI-NEXT: calll use64@PLT 5908; X86-NOBMI-NEXT: addl $16, %esp 5909; X86-NOBMI-NEXT: movl %esi, %eax 5910; X86-NOBMI-NEXT: movl %edi, %edx 5911; X86-NOBMI-NEXT: addl $12, %esp 5912; X86-NOBMI-NEXT: popl %esi 5913; X86-NOBMI-NEXT: popl %edi 5914; X86-NOBMI-NEXT: popl %ebx 5915; X86-NOBMI-NEXT: popl %ebp 5916; X86-NOBMI-NEXT: retl 5917; 5918; X86-BMI1-LABEL: bextr64_c5_skipextrauses: 5919; X86-BMI1: # %bb.0: 5920; X86-BMI1-NEXT: pushl %ebp 5921; X86-BMI1-NEXT: pushl %ebx 5922; X86-BMI1-NEXT: pushl %edi 5923; X86-BMI1-NEXT: pushl %esi 5924; X86-BMI1-NEXT: subl $12, %esp 5925; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 5926; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 5927; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %ecx 5928; X86-BMI1-NEXT: movl %eax, %edi 5929; X86-BMI1-NEXT: shrl %cl, %edi 5930; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 5931; X86-BMI1-NEXT: testb $32, %cl 5932; X86-BMI1-NEXT: je .LBB46_2 5933; X86-BMI1-NEXT: # %bb.1: 5934; X86-BMI1-NEXT: movl %edi, %esi 5935; X86-BMI1-NEXT: xorl %edi, %edi 5936; X86-BMI1-NEXT: .LBB46_2: 5937; X86-BMI1-NEXT: movb $64, %cl 5938; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 5939; X86-BMI1-NEXT: movl $-1, %ebx 5940; X86-BMI1-NEXT: movl $-1, %ebp 5941; X86-BMI1-NEXT: shrl %cl, %ebp 5942; X86-BMI1-NEXT: testb $32, %cl 5943; X86-BMI1-NEXT: je .LBB46_4 5944; X86-BMI1-NEXT: # %bb.3: 5945; X86-BMI1-NEXT: movl %ebp, %ebx 5946; X86-BMI1-NEXT: xorl %ebp, %ebp 5947; X86-BMI1-NEXT: .LBB46_4: 5948; X86-BMI1-NEXT: subl $8, %esp 5949; X86-BMI1-NEXT: pushl %ebp 5950; X86-BMI1-NEXT: pushl %ebx 5951; X86-BMI1-NEXT: calll use64@PLT 5952; X86-BMI1-NEXT: addl $16, %esp 5953; X86-BMI1-NEXT: andl %ebx, %esi 5954; X86-BMI1-NEXT: andl %ebp, %edi 5955; X86-BMI1-NEXT: subl $8, %esp 5956; X86-BMI1-NEXT: pushl {{[0-9]+}}(%esp) 5957; X86-BMI1-NEXT: pushl {{[0-9]+}}(%esp) 5958; X86-BMI1-NEXT: calll use64@PLT 5959; X86-BMI1-NEXT: addl $16, %esp 5960; X86-BMI1-NEXT: movl %esi, %eax 5961; X86-BMI1-NEXT: movl %edi, %edx 5962; X86-BMI1-NEXT: addl $12, %esp 5963; X86-BMI1-NEXT: popl %esi 5964; X86-BMI1-NEXT: popl %edi 5965; X86-BMI1-NEXT: popl %ebx 5966; X86-BMI1-NEXT: popl %ebp 5967; X86-BMI1-NEXT: retl 5968; 5969; X86-BMI2-LABEL: bextr64_c5_skipextrauses: 5970; X86-BMI2: # %bb.0: 5971; X86-BMI2-NEXT: pushl %ebp 5972; X86-BMI2-NEXT: pushl %ebx 5973; X86-BMI2-NEXT: pushl %edi 5974; X86-BMI2-NEXT: pushl %esi 5975; X86-BMI2-NEXT: subl $12, %esp 5976; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 5977; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 5978; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 5979; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 5980; X86-BMI2-NEXT: shrxl %ecx, %eax, %edi 5981; X86-BMI2-NEXT: testb $32, %cl 5982; X86-BMI2-NEXT: je .LBB46_2 5983; X86-BMI2-NEXT: # %bb.1: 5984; X86-BMI2-NEXT: movl %edi, %esi 5985; X86-BMI2-NEXT: xorl %edi, %edi 5986; X86-BMI2-NEXT: .LBB46_2: 5987; X86-BMI2-NEXT: movb $64, %al 5988; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al 5989; X86-BMI2-NEXT: movl $-1, %ebp 5990; X86-BMI2-NEXT: shrxl %eax, %ebp, %ebx 5991; X86-BMI2-NEXT: testb $32, %al 5992; X86-BMI2-NEXT: je .LBB46_4 5993; X86-BMI2-NEXT: # %bb.3: 5994; X86-BMI2-NEXT: movl %ebx, %ebp 5995; X86-BMI2-NEXT: xorl %ebx, %ebx 5996; X86-BMI2-NEXT: .LBB46_4: 5997; X86-BMI2-NEXT: subl $8, %esp 5998; X86-BMI2-NEXT: pushl %ebx 5999; X86-BMI2-NEXT: pushl %ebp 6000; X86-BMI2-NEXT: calll use64@PLT 6001; X86-BMI2-NEXT: addl $16, %esp 6002; X86-BMI2-NEXT: andl %ebp, %esi 6003; X86-BMI2-NEXT: andl %ebx, %edi 6004; X86-BMI2-NEXT: subl $8, %esp 6005; X86-BMI2-NEXT: pushl {{[0-9]+}}(%esp) 6006; X86-BMI2-NEXT: pushl {{[0-9]+}}(%esp) 6007; X86-BMI2-NEXT: calll use64@PLT 6008; X86-BMI2-NEXT: addl $16, %esp 6009; X86-BMI2-NEXT: movl %esi, %eax 6010; X86-BMI2-NEXT: movl %edi, %edx 6011; X86-BMI2-NEXT: addl $12, %esp 6012; X86-BMI2-NEXT: popl %esi 6013; X86-BMI2-NEXT: popl %edi 6014; X86-BMI2-NEXT: popl %ebx 6015; X86-BMI2-NEXT: popl %ebp 6016; X86-BMI2-NEXT: retl 6017; 6018; X64-NOBMI-LABEL: bextr64_c5_skipextrauses: 6019; X64-NOBMI: # %bb.0: 6020; X64-NOBMI-NEXT: pushq %r15 6021; X64-NOBMI-NEXT: pushq %r14 6022; X64-NOBMI-NEXT: pushq %rbx 6023; X64-NOBMI-NEXT: movq %rsi, %rbx 6024; X64-NOBMI-NEXT: movq %rdi, %r14 6025; X64-NOBMI-NEXT: movl %ebx, %ecx 6026; X64-NOBMI-NEXT: shrq %cl, %r14 6027; X64-NOBMI-NEXT: negb %dl 6028; X64-NOBMI-NEXT: movq $-1, %r15 6029; X64-NOBMI-NEXT: movl %edx, %ecx 6030; X64-NOBMI-NEXT: shrq %cl, %r15 6031; X64-NOBMI-NEXT: movq %r15, %rdi 6032; X64-NOBMI-NEXT: callq use64@PLT 6033; X64-NOBMI-NEXT: andq %r14, %r15 6034; X64-NOBMI-NEXT: movq %rbx, %rdi 6035; X64-NOBMI-NEXT: callq use64@PLT 6036; X64-NOBMI-NEXT: movq %r15, %rax 6037; X64-NOBMI-NEXT: popq %rbx 6038; X64-NOBMI-NEXT: popq %r14 6039; X64-NOBMI-NEXT: popq %r15 6040; X64-NOBMI-NEXT: retq 6041; 6042; X64-BMI1-LABEL: bextr64_c5_skipextrauses: 6043; X64-BMI1: # %bb.0: 6044; X64-BMI1-NEXT: pushq %r15 6045; X64-BMI1-NEXT: pushq %r14 6046; X64-BMI1-NEXT: pushq %rbx 6047; X64-BMI1-NEXT: movq %rsi, %rbx 6048; X64-BMI1-NEXT: movq %rdi, %r14 6049; X64-BMI1-NEXT: movl %ebx, %ecx 6050; X64-BMI1-NEXT: shrq %cl, %r14 6051; X64-BMI1-NEXT: negb %dl 6052; X64-BMI1-NEXT: movq $-1, %r15 6053; X64-BMI1-NEXT: movl %edx, %ecx 6054; X64-BMI1-NEXT: shrq %cl, %r15 6055; X64-BMI1-NEXT: movq %r15, %rdi 6056; X64-BMI1-NEXT: callq use64@PLT 6057; X64-BMI1-NEXT: andq %r14, %r15 6058; X64-BMI1-NEXT: movq %rbx, %rdi 6059; X64-BMI1-NEXT: callq use64@PLT 6060; X64-BMI1-NEXT: movq %r15, %rax 6061; X64-BMI1-NEXT: popq %rbx 6062; X64-BMI1-NEXT: popq %r14 6063; X64-BMI1-NEXT: popq %r15 6064; X64-BMI1-NEXT: retq 6065; 6066; X64-BMI2-LABEL: bextr64_c5_skipextrauses: 6067; X64-BMI2: # %bb.0: 6068; X64-BMI2-NEXT: pushq %r15 6069; X64-BMI2-NEXT: pushq %r14 6070; X64-BMI2-NEXT: pushq %rbx 6071; X64-BMI2-NEXT: movq %rdx, %rbx 6072; X64-BMI2-NEXT: movq %rsi, %r14 6073; X64-BMI2-NEXT: shrxq %rsi, %rdi, %r15 6074; X64-BMI2-NEXT: movq $-1, %rax 6075; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rdi 6076; X64-BMI2-NEXT: callq use64@PLT 6077; X64-BMI2-NEXT: bzhiq %rbx, %r15, %rbx 6078; X64-BMI2-NEXT: movq %r14, %rdi 6079; X64-BMI2-NEXT: callq use64@PLT 6080; X64-BMI2-NEXT: movq %rbx, %rax 6081; X64-BMI2-NEXT: popq %rbx 6082; X64-BMI2-NEXT: popq %r14 6083; X64-BMI2-NEXT: popq %r15 6084; X64-BMI2-NEXT: retq 6085 %shifted = lshr i64 %val, %numskipbits 6086 %numhighbits = sub i64 64, %numlowbits 6087 %mask = lshr i64 -1, %numhighbits 6088 call void @use64(i64 %mask) 6089 %masked = and i64 %mask, %shifted 6090 call void @use64(i64 %numskipbits) 6091 ret i64 %masked 6092} 6093 6094; 64-bit, but with 32-bit output 6095 6096; Everything done in 64-bit, truncation happens last. 6097define i32 @bextr64_32_c0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 6098; X86-NOBMI-LABEL: bextr64_32_c0: 6099; X86-NOBMI: # %bb.0: 6100; X86-NOBMI-NEXT: pushl %esi 6101; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6102; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 6103; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 6104; X86-NOBMI-NEXT: movl %esi, %edx 6105; X86-NOBMI-NEXT: shrl %cl, %edx 6106; X86-NOBMI-NEXT: shrdl %cl, %esi, %eax 6107; X86-NOBMI-NEXT: testb $32, %cl 6108; X86-NOBMI-NEXT: jne .LBB47_2 6109; X86-NOBMI-NEXT: # %bb.1: 6110; X86-NOBMI-NEXT: movl %eax, %edx 6111; X86-NOBMI-NEXT: .LBB47_2: 6112; X86-NOBMI-NEXT: movb $64, %cl 6113; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6114; X86-NOBMI-NEXT: movl $-1, %eax 6115; X86-NOBMI-NEXT: shrl %cl, %eax 6116; X86-NOBMI-NEXT: testb $32, %cl 6117; X86-NOBMI-NEXT: jne .LBB47_4 6118; X86-NOBMI-NEXT: # %bb.3: 6119; X86-NOBMI-NEXT: movl $-1, %eax 6120; X86-NOBMI-NEXT: .LBB47_4: 6121; X86-NOBMI-NEXT: andl %edx, %eax 6122; X86-NOBMI-NEXT: popl %esi 6123; X86-NOBMI-NEXT: retl 6124; 6125; X86-BMI1-LABEL: bextr64_32_c0: 6126; X86-BMI1: # %bb.0: 6127; X86-BMI1-NEXT: pushl %esi 6128; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6129; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 6130; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 6131; X86-BMI1-NEXT: movl %esi, %edx 6132; X86-BMI1-NEXT: shrl %cl, %edx 6133; X86-BMI1-NEXT: shrdl %cl, %esi, %eax 6134; X86-BMI1-NEXT: testb $32, %cl 6135; X86-BMI1-NEXT: jne .LBB47_2 6136; X86-BMI1-NEXT: # %bb.1: 6137; X86-BMI1-NEXT: movl %eax, %edx 6138; X86-BMI1-NEXT: .LBB47_2: 6139; X86-BMI1-NEXT: movb $64, %cl 6140; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 6141; X86-BMI1-NEXT: movl $-1, %eax 6142; X86-BMI1-NEXT: shrl %cl, %eax 6143; X86-BMI1-NEXT: testb $32, %cl 6144; X86-BMI1-NEXT: jne .LBB47_4 6145; X86-BMI1-NEXT: # %bb.3: 6146; X86-BMI1-NEXT: movl $-1, %eax 6147; X86-BMI1-NEXT: .LBB47_4: 6148; X86-BMI1-NEXT: andl %edx, %eax 6149; X86-BMI1-NEXT: popl %esi 6150; X86-BMI1-NEXT: retl 6151; 6152; X86-BMI2-LABEL: bextr64_32_c0: 6153; X86-BMI2: # %bb.0: 6154; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6155; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 6156; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 6157; X86-BMI2-NEXT: shrdl %cl, %eax, %edx 6158; X86-BMI2-NEXT: testb $32, %cl 6159; X86-BMI2-NEXT: je .LBB47_2 6160; X86-BMI2-NEXT: # %bb.1: 6161; X86-BMI2-NEXT: shrxl %ecx, %eax, %edx 6162; X86-BMI2-NEXT: .LBB47_2: 6163; X86-BMI2-NEXT: movb $64, %cl 6164; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 6165; X86-BMI2-NEXT: movl $-1, %eax 6166; X86-BMI2-NEXT: testb $32, %cl 6167; X86-BMI2-NEXT: je .LBB47_4 6168; X86-BMI2-NEXT: # %bb.3: 6169; X86-BMI2-NEXT: shrxl %ecx, %eax, %eax 6170; X86-BMI2-NEXT: .LBB47_4: 6171; X86-BMI2-NEXT: andl %edx, %eax 6172; X86-BMI2-NEXT: retl 6173; 6174; X64-NOBMI-LABEL: bextr64_32_c0: 6175; X64-NOBMI: # %bb.0: 6176; X64-NOBMI-NEXT: movq %rsi, %rcx 6177; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 6178; X64-NOBMI-NEXT: shrq %cl, %rdi 6179; X64-NOBMI-NEXT: negb %dl 6180; X64-NOBMI-NEXT: movq $-1, %rax 6181; X64-NOBMI-NEXT: movl %edx, %ecx 6182; X64-NOBMI-NEXT: shrq %cl, %rax 6183; X64-NOBMI-NEXT: andl %edi, %eax 6184; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 6185; X64-NOBMI-NEXT: retq 6186; 6187; X64-BMI1-LABEL: bextr64_32_c0: 6188; X64-BMI1: # %bb.0: 6189; X64-BMI1-NEXT: shll $8, %edx 6190; X64-BMI1-NEXT: movzbl %sil, %eax 6191; X64-BMI1-NEXT: orl %edx, %eax 6192; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 6193; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 6194; X64-BMI1-NEXT: retq 6195; 6196; X64-BMI2-LABEL: bextr64_32_c0: 6197; X64-BMI2: # %bb.0: 6198; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 6199; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 6200; X64-BMI2-NEXT: retq 6201 %shifted = lshr i64 %val, %numskipbits 6202 %numhighbits = sub i64 64, %numlowbits 6203 %mask = lshr i64 -1, %numhighbits 6204 %masked = and i64 %mask, %shifted 6205 %res = trunc i64 %masked to i32 6206 ret i32 %res 6207} 6208 6209; Shifting happens in 64-bit, then truncation. Masking is 32-bit. 6210define i32 @bextr64_32_c1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind { 6211; X86-NOBMI-LABEL: bextr64_32_c1: 6212; X86-NOBMI: # %bb.0: 6213; X86-NOBMI-NEXT: pushl %esi 6214; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6215; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 6216; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 6217; X86-NOBMI-NEXT: movl %esi, %eax 6218; X86-NOBMI-NEXT: shrl %cl, %eax 6219; X86-NOBMI-NEXT: shrdl %cl, %esi, %edx 6220; X86-NOBMI-NEXT: testb $32, %cl 6221; X86-NOBMI-NEXT: jne .LBB48_2 6222; X86-NOBMI-NEXT: # %bb.1: 6223; X86-NOBMI-NEXT: movl %edx, %eax 6224; X86-NOBMI-NEXT: .LBB48_2: 6225; X86-NOBMI-NEXT: xorl %ecx, %ecx 6226; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6227; X86-NOBMI-NEXT: shll %cl, %eax 6228; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6229; X86-NOBMI-NEXT: shrl %cl, %eax 6230; X86-NOBMI-NEXT: popl %esi 6231; X86-NOBMI-NEXT: retl 6232; 6233; X86-BMI1-LABEL: bextr64_32_c1: 6234; X86-BMI1: # %bb.0: 6235; X86-BMI1-NEXT: pushl %edi 6236; X86-BMI1-NEXT: pushl %esi 6237; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6238; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6239; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 6240; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 6241; X86-BMI1-NEXT: movl %edi, %edx 6242; X86-BMI1-NEXT: shrl %cl, %edx 6243; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 6244; X86-BMI1-NEXT: testb $32, %cl 6245; X86-BMI1-NEXT: jne .LBB48_2 6246; X86-BMI1-NEXT: # %bb.1: 6247; X86-BMI1-NEXT: movl %esi, %edx 6248; X86-BMI1-NEXT: .LBB48_2: 6249; X86-BMI1-NEXT: shll $8, %eax 6250; X86-BMI1-NEXT: bextrl %eax, %edx, %eax 6251; X86-BMI1-NEXT: popl %esi 6252; X86-BMI1-NEXT: popl %edi 6253; X86-BMI1-NEXT: retl 6254; 6255; X86-BMI2-LABEL: bextr64_32_c1: 6256; X86-BMI2: # %bb.0: 6257; X86-BMI2-NEXT: pushl %esi 6258; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6259; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6260; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 6261; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 6262; X86-BMI2-NEXT: shrdl %cl, %esi, %edx 6263; X86-BMI2-NEXT: testb $32, %cl 6264; X86-BMI2-NEXT: je .LBB48_2 6265; X86-BMI2-NEXT: # %bb.1: 6266; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 6267; X86-BMI2-NEXT: .LBB48_2: 6268; X86-BMI2-NEXT: bzhil %eax, %edx, %eax 6269; X86-BMI2-NEXT: popl %esi 6270; X86-BMI2-NEXT: retl 6271; 6272; X64-NOBMI-LABEL: bextr64_32_c1: 6273; X64-NOBMI: # %bb.0: 6274; X64-NOBMI-NEXT: movq %rsi, %rcx 6275; X64-NOBMI-NEXT: movq %rdi, %rax 6276; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 6277; X64-NOBMI-NEXT: shrq %cl, %rax 6278; X64-NOBMI-NEXT: negb %dl 6279; X64-NOBMI-NEXT: movl %edx, %ecx 6280; X64-NOBMI-NEXT: shll %cl, %eax 6281; X64-NOBMI-NEXT: shrl %cl, %eax 6282; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 6283; X64-NOBMI-NEXT: retq 6284; 6285; X64-BMI1-LABEL: bextr64_32_c1: 6286; X64-BMI1: # %bb.0: 6287; X64-BMI1-NEXT: shll $8, %edx 6288; X64-BMI1-NEXT: movzbl %sil, %eax 6289; X64-BMI1-NEXT: orl %edx, %eax 6290; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 6291; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 6292; X64-BMI1-NEXT: retq 6293; 6294; X64-BMI2-LABEL: bextr64_32_c1: 6295; X64-BMI2: # %bb.0: 6296; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 6297; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 6298; X64-BMI2-NEXT: retq 6299 %shifted = lshr i64 %val, %numskipbits 6300 %truncshifted = trunc i64 %shifted to i32 6301 %numhighbits = sub i32 32, %numlowbits 6302 %mask = lshr i32 -1, %numhighbits 6303 %masked = and i32 %mask, %truncshifted 6304 ret i32 %masked 6305} 6306 6307; Shifting happens in 64-bit. Mask is 32-bit, but extended to 64-bit. 6308; Masking is 64-bit. Then truncation. 6309define i32 @bextr64_32_c2(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind { 6310; X86-NOBMI-LABEL: bextr64_32_c2: 6311; X86-NOBMI: # %bb.0: 6312; X86-NOBMI-NEXT: pushl %esi 6313; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6314; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 6315; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 6316; X86-NOBMI-NEXT: movl %esi, %eax 6317; X86-NOBMI-NEXT: shrl %cl, %eax 6318; X86-NOBMI-NEXT: shrdl %cl, %esi, %edx 6319; X86-NOBMI-NEXT: testb $32, %cl 6320; X86-NOBMI-NEXT: jne .LBB49_2 6321; X86-NOBMI-NEXT: # %bb.1: 6322; X86-NOBMI-NEXT: movl %edx, %eax 6323; X86-NOBMI-NEXT: .LBB49_2: 6324; X86-NOBMI-NEXT: xorl %ecx, %ecx 6325; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6326; X86-NOBMI-NEXT: shll %cl, %eax 6327; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6328; X86-NOBMI-NEXT: shrl %cl, %eax 6329; X86-NOBMI-NEXT: popl %esi 6330; X86-NOBMI-NEXT: retl 6331; 6332; X86-BMI1-LABEL: bextr64_32_c2: 6333; X86-BMI1: # %bb.0: 6334; X86-BMI1-NEXT: pushl %edi 6335; X86-BMI1-NEXT: pushl %esi 6336; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6337; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6338; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 6339; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 6340; X86-BMI1-NEXT: movl %edi, %edx 6341; X86-BMI1-NEXT: shrl %cl, %edx 6342; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 6343; X86-BMI1-NEXT: testb $32, %cl 6344; X86-BMI1-NEXT: jne .LBB49_2 6345; X86-BMI1-NEXT: # %bb.1: 6346; X86-BMI1-NEXT: movl %esi, %edx 6347; X86-BMI1-NEXT: .LBB49_2: 6348; X86-BMI1-NEXT: shll $8, %eax 6349; X86-BMI1-NEXT: bextrl %eax, %edx, %eax 6350; X86-BMI1-NEXT: popl %esi 6351; X86-BMI1-NEXT: popl %edi 6352; X86-BMI1-NEXT: retl 6353; 6354; X86-BMI2-LABEL: bextr64_32_c2: 6355; X86-BMI2: # %bb.0: 6356; X86-BMI2-NEXT: pushl %esi 6357; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6358; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6359; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 6360; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 6361; X86-BMI2-NEXT: shrdl %cl, %esi, %edx 6362; X86-BMI2-NEXT: testb $32, %cl 6363; X86-BMI2-NEXT: je .LBB49_2 6364; X86-BMI2-NEXT: # %bb.1: 6365; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 6366; X86-BMI2-NEXT: .LBB49_2: 6367; X86-BMI2-NEXT: bzhil %eax, %edx, %eax 6368; X86-BMI2-NEXT: popl %esi 6369; X86-BMI2-NEXT: retl 6370; 6371; X64-NOBMI-LABEL: bextr64_32_c2: 6372; X64-NOBMI: # %bb.0: 6373; X64-NOBMI-NEXT: movq %rsi, %rcx 6374; X64-NOBMI-NEXT: movq %rdi, %rax 6375; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 6376; X64-NOBMI-NEXT: shrq %cl, %rax 6377; X64-NOBMI-NEXT: negb %dl 6378; X64-NOBMI-NEXT: movl %edx, %ecx 6379; X64-NOBMI-NEXT: shll %cl, %eax 6380; X64-NOBMI-NEXT: shrl %cl, %eax 6381; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 6382; X64-NOBMI-NEXT: retq 6383; 6384; X64-BMI1-LABEL: bextr64_32_c2: 6385; X64-BMI1: # %bb.0: 6386; X64-BMI1-NEXT: shll $8, %edx 6387; X64-BMI1-NEXT: movzbl %sil, %eax 6388; X64-BMI1-NEXT: orl %edx, %eax 6389; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 6390; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 6391; X64-BMI1-NEXT: retq 6392; 6393; X64-BMI2-LABEL: bextr64_32_c2: 6394; X64-BMI2: # %bb.0: 6395; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 6396; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 6397; X64-BMI2-NEXT: retq 6398 %shifted = lshr i64 %val, %numskipbits 6399 %numhighbits = sub i32 32, %numlowbits 6400 %mask = lshr i32 -1, %numhighbits 6401 %zextmask = zext i32 %mask to i64 6402 %masked = and i64 %zextmask, %shifted 6403 %truncmasked = trunc i64 %masked to i32 6404 ret i32 %truncmasked 6405} 6406 6407; Shifting happens in 64-bit. Mask is 32-bit, but calculated in 64-bit. 6408; Masking is 64-bit. Then truncation. 6409define i32 @bextr64_32_c3(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 6410; X86-NOBMI-LABEL: bextr64_32_c3: 6411; X86-NOBMI: # %bb.0: 6412; X86-NOBMI-NEXT: pushl %esi 6413; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6414; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 6415; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 6416; X86-NOBMI-NEXT: movl %esi, %edx 6417; X86-NOBMI-NEXT: shrl %cl, %edx 6418; X86-NOBMI-NEXT: shrdl %cl, %esi, %eax 6419; X86-NOBMI-NEXT: testb $32, %cl 6420; X86-NOBMI-NEXT: jne .LBB50_2 6421; X86-NOBMI-NEXT: # %bb.1: 6422; X86-NOBMI-NEXT: movl %eax, %edx 6423; X86-NOBMI-NEXT: .LBB50_2: 6424; X86-NOBMI-NEXT: movb $64, %cl 6425; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6426; X86-NOBMI-NEXT: xorl %eax, %eax 6427; X86-NOBMI-NEXT: movl $-1, %esi 6428; X86-NOBMI-NEXT: shrdl %cl, %eax, %esi 6429; X86-NOBMI-NEXT: testb $32, %cl 6430; X86-NOBMI-NEXT: jne .LBB50_4 6431; X86-NOBMI-NEXT: # %bb.3: 6432; X86-NOBMI-NEXT: movl %esi, %eax 6433; X86-NOBMI-NEXT: .LBB50_4: 6434; X86-NOBMI-NEXT: andl %edx, %eax 6435; X86-NOBMI-NEXT: popl %esi 6436; X86-NOBMI-NEXT: retl 6437; 6438; X86-BMI1-LABEL: bextr64_32_c3: 6439; X86-BMI1: # %bb.0: 6440; X86-BMI1-NEXT: pushl %esi 6441; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6442; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 6443; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 6444; X86-BMI1-NEXT: movl %esi, %edx 6445; X86-BMI1-NEXT: shrl %cl, %edx 6446; X86-BMI1-NEXT: shrdl %cl, %esi, %eax 6447; X86-BMI1-NEXT: testb $32, %cl 6448; X86-BMI1-NEXT: jne .LBB50_2 6449; X86-BMI1-NEXT: # %bb.1: 6450; X86-BMI1-NEXT: movl %eax, %edx 6451; X86-BMI1-NEXT: .LBB50_2: 6452; X86-BMI1-NEXT: movb $64, %cl 6453; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 6454; X86-BMI1-NEXT: xorl %eax, %eax 6455; X86-BMI1-NEXT: movl $-1, %esi 6456; X86-BMI1-NEXT: shrdl %cl, %eax, %esi 6457; X86-BMI1-NEXT: testb $32, %cl 6458; X86-BMI1-NEXT: jne .LBB50_4 6459; X86-BMI1-NEXT: # %bb.3: 6460; X86-BMI1-NEXT: movl %esi, %eax 6461; X86-BMI1-NEXT: .LBB50_4: 6462; X86-BMI1-NEXT: andl %edx, %eax 6463; X86-BMI1-NEXT: popl %esi 6464; X86-BMI1-NEXT: retl 6465; 6466; X86-BMI2-LABEL: bextr64_32_c3: 6467; X86-BMI2: # %bb.0: 6468; X86-BMI2-NEXT: pushl %esi 6469; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6470; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 6471; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 6472; X86-BMI2-NEXT: shrdl %cl, %eax, %edx 6473; X86-BMI2-NEXT: testb $32, %cl 6474; X86-BMI2-NEXT: je .LBB50_2 6475; X86-BMI2-NEXT: # %bb.1: 6476; X86-BMI2-NEXT: shrxl %ecx, %eax, %edx 6477; X86-BMI2-NEXT: .LBB50_2: 6478; X86-BMI2-NEXT: movb $64, %cl 6479; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 6480; X86-BMI2-NEXT: xorl %eax, %eax 6481; X86-BMI2-NEXT: movl $-1, %esi 6482; X86-BMI2-NEXT: shrdl %cl, %eax, %esi 6483; X86-BMI2-NEXT: testb $32, %cl 6484; X86-BMI2-NEXT: jne .LBB50_4 6485; X86-BMI2-NEXT: # %bb.3: 6486; X86-BMI2-NEXT: movl %esi, %eax 6487; X86-BMI2-NEXT: .LBB50_4: 6488; X86-BMI2-NEXT: andl %edx, %eax 6489; X86-BMI2-NEXT: popl %esi 6490; X86-BMI2-NEXT: retl 6491; 6492; X64-NOBMI-LABEL: bextr64_32_c3: 6493; X64-NOBMI: # %bb.0: 6494; X64-NOBMI-NEXT: movq %rsi, %rcx 6495; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 6496; X64-NOBMI-NEXT: shrq %cl, %rdi 6497; X64-NOBMI-NEXT: negb %dl 6498; X64-NOBMI-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 6499; X64-NOBMI-NEXT: movl %edx, %ecx 6500; X64-NOBMI-NEXT: shrq %cl, %rax 6501; X64-NOBMI-NEXT: andl %edi, %eax 6502; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 6503; X64-NOBMI-NEXT: retq 6504; 6505; X64-BMI1-LABEL: bextr64_32_c3: 6506; X64-BMI1: # %bb.0: 6507; X64-BMI1-NEXT: movq %rsi, %rcx 6508; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $rcx 6509; X64-BMI1-NEXT: shrq %cl, %rdi 6510; X64-BMI1-NEXT: negb %dl 6511; X64-BMI1-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 6512; X64-BMI1-NEXT: movl %edx, %ecx 6513; X64-BMI1-NEXT: shrq %cl, %rax 6514; X64-BMI1-NEXT: andl %edi, %eax 6515; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 6516; X64-BMI1-NEXT: retq 6517; 6518; X64-BMI2-LABEL: bextr64_32_c3: 6519; X64-BMI2: # %bb.0: 6520; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rcx 6521; X64-BMI2-NEXT: negb %dl 6522; X64-BMI2-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF 6523; X64-BMI2-NEXT: shrxq %rdx, %rax, %rax 6524; X64-BMI2-NEXT: andl %ecx, %eax 6525; X64-BMI2-NEXT: # kill: def $eax killed $eax killed $rax 6526; X64-BMI2-NEXT: retq 6527 %shifted = lshr i64 %val, %numskipbits 6528 %numhighbits = sub i64 64, %numlowbits 6529 %mask = lshr i64 4294967295, %numhighbits 6530 %masked = and i64 %mask, %shifted 6531 %truncmasked = trunc i64 %masked to i32 6532 ret i32 %truncmasked 6533} 6534 6535; ---------------------------------------------------------------------------- ; 6536; Pattern d. 32-bit. 6537; ---------------------------------------------------------------------------- ; 6538 6539define i32 @bextr32_d0(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 6540; X86-NOBMI-LABEL: bextr32_d0: 6541; X86-NOBMI: # %bb.0: 6542; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6543; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 6544; X86-NOBMI-NEXT: shrl %cl, %eax 6545; X86-NOBMI-NEXT: xorl %ecx, %ecx 6546; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6547; X86-NOBMI-NEXT: shll %cl, %eax 6548; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6549; X86-NOBMI-NEXT: shrl %cl, %eax 6550; X86-NOBMI-NEXT: retl 6551; 6552; X86-BMI1-LABEL: bextr32_d0: 6553; X86-BMI1: # %bb.0: 6554; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6555; X86-BMI1-NEXT: shll $8, %eax 6556; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6557; X86-BMI1-NEXT: orl %eax, %ecx 6558; X86-BMI1-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %eax 6559; X86-BMI1-NEXT: retl 6560; 6561; X86-BMI2-LABEL: bextr32_d0: 6562; X86-BMI2: # %bb.0: 6563; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6564; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6565; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %ecx 6566; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 6567; X86-BMI2-NEXT: retl 6568; 6569; X64-NOBMI-LABEL: bextr32_d0: 6570; X64-NOBMI: # %bb.0: 6571; X64-NOBMI-NEXT: movl %esi, %ecx 6572; X64-NOBMI-NEXT: movl %edi, %eax 6573; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6574; X64-NOBMI-NEXT: shrl %cl, %eax 6575; X64-NOBMI-NEXT: negb %dl 6576; X64-NOBMI-NEXT: movl %edx, %ecx 6577; X64-NOBMI-NEXT: shll %cl, %eax 6578; X64-NOBMI-NEXT: shrl %cl, %eax 6579; X64-NOBMI-NEXT: retq 6580; 6581; X64-BMI1-LABEL: bextr32_d0: 6582; X64-BMI1: # %bb.0: 6583; X64-BMI1-NEXT: shll $8, %edx 6584; X64-BMI1-NEXT: movzbl %sil, %eax 6585; X64-BMI1-NEXT: orl %edx, %eax 6586; X64-BMI1-NEXT: bextrl %eax, %edi, %eax 6587; X64-BMI1-NEXT: retq 6588; 6589; X64-BMI2-LABEL: bextr32_d0: 6590; X64-BMI2: # %bb.0: 6591; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 6592; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 6593; X64-BMI2-NEXT: retq 6594 %shifted = lshr i32 %val, %numskipbits 6595 %numhighbits = sub i32 32, %numlowbits 6596 %highbitscleared = shl i32 %shifted, %numhighbits 6597 %masked = lshr i32 %highbitscleared, %numhighbits 6598 ret i32 %masked 6599} 6600 6601define i32 @bextr32_d1_indexzext(i32 %val, i8 %numskipbits, i8 %numlowbits) nounwind { 6602; X86-NOBMI-LABEL: bextr32_d1_indexzext: 6603; X86-NOBMI: # %bb.0: 6604; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6605; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 6606; X86-NOBMI-NEXT: shrl %cl, %eax 6607; X86-NOBMI-NEXT: xorl %ecx, %ecx 6608; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6609; X86-NOBMI-NEXT: shll %cl, %eax 6610; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6611; X86-NOBMI-NEXT: shrl %cl, %eax 6612; X86-NOBMI-NEXT: retl 6613; 6614; X86-BMI1-LABEL: bextr32_d1_indexzext: 6615; X86-BMI1: # %bb.0: 6616; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6617; X86-BMI1-NEXT: shll $8, %eax 6618; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6619; X86-BMI1-NEXT: orl %eax, %ecx 6620; X86-BMI1-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %eax 6621; X86-BMI1-NEXT: retl 6622; 6623; X86-BMI2-LABEL: bextr32_d1_indexzext: 6624; X86-BMI2: # %bb.0: 6625; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6626; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6627; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %ecx 6628; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 6629; X86-BMI2-NEXT: retl 6630; 6631; X64-NOBMI-LABEL: bextr32_d1_indexzext: 6632; X64-NOBMI: # %bb.0: 6633; X64-NOBMI-NEXT: movl %esi, %ecx 6634; X64-NOBMI-NEXT: movl %edi, %eax 6635; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6636; X64-NOBMI-NEXT: shrl %cl, %eax 6637; X64-NOBMI-NEXT: negb %dl 6638; X64-NOBMI-NEXT: movl %edx, %ecx 6639; X64-NOBMI-NEXT: shll %cl, %eax 6640; X64-NOBMI-NEXT: shrl %cl, %eax 6641; X64-NOBMI-NEXT: retq 6642; 6643; X64-BMI1-LABEL: bextr32_d1_indexzext: 6644; X64-BMI1: # %bb.0: 6645; X64-BMI1-NEXT: shll $8, %edx 6646; X64-BMI1-NEXT: movzbl %sil, %eax 6647; X64-BMI1-NEXT: orl %edx, %eax 6648; X64-BMI1-NEXT: bextrl %eax, %edi, %eax 6649; X64-BMI1-NEXT: retq 6650; 6651; X64-BMI2-LABEL: bextr32_d1_indexzext: 6652; X64-BMI2: # %bb.0: 6653; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 6654; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 6655; X64-BMI2-NEXT: retq 6656 %skip = zext i8 %numskipbits to i32 6657 %shifted = lshr i32 %val, %skip 6658 %numhighbits = sub i8 32, %numlowbits 6659 %sh_prom = zext i8 %numhighbits to i32 6660 %highbitscleared = shl i32 %shifted, %sh_prom 6661 %masked = lshr i32 %highbitscleared, %sh_prom 6662 ret i32 %masked 6663} 6664 6665define i32 @bextr32_d2_load(ptr %w, i32 %numskipbits, i32 %numlowbits) nounwind { 6666; X86-NOBMI-LABEL: bextr32_d2_load: 6667; X86-NOBMI: # %bb.0: 6668; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6669; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 6670; X86-NOBMI-NEXT: movl (%eax), %eax 6671; X86-NOBMI-NEXT: shrl %cl, %eax 6672; X86-NOBMI-NEXT: xorl %ecx, %ecx 6673; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6674; X86-NOBMI-NEXT: shll %cl, %eax 6675; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6676; X86-NOBMI-NEXT: shrl %cl, %eax 6677; X86-NOBMI-NEXT: retl 6678; 6679; X86-BMI1-LABEL: bextr32_d2_load: 6680; X86-BMI1: # %bb.0: 6681; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 6682; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6683; X86-BMI1-NEXT: shll $8, %ecx 6684; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 6685; X86-BMI1-NEXT: orl %ecx, %edx 6686; X86-BMI1-NEXT: bextrl %edx, (%eax), %eax 6687; X86-BMI1-NEXT: retl 6688; 6689; X86-BMI2-LABEL: bextr32_d2_load: 6690; X86-BMI2: # %bb.0: 6691; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6692; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 6693; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %edx 6694; X86-BMI2-NEXT: shrxl %edx, (%ecx), %ecx 6695; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 6696; X86-BMI2-NEXT: retl 6697; 6698; X64-NOBMI-LABEL: bextr32_d2_load: 6699; X64-NOBMI: # %bb.0: 6700; X64-NOBMI-NEXT: movl %esi, %ecx 6701; X64-NOBMI-NEXT: movl (%rdi), %eax 6702; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6703; X64-NOBMI-NEXT: shrl %cl, %eax 6704; X64-NOBMI-NEXT: negb %dl 6705; X64-NOBMI-NEXT: movl %edx, %ecx 6706; X64-NOBMI-NEXT: shll %cl, %eax 6707; X64-NOBMI-NEXT: shrl %cl, %eax 6708; X64-NOBMI-NEXT: retq 6709; 6710; X64-BMI1-LABEL: bextr32_d2_load: 6711; X64-BMI1: # %bb.0: 6712; X64-BMI1-NEXT: shll $8, %edx 6713; X64-BMI1-NEXT: movzbl %sil, %eax 6714; X64-BMI1-NEXT: orl %edx, %eax 6715; X64-BMI1-NEXT: bextrl %eax, (%rdi), %eax 6716; X64-BMI1-NEXT: retq 6717; 6718; X64-BMI2-LABEL: bextr32_d2_load: 6719; X64-BMI2: # %bb.0: 6720; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 6721; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 6722; X64-BMI2-NEXT: retq 6723 %val = load i32, ptr %w 6724 %shifted = lshr i32 %val, %numskipbits 6725 %numhighbits = sub i32 32, %numlowbits 6726 %highbitscleared = shl i32 %shifted, %numhighbits 6727 %masked = lshr i32 %highbitscleared, %numhighbits 6728 ret i32 %masked 6729} 6730 6731define i32 @bextr32_d3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind { 6732; X86-NOBMI-LABEL: bextr32_d3_load_indexzext: 6733; X86-NOBMI: # %bb.0: 6734; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6735; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 6736; X86-NOBMI-NEXT: movl (%eax), %eax 6737; X86-NOBMI-NEXT: shrl %cl, %eax 6738; X86-NOBMI-NEXT: xorl %ecx, %ecx 6739; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6740; X86-NOBMI-NEXT: shll %cl, %eax 6741; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6742; X86-NOBMI-NEXT: shrl %cl, %eax 6743; X86-NOBMI-NEXT: retl 6744; 6745; X86-BMI1-LABEL: bextr32_d3_load_indexzext: 6746; X86-BMI1: # %bb.0: 6747; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 6748; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6749; X86-BMI1-NEXT: shll $8, %ecx 6750; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %edx 6751; X86-BMI1-NEXT: orl %ecx, %edx 6752; X86-BMI1-NEXT: bextrl %edx, (%eax), %eax 6753; X86-BMI1-NEXT: retl 6754; 6755; X86-BMI2-LABEL: bextr32_d3_load_indexzext: 6756; X86-BMI2: # %bb.0: 6757; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6758; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 6759; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %edx 6760; X86-BMI2-NEXT: shrxl %edx, (%ecx), %ecx 6761; X86-BMI2-NEXT: bzhil %eax, %ecx, %eax 6762; X86-BMI2-NEXT: retl 6763; 6764; X64-NOBMI-LABEL: bextr32_d3_load_indexzext: 6765; X64-NOBMI: # %bb.0: 6766; X64-NOBMI-NEXT: movl %esi, %ecx 6767; X64-NOBMI-NEXT: movl (%rdi), %eax 6768; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6769; X64-NOBMI-NEXT: shrl %cl, %eax 6770; X64-NOBMI-NEXT: negb %dl 6771; X64-NOBMI-NEXT: movl %edx, %ecx 6772; X64-NOBMI-NEXT: shll %cl, %eax 6773; X64-NOBMI-NEXT: shrl %cl, %eax 6774; X64-NOBMI-NEXT: retq 6775; 6776; X64-BMI1-LABEL: bextr32_d3_load_indexzext: 6777; X64-BMI1: # %bb.0: 6778; X64-BMI1-NEXT: shll $8, %edx 6779; X64-BMI1-NEXT: movzbl %sil, %eax 6780; X64-BMI1-NEXT: orl %edx, %eax 6781; X64-BMI1-NEXT: bextrl %eax, (%rdi), %eax 6782; X64-BMI1-NEXT: retq 6783; 6784; X64-BMI2-LABEL: bextr32_d3_load_indexzext: 6785; X64-BMI2: # %bb.0: 6786; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 6787; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 6788; X64-BMI2-NEXT: retq 6789 %val = load i32, ptr %w 6790 %skip = zext i8 %numskipbits to i32 6791 %shifted = lshr i32 %val, %skip 6792 %numhighbits = sub i8 32, %numlowbits 6793 %sh_prom = zext i8 %numhighbits to i32 6794 %highbitscleared = shl i32 %shifted, %sh_prom 6795 %masked = lshr i32 %highbitscleared, %sh_prom 6796 ret i32 %masked 6797} 6798 6799define i32 @bextr32_d5_skipextrauses(i32 %val, i32 %numskipbits, i32 %numlowbits) nounwind { 6800; X86-NOBMI-LABEL: bextr32_d5_skipextrauses: 6801; X86-NOBMI: # %bb.0: 6802; X86-NOBMI-NEXT: pushl %esi 6803; X86-NOBMI-NEXT: subl $8, %esp 6804; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 6805; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 6806; X86-NOBMI-NEXT: movl %eax, %ecx 6807; X86-NOBMI-NEXT: shrl %cl, %esi 6808; X86-NOBMI-NEXT: xorl %ecx, %ecx 6809; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6810; X86-NOBMI-NEXT: shll %cl, %esi 6811; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 6812; X86-NOBMI-NEXT: shrl %cl, %esi 6813; X86-NOBMI-NEXT: movl %eax, (%esp) 6814; X86-NOBMI-NEXT: calll use32@PLT 6815; X86-NOBMI-NEXT: movl %esi, %eax 6816; X86-NOBMI-NEXT: addl $8, %esp 6817; X86-NOBMI-NEXT: popl %esi 6818; X86-NOBMI-NEXT: retl 6819; 6820; X86-BMI1-LABEL: bextr32_d5_skipextrauses: 6821; X86-BMI1: # %bb.0: 6822; X86-BMI1-NEXT: pushl %esi 6823; X86-BMI1-NEXT: subl $8, %esp 6824; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6825; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 6826; X86-BMI1-NEXT: shll $8, %ecx 6827; X86-BMI1-NEXT: movzbl %al, %edx 6828; X86-BMI1-NEXT: orl %ecx, %edx 6829; X86-BMI1-NEXT: bextrl %edx, {{[0-9]+}}(%esp), %esi 6830; X86-BMI1-NEXT: movl %eax, (%esp) 6831; X86-BMI1-NEXT: calll use32@PLT 6832; X86-BMI1-NEXT: movl %esi, %eax 6833; X86-BMI1-NEXT: addl $8, %esp 6834; X86-BMI1-NEXT: popl %esi 6835; X86-BMI1-NEXT: retl 6836; 6837; X86-BMI2-LABEL: bextr32_d5_skipextrauses: 6838; X86-BMI2: # %bb.0: 6839; X86-BMI2-NEXT: pushl %esi 6840; X86-BMI2-NEXT: subl $8, %esp 6841; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 6842; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 6843; X86-BMI2-NEXT: shrxl %ecx, {{[0-9]+}}(%esp), %edx 6844; X86-BMI2-NEXT: bzhil %eax, %edx, %esi 6845; X86-BMI2-NEXT: movl %ecx, (%esp) 6846; X86-BMI2-NEXT: calll use32@PLT 6847; X86-BMI2-NEXT: movl %esi, %eax 6848; X86-BMI2-NEXT: addl $8, %esp 6849; X86-BMI2-NEXT: popl %esi 6850; X86-BMI2-NEXT: retl 6851; 6852; X64-NOBMI-LABEL: bextr32_d5_skipextrauses: 6853; X64-NOBMI: # %bb.0: 6854; X64-NOBMI-NEXT: pushq %rbx 6855; X64-NOBMI-NEXT: movl %edi, %ebx 6856; X64-NOBMI-NEXT: movl %esi, %ecx 6857; X64-NOBMI-NEXT: shrl %cl, %ebx 6858; X64-NOBMI-NEXT: negb %dl 6859; X64-NOBMI-NEXT: movl %edx, %ecx 6860; X64-NOBMI-NEXT: shll %cl, %ebx 6861; X64-NOBMI-NEXT: shrl %cl, %ebx 6862; X64-NOBMI-NEXT: movl %esi, %edi 6863; X64-NOBMI-NEXT: callq use32@PLT 6864; X64-NOBMI-NEXT: movl %ebx, %eax 6865; X64-NOBMI-NEXT: popq %rbx 6866; X64-NOBMI-NEXT: retq 6867; 6868; X64-BMI1-LABEL: bextr32_d5_skipextrauses: 6869; X64-BMI1: # %bb.0: 6870; X64-BMI1-NEXT: pushq %rbx 6871; X64-BMI1-NEXT: shll $8, %edx 6872; X64-BMI1-NEXT: movzbl %sil, %eax 6873; X64-BMI1-NEXT: orl %edx, %eax 6874; X64-BMI1-NEXT: bextrl %eax, %edi, %ebx 6875; X64-BMI1-NEXT: movl %esi, %edi 6876; X64-BMI1-NEXT: callq use32@PLT 6877; X64-BMI1-NEXT: movl %ebx, %eax 6878; X64-BMI1-NEXT: popq %rbx 6879; X64-BMI1-NEXT: retq 6880; 6881; X64-BMI2-LABEL: bextr32_d5_skipextrauses: 6882; X64-BMI2: # %bb.0: 6883; X64-BMI2-NEXT: pushq %rbx 6884; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 6885; X64-BMI2-NEXT: bzhil %edx, %eax, %ebx 6886; X64-BMI2-NEXT: movl %esi, %edi 6887; X64-BMI2-NEXT: callq use32@PLT 6888; X64-BMI2-NEXT: movl %ebx, %eax 6889; X64-BMI2-NEXT: popq %rbx 6890; X64-BMI2-NEXT: retq 6891 %shifted = lshr i32 %val, %numskipbits 6892 %numhighbits = sub i32 32, %numlowbits 6893 %highbitscleared = shl i32 %shifted, %numhighbits 6894 %masked = lshr i32 %highbitscleared, %numhighbits 6895 call void @use32(i32 %numskipbits) 6896 ret i32 %masked 6897} 6898 6899; 64-bit. 6900 6901define i64 @bextr64_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 6902; X86-NOBMI-LABEL: bextr64_d0: 6903; X86-NOBMI: # %bb.0: 6904; X86-NOBMI-NEXT: pushl %ebx 6905; X86-NOBMI-NEXT: pushl %edi 6906; X86-NOBMI-NEXT: pushl %esi 6907; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6908; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 6909; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 6910; X86-NOBMI-NEXT: movl %edx, %eax 6911; X86-NOBMI-NEXT: shrl %cl, %eax 6912; X86-NOBMI-NEXT: shrdl %cl, %edx, %edi 6913; X86-NOBMI-NEXT: xorl %esi, %esi 6914; X86-NOBMI-NEXT: testb $32, %cl 6915; X86-NOBMI-NEXT: je .LBB56_2 6916; X86-NOBMI-NEXT: # %bb.1: 6917; X86-NOBMI-NEXT: movl %eax, %edi 6918; X86-NOBMI-NEXT: xorl %eax, %eax 6919; X86-NOBMI-NEXT: .LBB56_2: 6920; X86-NOBMI-NEXT: movb $64, %cl 6921; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 6922; X86-NOBMI-NEXT: shldl %cl, %edi, %eax 6923; X86-NOBMI-NEXT: shll %cl, %edi 6924; X86-NOBMI-NEXT: testb $32, %cl 6925; X86-NOBMI-NEXT: movl %edi, %ebx 6926; X86-NOBMI-NEXT: jne .LBB56_4 6927; X86-NOBMI-NEXT: # %bb.3: 6928; X86-NOBMI-NEXT: movl %eax, %ebx 6929; X86-NOBMI-NEXT: .LBB56_4: 6930; X86-NOBMI-NEXT: movl %ebx, %eax 6931; X86-NOBMI-NEXT: shrl %cl, %eax 6932; X86-NOBMI-NEXT: testb $32, %cl 6933; X86-NOBMI-NEXT: movl $0, %edx 6934; X86-NOBMI-NEXT: jne .LBB56_6 6935; X86-NOBMI-NEXT: # %bb.5: 6936; X86-NOBMI-NEXT: movl %edi, %esi 6937; X86-NOBMI-NEXT: movl %eax, %edx 6938; X86-NOBMI-NEXT: .LBB56_6: 6939; X86-NOBMI-NEXT: shrdl %cl, %ebx, %esi 6940; X86-NOBMI-NEXT: testb $32, %cl 6941; X86-NOBMI-NEXT: jne .LBB56_8 6942; X86-NOBMI-NEXT: # %bb.7: 6943; X86-NOBMI-NEXT: movl %esi, %eax 6944; X86-NOBMI-NEXT: .LBB56_8: 6945; X86-NOBMI-NEXT: popl %esi 6946; X86-NOBMI-NEXT: popl %edi 6947; X86-NOBMI-NEXT: popl %ebx 6948; X86-NOBMI-NEXT: retl 6949; 6950; X86-BMI1-LABEL: bextr64_d0: 6951; X86-BMI1: # %bb.0: 6952; X86-BMI1-NEXT: pushl %ebx 6953; X86-BMI1-NEXT: pushl %edi 6954; X86-BMI1-NEXT: pushl %esi 6955; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 6956; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 6957; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edx 6958; X86-BMI1-NEXT: movl %edx, %eax 6959; X86-BMI1-NEXT: shrl %cl, %eax 6960; X86-BMI1-NEXT: shrdl %cl, %edx, %edi 6961; X86-BMI1-NEXT: xorl %esi, %esi 6962; X86-BMI1-NEXT: testb $32, %cl 6963; X86-BMI1-NEXT: je .LBB56_2 6964; X86-BMI1-NEXT: # %bb.1: 6965; X86-BMI1-NEXT: movl %eax, %edi 6966; X86-BMI1-NEXT: xorl %eax, %eax 6967; X86-BMI1-NEXT: .LBB56_2: 6968; X86-BMI1-NEXT: movb $64, %cl 6969; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 6970; X86-BMI1-NEXT: shldl %cl, %edi, %eax 6971; X86-BMI1-NEXT: shll %cl, %edi 6972; X86-BMI1-NEXT: testb $32, %cl 6973; X86-BMI1-NEXT: movl %edi, %ebx 6974; X86-BMI1-NEXT: jne .LBB56_4 6975; X86-BMI1-NEXT: # %bb.3: 6976; X86-BMI1-NEXT: movl %eax, %ebx 6977; X86-BMI1-NEXT: .LBB56_4: 6978; X86-BMI1-NEXT: movl %ebx, %eax 6979; X86-BMI1-NEXT: shrl %cl, %eax 6980; X86-BMI1-NEXT: testb $32, %cl 6981; X86-BMI1-NEXT: movl $0, %edx 6982; X86-BMI1-NEXT: jne .LBB56_6 6983; X86-BMI1-NEXT: # %bb.5: 6984; X86-BMI1-NEXT: movl %edi, %esi 6985; X86-BMI1-NEXT: movl %eax, %edx 6986; X86-BMI1-NEXT: .LBB56_6: 6987; X86-BMI1-NEXT: shrdl %cl, %ebx, %esi 6988; X86-BMI1-NEXT: testb $32, %cl 6989; X86-BMI1-NEXT: jne .LBB56_8 6990; X86-BMI1-NEXT: # %bb.7: 6991; X86-BMI1-NEXT: movl %esi, %eax 6992; X86-BMI1-NEXT: .LBB56_8: 6993; X86-BMI1-NEXT: popl %esi 6994; X86-BMI1-NEXT: popl %edi 6995; X86-BMI1-NEXT: popl %ebx 6996; X86-BMI1-NEXT: retl 6997; 6998; X86-BMI2-LABEL: bextr64_d0: 6999; X86-BMI2: # %bb.0: 7000; X86-BMI2-NEXT: pushl %edi 7001; X86-BMI2-NEXT: pushl %esi 7002; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7003; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 7004; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 7005; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 7006; X86-BMI2-NEXT: shrxl %ecx, %edx, %esi 7007; X86-BMI2-NEXT: xorl %edx, %edx 7008; X86-BMI2-NEXT: testb $32, %cl 7009; X86-BMI2-NEXT: je .LBB56_2 7010; X86-BMI2-NEXT: # %bb.1: 7011; X86-BMI2-NEXT: movl %esi, %eax 7012; X86-BMI2-NEXT: xorl %esi, %esi 7013; X86-BMI2-NEXT: .LBB56_2: 7014; X86-BMI2-NEXT: movb $64, %cl 7015; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 7016; X86-BMI2-NEXT: shldl %cl, %eax, %esi 7017; X86-BMI2-NEXT: shlxl %ecx, %eax, %edi 7018; X86-BMI2-NEXT: testb $32, %cl 7019; X86-BMI2-NEXT: je .LBB56_4 7020; X86-BMI2-NEXT: # %bb.3: 7021; X86-BMI2-NEXT: movl %edi, %esi 7022; X86-BMI2-NEXT: movl $0, %edi 7023; X86-BMI2-NEXT: .LBB56_4: 7024; X86-BMI2-NEXT: shrxl %ecx, %esi, %eax 7025; X86-BMI2-NEXT: jne .LBB56_6 7026; X86-BMI2-NEXT: # %bb.5: 7027; X86-BMI2-NEXT: movl %eax, %edx 7028; X86-BMI2-NEXT: .LBB56_6: 7029; X86-BMI2-NEXT: shrdl %cl, %esi, %edi 7030; X86-BMI2-NEXT: testb $32, %cl 7031; X86-BMI2-NEXT: jne .LBB56_8 7032; X86-BMI2-NEXT: # %bb.7: 7033; X86-BMI2-NEXT: movl %edi, %eax 7034; X86-BMI2-NEXT: .LBB56_8: 7035; X86-BMI2-NEXT: popl %esi 7036; X86-BMI2-NEXT: popl %edi 7037; X86-BMI2-NEXT: retl 7038; 7039; X64-NOBMI-LABEL: bextr64_d0: 7040; X64-NOBMI: # %bb.0: 7041; X64-NOBMI-NEXT: movq %rsi, %rcx 7042; X64-NOBMI-NEXT: movq %rdi, %rax 7043; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 7044; X64-NOBMI-NEXT: shrq %cl, %rax 7045; X64-NOBMI-NEXT: negb %dl 7046; X64-NOBMI-NEXT: movl %edx, %ecx 7047; X64-NOBMI-NEXT: shlq %cl, %rax 7048; X64-NOBMI-NEXT: shrq %cl, %rax 7049; X64-NOBMI-NEXT: retq 7050; 7051; X64-BMI1-LABEL: bextr64_d0: 7052; X64-BMI1: # %bb.0: 7053; X64-BMI1-NEXT: shll $8, %edx 7054; X64-BMI1-NEXT: movzbl %sil, %eax 7055; X64-BMI1-NEXT: orl %edx, %eax 7056; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 7057; X64-BMI1-NEXT: retq 7058; 7059; X64-BMI2-LABEL: bextr64_d0: 7060; X64-BMI2: # %bb.0: 7061; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 7062; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 7063; X64-BMI2-NEXT: retq 7064 %shifted = lshr i64 %val, %numskipbits 7065 %numhighbits = sub i64 64, %numlowbits 7066 %highbitscleared = shl i64 %shifted, %numhighbits 7067 %masked = lshr i64 %highbitscleared, %numhighbits 7068 ret i64 %masked 7069} 7070 7071define i64 @bextr64_d1_indexzext(i64 %val, i8 %numskipbits, i8 %numlowbits) nounwind { 7072; X86-NOBMI-LABEL: bextr64_d1_indexzext: 7073; X86-NOBMI: # %bb.0: 7074; X86-NOBMI-NEXT: pushl %ebx 7075; X86-NOBMI-NEXT: pushl %edi 7076; X86-NOBMI-NEXT: pushl %esi 7077; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7078; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edi 7079; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 7080; X86-NOBMI-NEXT: movl %edx, %eax 7081; X86-NOBMI-NEXT: shrl %cl, %eax 7082; X86-NOBMI-NEXT: shrdl %cl, %edx, %edi 7083; X86-NOBMI-NEXT: xorl %esi, %esi 7084; X86-NOBMI-NEXT: testb $32, %cl 7085; X86-NOBMI-NEXT: je .LBB57_2 7086; X86-NOBMI-NEXT: # %bb.1: 7087; X86-NOBMI-NEXT: movl %eax, %edi 7088; X86-NOBMI-NEXT: xorl %eax, %eax 7089; X86-NOBMI-NEXT: .LBB57_2: 7090; X86-NOBMI-NEXT: movb $64, %cl 7091; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 7092; X86-NOBMI-NEXT: shldl %cl, %edi, %eax 7093; X86-NOBMI-NEXT: shll %cl, %edi 7094; X86-NOBMI-NEXT: testb $32, %cl 7095; X86-NOBMI-NEXT: movl %edi, %ebx 7096; X86-NOBMI-NEXT: jne .LBB57_4 7097; X86-NOBMI-NEXT: # %bb.3: 7098; X86-NOBMI-NEXT: movl %eax, %ebx 7099; X86-NOBMI-NEXT: .LBB57_4: 7100; X86-NOBMI-NEXT: movl %ebx, %eax 7101; X86-NOBMI-NEXT: shrl %cl, %eax 7102; X86-NOBMI-NEXT: testb $32, %cl 7103; X86-NOBMI-NEXT: movl $0, %edx 7104; X86-NOBMI-NEXT: jne .LBB57_6 7105; X86-NOBMI-NEXT: # %bb.5: 7106; X86-NOBMI-NEXT: movl %edi, %esi 7107; X86-NOBMI-NEXT: movl %eax, %edx 7108; X86-NOBMI-NEXT: .LBB57_6: 7109; X86-NOBMI-NEXT: shrdl %cl, %ebx, %esi 7110; X86-NOBMI-NEXT: testb $32, %cl 7111; X86-NOBMI-NEXT: jne .LBB57_8 7112; X86-NOBMI-NEXT: # %bb.7: 7113; X86-NOBMI-NEXT: movl %esi, %eax 7114; X86-NOBMI-NEXT: .LBB57_8: 7115; X86-NOBMI-NEXT: popl %esi 7116; X86-NOBMI-NEXT: popl %edi 7117; X86-NOBMI-NEXT: popl %ebx 7118; X86-NOBMI-NEXT: retl 7119; 7120; X86-BMI1-LABEL: bextr64_d1_indexzext: 7121; X86-BMI1: # %bb.0: 7122; X86-BMI1-NEXT: pushl %ebx 7123; X86-BMI1-NEXT: pushl %edi 7124; X86-BMI1-NEXT: pushl %esi 7125; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7126; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 7127; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edx 7128; X86-BMI1-NEXT: movl %edx, %eax 7129; X86-BMI1-NEXT: shrl %cl, %eax 7130; X86-BMI1-NEXT: shrdl %cl, %edx, %edi 7131; X86-BMI1-NEXT: xorl %esi, %esi 7132; X86-BMI1-NEXT: testb $32, %cl 7133; X86-BMI1-NEXT: je .LBB57_2 7134; X86-BMI1-NEXT: # %bb.1: 7135; X86-BMI1-NEXT: movl %eax, %edi 7136; X86-BMI1-NEXT: xorl %eax, %eax 7137; X86-BMI1-NEXT: .LBB57_2: 7138; X86-BMI1-NEXT: movb $64, %cl 7139; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 7140; X86-BMI1-NEXT: shldl %cl, %edi, %eax 7141; X86-BMI1-NEXT: shll %cl, %edi 7142; X86-BMI1-NEXT: testb $32, %cl 7143; X86-BMI1-NEXT: movl %edi, %ebx 7144; X86-BMI1-NEXT: jne .LBB57_4 7145; X86-BMI1-NEXT: # %bb.3: 7146; X86-BMI1-NEXT: movl %eax, %ebx 7147; X86-BMI1-NEXT: .LBB57_4: 7148; X86-BMI1-NEXT: movl %ebx, %eax 7149; X86-BMI1-NEXT: shrl %cl, %eax 7150; X86-BMI1-NEXT: testb $32, %cl 7151; X86-BMI1-NEXT: movl $0, %edx 7152; X86-BMI1-NEXT: jne .LBB57_6 7153; X86-BMI1-NEXT: # %bb.5: 7154; X86-BMI1-NEXT: movl %edi, %esi 7155; X86-BMI1-NEXT: movl %eax, %edx 7156; X86-BMI1-NEXT: .LBB57_6: 7157; X86-BMI1-NEXT: shrdl %cl, %ebx, %esi 7158; X86-BMI1-NEXT: testb $32, %cl 7159; X86-BMI1-NEXT: jne .LBB57_8 7160; X86-BMI1-NEXT: # %bb.7: 7161; X86-BMI1-NEXT: movl %esi, %eax 7162; X86-BMI1-NEXT: .LBB57_8: 7163; X86-BMI1-NEXT: popl %esi 7164; X86-BMI1-NEXT: popl %edi 7165; X86-BMI1-NEXT: popl %ebx 7166; X86-BMI1-NEXT: retl 7167; 7168; X86-BMI2-LABEL: bextr64_d1_indexzext: 7169; X86-BMI2: # %bb.0: 7170; X86-BMI2-NEXT: pushl %edi 7171; X86-BMI2-NEXT: pushl %esi 7172; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7173; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 7174; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 7175; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 7176; X86-BMI2-NEXT: shrxl %ecx, %edx, %esi 7177; X86-BMI2-NEXT: xorl %edx, %edx 7178; X86-BMI2-NEXT: testb $32, %cl 7179; X86-BMI2-NEXT: je .LBB57_2 7180; X86-BMI2-NEXT: # %bb.1: 7181; X86-BMI2-NEXT: movl %esi, %eax 7182; X86-BMI2-NEXT: xorl %esi, %esi 7183; X86-BMI2-NEXT: .LBB57_2: 7184; X86-BMI2-NEXT: movb $64, %cl 7185; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 7186; X86-BMI2-NEXT: shldl %cl, %eax, %esi 7187; X86-BMI2-NEXT: shlxl %ecx, %eax, %edi 7188; X86-BMI2-NEXT: testb $32, %cl 7189; X86-BMI2-NEXT: je .LBB57_4 7190; X86-BMI2-NEXT: # %bb.3: 7191; X86-BMI2-NEXT: movl %edi, %esi 7192; X86-BMI2-NEXT: movl $0, %edi 7193; X86-BMI2-NEXT: .LBB57_4: 7194; X86-BMI2-NEXT: shrxl %ecx, %esi, %eax 7195; X86-BMI2-NEXT: jne .LBB57_6 7196; X86-BMI2-NEXT: # %bb.5: 7197; X86-BMI2-NEXT: movl %eax, %edx 7198; X86-BMI2-NEXT: .LBB57_6: 7199; X86-BMI2-NEXT: shrdl %cl, %esi, %edi 7200; X86-BMI2-NEXT: testb $32, %cl 7201; X86-BMI2-NEXT: jne .LBB57_8 7202; X86-BMI2-NEXT: # %bb.7: 7203; X86-BMI2-NEXT: movl %edi, %eax 7204; X86-BMI2-NEXT: .LBB57_8: 7205; X86-BMI2-NEXT: popl %esi 7206; X86-BMI2-NEXT: popl %edi 7207; X86-BMI2-NEXT: retl 7208; 7209; X64-NOBMI-LABEL: bextr64_d1_indexzext: 7210; X64-NOBMI: # %bb.0: 7211; X64-NOBMI-NEXT: movl %esi, %ecx 7212; X64-NOBMI-NEXT: movq %rdi, %rax 7213; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 7214; X64-NOBMI-NEXT: shrq %cl, %rax 7215; X64-NOBMI-NEXT: negb %dl 7216; X64-NOBMI-NEXT: movl %edx, %ecx 7217; X64-NOBMI-NEXT: shlq %cl, %rax 7218; X64-NOBMI-NEXT: shrq %cl, %rax 7219; X64-NOBMI-NEXT: retq 7220; 7221; X64-BMI1-LABEL: bextr64_d1_indexzext: 7222; X64-BMI1: # %bb.0: 7223; X64-BMI1-NEXT: shll $8, %edx 7224; X64-BMI1-NEXT: movzbl %sil, %eax 7225; X64-BMI1-NEXT: orl %edx, %eax 7226; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 7227; X64-BMI1-NEXT: retq 7228; 7229; X64-BMI2-LABEL: bextr64_d1_indexzext: 7230; X64-BMI2: # %bb.0: 7231; X64-BMI2-NEXT: # kill: def $edx killed $edx def $rdx 7232; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 7233; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 7234; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 7235; X64-BMI2-NEXT: retq 7236 %skip = zext i8 %numskipbits to i64 7237 %shifted = lshr i64 %val, %skip 7238 %numhighbits = sub i8 64, %numlowbits 7239 %sh_prom = zext i8 %numhighbits to i64 7240 %highbitscleared = shl i64 %shifted, %sh_prom 7241 %masked = lshr i64 %highbitscleared, %sh_prom 7242 ret i64 %masked 7243} 7244 7245define i64 @bextr64_d2_load(ptr %w, i64 %numskipbits, i64 %numlowbits) nounwind { 7246; X86-NOBMI-LABEL: bextr64_d2_load: 7247; X86-NOBMI: # %bb.0: 7248; X86-NOBMI-NEXT: pushl %ebx 7249; X86-NOBMI-NEXT: pushl %edi 7250; X86-NOBMI-NEXT: pushl %esi 7251; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7252; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 7253; X86-NOBMI-NEXT: movl (%eax), %edi 7254; X86-NOBMI-NEXT: movl 4(%eax), %edx 7255; X86-NOBMI-NEXT: movl %edx, %eax 7256; X86-NOBMI-NEXT: shrl %cl, %eax 7257; X86-NOBMI-NEXT: shrdl %cl, %edx, %edi 7258; X86-NOBMI-NEXT: xorl %esi, %esi 7259; X86-NOBMI-NEXT: testb $32, %cl 7260; X86-NOBMI-NEXT: je .LBB58_2 7261; X86-NOBMI-NEXT: # %bb.1: 7262; X86-NOBMI-NEXT: movl %eax, %edi 7263; X86-NOBMI-NEXT: xorl %eax, %eax 7264; X86-NOBMI-NEXT: .LBB58_2: 7265; X86-NOBMI-NEXT: movb $64, %cl 7266; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 7267; X86-NOBMI-NEXT: shldl %cl, %edi, %eax 7268; X86-NOBMI-NEXT: shll %cl, %edi 7269; X86-NOBMI-NEXT: testb $32, %cl 7270; X86-NOBMI-NEXT: movl %edi, %ebx 7271; X86-NOBMI-NEXT: jne .LBB58_4 7272; X86-NOBMI-NEXT: # %bb.3: 7273; X86-NOBMI-NEXT: movl %eax, %ebx 7274; X86-NOBMI-NEXT: .LBB58_4: 7275; X86-NOBMI-NEXT: movl %ebx, %eax 7276; X86-NOBMI-NEXT: shrl %cl, %eax 7277; X86-NOBMI-NEXT: testb $32, %cl 7278; X86-NOBMI-NEXT: movl $0, %edx 7279; X86-NOBMI-NEXT: jne .LBB58_6 7280; X86-NOBMI-NEXT: # %bb.5: 7281; X86-NOBMI-NEXT: movl %edi, %esi 7282; X86-NOBMI-NEXT: movl %eax, %edx 7283; X86-NOBMI-NEXT: .LBB58_6: 7284; X86-NOBMI-NEXT: shrdl %cl, %ebx, %esi 7285; X86-NOBMI-NEXT: testb $32, %cl 7286; X86-NOBMI-NEXT: jne .LBB58_8 7287; X86-NOBMI-NEXT: # %bb.7: 7288; X86-NOBMI-NEXT: movl %esi, %eax 7289; X86-NOBMI-NEXT: .LBB58_8: 7290; X86-NOBMI-NEXT: popl %esi 7291; X86-NOBMI-NEXT: popl %edi 7292; X86-NOBMI-NEXT: popl %ebx 7293; X86-NOBMI-NEXT: retl 7294; 7295; X86-BMI1-LABEL: bextr64_d2_load: 7296; X86-BMI1: # %bb.0: 7297; X86-BMI1-NEXT: pushl %ebx 7298; X86-BMI1-NEXT: pushl %edi 7299; X86-BMI1-NEXT: pushl %esi 7300; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7301; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 7302; X86-BMI1-NEXT: movl (%eax), %edi 7303; X86-BMI1-NEXT: movl 4(%eax), %edx 7304; X86-BMI1-NEXT: movl %edx, %eax 7305; X86-BMI1-NEXT: shrl %cl, %eax 7306; X86-BMI1-NEXT: shrdl %cl, %edx, %edi 7307; X86-BMI1-NEXT: xorl %esi, %esi 7308; X86-BMI1-NEXT: testb $32, %cl 7309; X86-BMI1-NEXT: je .LBB58_2 7310; X86-BMI1-NEXT: # %bb.1: 7311; X86-BMI1-NEXT: movl %eax, %edi 7312; X86-BMI1-NEXT: xorl %eax, %eax 7313; X86-BMI1-NEXT: .LBB58_2: 7314; X86-BMI1-NEXT: movb $64, %cl 7315; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 7316; X86-BMI1-NEXT: shldl %cl, %edi, %eax 7317; X86-BMI1-NEXT: shll %cl, %edi 7318; X86-BMI1-NEXT: testb $32, %cl 7319; X86-BMI1-NEXT: movl %edi, %ebx 7320; X86-BMI1-NEXT: jne .LBB58_4 7321; X86-BMI1-NEXT: # %bb.3: 7322; X86-BMI1-NEXT: movl %eax, %ebx 7323; X86-BMI1-NEXT: .LBB58_4: 7324; X86-BMI1-NEXT: movl %ebx, %eax 7325; X86-BMI1-NEXT: shrl %cl, %eax 7326; X86-BMI1-NEXT: testb $32, %cl 7327; X86-BMI1-NEXT: movl $0, %edx 7328; X86-BMI1-NEXT: jne .LBB58_6 7329; X86-BMI1-NEXT: # %bb.5: 7330; X86-BMI1-NEXT: movl %edi, %esi 7331; X86-BMI1-NEXT: movl %eax, %edx 7332; X86-BMI1-NEXT: .LBB58_6: 7333; X86-BMI1-NEXT: shrdl %cl, %ebx, %esi 7334; X86-BMI1-NEXT: testb $32, %cl 7335; X86-BMI1-NEXT: jne .LBB58_8 7336; X86-BMI1-NEXT: # %bb.7: 7337; X86-BMI1-NEXT: movl %esi, %eax 7338; X86-BMI1-NEXT: .LBB58_8: 7339; X86-BMI1-NEXT: popl %esi 7340; X86-BMI1-NEXT: popl %edi 7341; X86-BMI1-NEXT: popl %ebx 7342; X86-BMI1-NEXT: retl 7343; 7344; X86-BMI2-LABEL: bextr64_d2_load: 7345; X86-BMI2: # %bb.0: 7346; X86-BMI2-NEXT: pushl %edi 7347; X86-BMI2-NEXT: pushl %esi 7348; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7349; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 7350; X86-BMI2-NEXT: movl (%edx), %eax 7351; X86-BMI2-NEXT: movl 4(%edx), %edx 7352; X86-BMI2-NEXT: shrxl %ecx, %edx, %esi 7353; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 7354; X86-BMI2-NEXT: xorl %edx, %edx 7355; X86-BMI2-NEXT: testb $32, %cl 7356; X86-BMI2-NEXT: je .LBB58_2 7357; X86-BMI2-NEXT: # %bb.1: 7358; X86-BMI2-NEXT: movl %esi, %eax 7359; X86-BMI2-NEXT: xorl %esi, %esi 7360; X86-BMI2-NEXT: .LBB58_2: 7361; X86-BMI2-NEXT: movb $64, %cl 7362; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 7363; X86-BMI2-NEXT: shldl %cl, %eax, %esi 7364; X86-BMI2-NEXT: shlxl %ecx, %eax, %edi 7365; X86-BMI2-NEXT: testb $32, %cl 7366; X86-BMI2-NEXT: je .LBB58_4 7367; X86-BMI2-NEXT: # %bb.3: 7368; X86-BMI2-NEXT: movl %edi, %esi 7369; X86-BMI2-NEXT: movl $0, %edi 7370; X86-BMI2-NEXT: .LBB58_4: 7371; X86-BMI2-NEXT: shrxl %ecx, %esi, %eax 7372; X86-BMI2-NEXT: jne .LBB58_6 7373; X86-BMI2-NEXT: # %bb.5: 7374; X86-BMI2-NEXT: movl %eax, %edx 7375; X86-BMI2-NEXT: .LBB58_6: 7376; X86-BMI2-NEXT: shrdl %cl, %esi, %edi 7377; X86-BMI2-NEXT: testb $32, %cl 7378; X86-BMI2-NEXT: jne .LBB58_8 7379; X86-BMI2-NEXT: # %bb.7: 7380; X86-BMI2-NEXT: movl %edi, %eax 7381; X86-BMI2-NEXT: .LBB58_8: 7382; X86-BMI2-NEXT: popl %esi 7383; X86-BMI2-NEXT: popl %edi 7384; X86-BMI2-NEXT: retl 7385; 7386; X64-NOBMI-LABEL: bextr64_d2_load: 7387; X64-NOBMI: # %bb.0: 7388; X64-NOBMI-NEXT: movq %rsi, %rcx 7389; X64-NOBMI-NEXT: movq (%rdi), %rax 7390; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 7391; X64-NOBMI-NEXT: shrq %cl, %rax 7392; X64-NOBMI-NEXT: negb %dl 7393; X64-NOBMI-NEXT: movl %edx, %ecx 7394; X64-NOBMI-NEXT: shlq %cl, %rax 7395; X64-NOBMI-NEXT: shrq %cl, %rax 7396; X64-NOBMI-NEXT: retq 7397; 7398; X64-BMI1-LABEL: bextr64_d2_load: 7399; X64-BMI1: # %bb.0: 7400; X64-BMI1-NEXT: shll $8, %edx 7401; X64-BMI1-NEXT: movzbl %sil, %eax 7402; X64-BMI1-NEXT: orl %edx, %eax 7403; X64-BMI1-NEXT: bextrq %rax, (%rdi), %rax 7404; X64-BMI1-NEXT: retq 7405; 7406; X64-BMI2-LABEL: bextr64_d2_load: 7407; X64-BMI2: # %bb.0: 7408; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 7409; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 7410; X64-BMI2-NEXT: retq 7411 %val = load i64, ptr %w 7412 %shifted = lshr i64 %val, %numskipbits 7413 %numhighbits = sub i64 64, %numlowbits 7414 %highbitscleared = shl i64 %shifted, %numhighbits 7415 %masked = lshr i64 %highbitscleared, %numhighbits 7416 ret i64 %masked 7417} 7418 7419define i64 @bextr64_d3_load_indexzext(ptr %w, i8 %numskipbits, i8 %numlowbits) nounwind { 7420; X86-NOBMI-LABEL: bextr64_d3_load_indexzext: 7421; X86-NOBMI: # %bb.0: 7422; X86-NOBMI-NEXT: pushl %ebx 7423; X86-NOBMI-NEXT: pushl %edi 7424; X86-NOBMI-NEXT: pushl %esi 7425; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7426; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 7427; X86-NOBMI-NEXT: movl (%eax), %edi 7428; X86-NOBMI-NEXT: movl 4(%eax), %edx 7429; X86-NOBMI-NEXT: movl %edx, %eax 7430; X86-NOBMI-NEXT: shrl %cl, %eax 7431; X86-NOBMI-NEXT: shrdl %cl, %edx, %edi 7432; X86-NOBMI-NEXT: xorl %esi, %esi 7433; X86-NOBMI-NEXT: testb $32, %cl 7434; X86-NOBMI-NEXT: je .LBB59_2 7435; X86-NOBMI-NEXT: # %bb.1: 7436; X86-NOBMI-NEXT: movl %eax, %edi 7437; X86-NOBMI-NEXT: xorl %eax, %eax 7438; X86-NOBMI-NEXT: .LBB59_2: 7439; X86-NOBMI-NEXT: movb $64, %cl 7440; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 7441; X86-NOBMI-NEXT: shldl %cl, %edi, %eax 7442; X86-NOBMI-NEXT: shll %cl, %edi 7443; X86-NOBMI-NEXT: testb $32, %cl 7444; X86-NOBMI-NEXT: movl %edi, %ebx 7445; X86-NOBMI-NEXT: jne .LBB59_4 7446; X86-NOBMI-NEXT: # %bb.3: 7447; X86-NOBMI-NEXT: movl %eax, %ebx 7448; X86-NOBMI-NEXT: .LBB59_4: 7449; X86-NOBMI-NEXT: movl %ebx, %eax 7450; X86-NOBMI-NEXT: shrl %cl, %eax 7451; X86-NOBMI-NEXT: testb $32, %cl 7452; X86-NOBMI-NEXT: movl $0, %edx 7453; X86-NOBMI-NEXT: jne .LBB59_6 7454; X86-NOBMI-NEXT: # %bb.5: 7455; X86-NOBMI-NEXT: movl %edi, %esi 7456; X86-NOBMI-NEXT: movl %eax, %edx 7457; X86-NOBMI-NEXT: .LBB59_6: 7458; X86-NOBMI-NEXT: shrdl %cl, %ebx, %esi 7459; X86-NOBMI-NEXT: testb $32, %cl 7460; X86-NOBMI-NEXT: jne .LBB59_8 7461; X86-NOBMI-NEXT: # %bb.7: 7462; X86-NOBMI-NEXT: movl %esi, %eax 7463; X86-NOBMI-NEXT: .LBB59_8: 7464; X86-NOBMI-NEXT: popl %esi 7465; X86-NOBMI-NEXT: popl %edi 7466; X86-NOBMI-NEXT: popl %ebx 7467; X86-NOBMI-NEXT: retl 7468; 7469; X86-BMI1-LABEL: bextr64_d3_load_indexzext: 7470; X86-BMI1: # %bb.0: 7471; X86-BMI1-NEXT: pushl %ebx 7472; X86-BMI1-NEXT: pushl %edi 7473; X86-BMI1-NEXT: pushl %esi 7474; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7475; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 7476; X86-BMI1-NEXT: movl (%eax), %edi 7477; X86-BMI1-NEXT: movl 4(%eax), %edx 7478; X86-BMI1-NEXT: movl %edx, %eax 7479; X86-BMI1-NEXT: shrl %cl, %eax 7480; X86-BMI1-NEXT: shrdl %cl, %edx, %edi 7481; X86-BMI1-NEXT: xorl %esi, %esi 7482; X86-BMI1-NEXT: testb $32, %cl 7483; X86-BMI1-NEXT: je .LBB59_2 7484; X86-BMI1-NEXT: # %bb.1: 7485; X86-BMI1-NEXT: movl %eax, %edi 7486; X86-BMI1-NEXT: xorl %eax, %eax 7487; X86-BMI1-NEXT: .LBB59_2: 7488; X86-BMI1-NEXT: movb $64, %cl 7489; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 7490; X86-BMI1-NEXT: shldl %cl, %edi, %eax 7491; X86-BMI1-NEXT: shll %cl, %edi 7492; X86-BMI1-NEXT: testb $32, %cl 7493; X86-BMI1-NEXT: movl %edi, %ebx 7494; X86-BMI1-NEXT: jne .LBB59_4 7495; X86-BMI1-NEXT: # %bb.3: 7496; X86-BMI1-NEXT: movl %eax, %ebx 7497; X86-BMI1-NEXT: .LBB59_4: 7498; X86-BMI1-NEXT: movl %ebx, %eax 7499; X86-BMI1-NEXT: shrl %cl, %eax 7500; X86-BMI1-NEXT: testb $32, %cl 7501; X86-BMI1-NEXT: movl $0, %edx 7502; X86-BMI1-NEXT: jne .LBB59_6 7503; X86-BMI1-NEXT: # %bb.5: 7504; X86-BMI1-NEXT: movl %edi, %esi 7505; X86-BMI1-NEXT: movl %eax, %edx 7506; X86-BMI1-NEXT: .LBB59_6: 7507; X86-BMI1-NEXT: shrdl %cl, %ebx, %esi 7508; X86-BMI1-NEXT: testb $32, %cl 7509; X86-BMI1-NEXT: jne .LBB59_8 7510; X86-BMI1-NEXT: # %bb.7: 7511; X86-BMI1-NEXT: movl %esi, %eax 7512; X86-BMI1-NEXT: .LBB59_8: 7513; X86-BMI1-NEXT: popl %esi 7514; X86-BMI1-NEXT: popl %edi 7515; X86-BMI1-NEXT: popl %ebx 7516; X86-BMI1-NEXT: retl 7517; 7518; X86-BMI2-LABEL: bextr64_d3_load_indexzext: 7519; X86-BMI2: # %bb.0: 7520; X86-BMI2-NEXT: pushl %edi 7521; X86-BMI2-NEXT: pushl %esi 7522; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7523; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 7524; X86-BMI2-NEXT: movl (%edx), %eax 7525; X86-BMI2-NEXT: movl 4(%edx), %edx 7526; X86-BMI2-NEXT: shrxl %ecx, %edx, %esi 7527; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 7528; X86-BMI2-NEXT: xorl %edx, %edx 7529; X86-BMI2-NEXT: testb $32, %cl 7530; X86-BMI2-NEXT: je .LBB59_2 7531; X86-BMI2-NEXT: # %bb.1: 7532; X86-BMI2-NEXT: movl %esi, %eax 7533; X86-BMI2-NEXT: xorl %esi, %esi 7534; X86-BMI2-NEXT: .LBB59_2: 7535; X86-BMI2-NEXT: movb $64, %cl 7536; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 7537; X86-BMI2-NEXT: shldl %cl, %eax, %esi 7538; X86-BMI2-NEXT: shlxl %ecx, %eax, %edi 7539; X86-BMI2-NEXT: testb $32, %cl 7540; X86-BMI2-NEXT: je .LBB59_4 7541; X86-BMI2-NEXT: # %bb.3: 7542; X86-BMI2-NEXT: movl %edi, %esi 7543; X86-BMI2-NEXT: movl $0, %edi 7544; X86-BMI2-NEXT: .LBB59_4: 7545; X86-BMI2-NEXT: shrxl %ecx, %esi, %eax 7546; X86-BMI2-NEXT: jne .LBB59_6 7547; X86-BMI2-NEXT: # %bb.5: 7548; X86-BMI2-NEXT: movl %eax, %edx 7549; X86-BMI2-NEXT: .LBB59_6: 7550; X86-BMI2-NEXT: shrdl %cl, %esi, %edi 7551; X86-BMI2-NEXT: testb $32, %cl 7552; X86-BMI2-NEXT: jne .LBB59_8 7553; X86-BMI2-NEXT: # %bb.7: 7554; X86-BMI2-NEXT: movl %edi, %eax 7555; X86-BMI2-NEXT: .LBB59_8: 7556; X86-BMI2-NEXT: popl %esi 7557; X86-BMI2-NEXT: popl %edi 7558; X86-BMI2-NEXT: retl 7559; 7560; X64-NOBMI-LABEL: bextr64_d3_load_indexzext: 7561; X64-NOBMI: # %bb.0: 7562; X64-NOBMI-NEXT: movl %esi, %ecx 7563; X64-NOBMI-NEXT: movq (%rdi), %rax 7564; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 7565; X64-NOBMI-NEXT: shrq %cl, %rax 7566; X64-NOBMI-NEXT: negb %dl 7567; X64-NOBMI-NEXT: movl %edx, %ecx 7568; X64-NOBMI-NEXT: shlq %cl, %rax 7569; X64-NOBMI-NEXT: shrq %cl, %rax 7570; X64-NOBMI-NEXT: retq 7571; 7572; X64-BMI1-LABEL: bextr64_d3_load_indexzext: 7573; X64-BMI1: # %bb.0: 7574; X64-BMI1-NEXT: shll $8, %edx 7575; X64-BMI1-NEXT: movzbl %sil, %eax 7576; X64-BMI1-NEXT: orl %edx, %eax 7577; X64-BMI1-NEXT: bextrq %rax, (%rdi), %rax 7578; X64-BMI1-NEXT: retq 7579; 7580; X64-BMI2-LABEL: bextr64_d3_load_indexzext: 7581; X64-BMI2: # %bb.0: 7582; X64-BMI2-NEXT: # kill: def $edx killed $edx def $rdx 7583; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 7584; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 7585; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 7586; X64-BMI2-NEXT: retq 7587 %val = load i64, ptr %w 7588 %skip = zext i8 %numskipbits to i64 7589 %shifted = lshr i64 %val, %skip 7590 %numhighbits = sub i8 64, %numlowbits 7591 %sh_prom = zext i8 %numhighbits to i64 7592 %highbitscleared = shl i64 %shifted, %sh_prom 7593 %masked = lshr i64 %highbitscleared, %sh_prom 7594 ret i64 %masked 7595} 7596 7597define i64 @bextr64_d5_skipextrauses(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 7598; X86-NOBMI-LABEL: bextr64_d5_skipextrauses: 7599; X86-NOBMI: # %bb.0: 7600; X86-NOBMI-NEXT: pushl %ebp 7601; X86-NOBMI-NEXT: pushl %ebx 7602; X86-NOBMI-NEXT: pushl %edi 7603; X86-NOBMI-NEXT: pushl %esi 7604; X86-NOBMI-NEXT: subl $12, %esp 7605; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ebx 7606; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 7607; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 7608; X86-NOBMI-NEXT: movl %edx, %esi 7609; X86-NOBMI-NEXT: movl %eax, %ecx 7610; X86-NOBMI-NEXT: shrl %cl, %esi 7611; X86-NOBMI-NEXT: shrdl %cl, %edx, %ebx 7612; X86-NOBMI-NEXT: xorl %edx, %edx 7613; X86-NOBMI-NEXT: testb $32, %al 7614; X86-NOBMI-NEXT: je .LBB60_2 7615; X86-NOBMI-NEXT: # %bb.1: 7616; X86-NOBMI-NEXT: movl %esi, %ebx 7617; X86-NOBMI-NEXT: xorl %esi, %esi 7618; X86-NOBMI-NEXT: .LBB60_2: 7619; X86-NOBMI-NEXT: movb $64, %cl 7620; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 7621; X86-NOBMI-NEXT: shldl %cl, %ebx, %esi 7622; X86-NOBMI-NEXT: shll %cl, %ebx 7623; X86-NOBMI-NEXT: testb $32, %cl 7624; X86-NOBMI-NEXT: movl %ebx, %ebp 7625; X86-NOBMI-NEXT: jne .LBB60_4 7626; X86-NOBMI-NEXT: # %bb.3: 7627; X86-NOBMI-NEXT: movl %esi, %ebp 7628; X86-NOBMI-NEXT: .LBB60_4: 7629; X86-NOBMI-NEXT: movl %ebp, %esi 7630; X86-NOBMI-NEXT: shrl %cl, %esi 7631; X86-NOBMI-NEXT: testb $32, %cl 7632; X86-NOBMI-NEXT: movl $0, %edi 7633; X86-NOBMI-NEXT: jne .LBB60_6 7634; X86-NOBMI-NEXT: # %bb.5: 7635; X86-NOBMI-NEXT: movl %ebx, %edx 7636; X86-NOBMI-NEXT: movl %esi, %edi 7637; X86-NOBMI-NEXT: .LBB60_6: 7638; X86-NOBMI-NEXT: shrdl %cl, %ebp, %edx 7639; X86-NOBMI-NEXT: testb $32, %cl 7640; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx 7641; X86-NOBMI-NEXT: jne .LBB60_8 7642; X86-NOBMI-NEXT: # %bb.7: 7643; X86-NOBMI-NEXT: movl %edx, %esi 7644; X86-NOBMI-NEXT: .LBB60_8: 7645; X86-NOBMI-NEXT: subl $8, %esp 7646; X86-NOBMI-NEXT: pushl %ecx 7647; X86-NOBMI-NEXT: pushl %eax 7648; X86-NOBMI-NEXT: calll use64@PLT 7649; X86-NOBMI-NEXT: addl $16, %esp 7650; X86-NOBMI-NEXT: movl %esi, %eax 7651; X86-NOBMI-NEXT: movl %edi, %edx 7652; X86-NOBMI-NEXT: addl $12, %esp 7653; X86-NOBMI-NEXT: popl %esi 7654; X86-NOBMI-NEXT: popl %edi 7655; X86-NOBMI-NEXT: popl %ebx 7656; X86-NOBMI-NEXT: popl %ebp 7657; X86-NOBMI-NEXT: retl 7658; 7659; X86-BMI1-LABEL: bextr64_d5_skipextrauses: 7660; X86-BMI1: # %bb.0: 7661; X86-BMI1-NEXT: pushl %ebp 7662; X86-BMI1-NEXT: pushl %ebx 7663; X86-BMI1-NEXT: pushl %edi 7664; X86-BMI1-NEXT: pushl %esi 7665; X86-BMI1-NEXT: subl $12, %esp 7666; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %ebx 7667; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edx 7668; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %eax 7669; X86-BMI1-NEXT: movl %edx, %esi 7670; X86-BMI1-NEXT: movl %eax, %ecx 7671; X86-BMI1-NEXT: shrl %cl, %esi 7672; X86-BMI1-NEXT: shrdl %cl, %edx, %ebx 7673; X86-BMI1-NEXT: xorl %edx, %edx 7674; X86-BMI1-NEXT: testb $32, %al 7675; X86-BMI1-NEXT: je .LBB60_2 7676; X86-BMI1-NEXT: # %bb.1: 7677; X86-BMI1-NEXT: movl %esi, %ebx 7678; X86-BMI1-NEXT: xorl %esi, %esi 7679; X86-BMI1-NEXT: .LBB60_2: 7680; X86-BMI1-NEXT: movb $64, %cl 7681; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 7682; X86-BMI1-NEXT: shldl %cl, %ebx, %esi 7683; X86-BMI1-NEXT: shll %cl, %ebx 7684; X86-BMI1-NEXT: testb $32, %cl 7685; X86-BMI1-NEXT: movl %ebx, %ebp 7686; X86-BMI1-NEXT: jne .LBB60_4 7687; X86-BMI1-NEXT: # %bb.3: 7688; X86-BMI1-NEXT: movl %esi, %ebp 7689; X86-BMI1-NEXT: .LBB60_4: 7690; X86-BMI1-NEXT: movl %ebp, %esi 7691; X86-BMI1-NEXT: shrl %cl, %esi 7692; X86-BMI1-NEXT: testb $32, %cl 7693; X86-BMI1-NEXT: movl $0, %edi 7694; X86-BMI1-NEXT: jne .LBB60_6 7695; X86-BMI1-NEXT: # %bb.5: 7696; X86-BMI1-NEXT: movl %ebx, %edx 7697; X86-BMI1-NEXT: movl %esi, %edi 7698; X86-BMI1-NEXT: .LBB60_6: 7699; X86-BMI1-NEXT: shrdl %cl, %ebp, %edx 7700; X86-BMI1-NEXT: testb $32, %cl 7701; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %ecx 7702; X86-BMI1-NEXT: jne .LBB60_8 7703; X86-BMI1-NEXT: # %bb.7: 7704; X86-BMI1-NEXT: movl %edx, %esi 7705; X86-BMI1-NEXT: .LBB60_8: 7706; X86-BMI1-NEXT: subl $8, %esp 7707; X86-BMI1-NEXT: pushl %ecx 7708; X86-BMI1-NEXT: pushl %eax 7709; X86-BMI1-NEXT: calll use64@PLT 7710; X86-BMI1-NEXT: addl $16, %esp 7711; X86-BMI1-NEXT: movl %esi, %eax 7712; X86-BMI1-NEXT: movl %edi, %edx 7713; X86-BMI1-NEXT: addl $12, %esp 7714; X86-BMI1-NEXT: popl %esi 7715; X86-BMI1-NEXT: popl %edi 7716; X86-BMI1-NEXT: popl %ebx 7717; X86-BMI1-NEXT: popl %ebp 7718; X86-BMI1-NEXT: retl 7719; 7720; X86-BMI2-LABEL: bextr64_d5_skipextrauses: 7721; X86-BMI2: # %bb.0: 7722; X86-BMI2-NEXT: pushl %ebx 7723; X86-BMI2-NEXT: pushl %edi 7724; X86-BMI2-NEXT: pushl %esi 7725; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edi 7726; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 7727; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 7728; X86-BMI2-NEXT: movl %eax, %ecx 7729; X86-BMI2-NEXT: shrdl %cl, %edx, %edi 7730; X86-BMI2-NEXT: shrxl %eax, %edx, %edx 7731; X86-BMI2-NEXT: xorl %esi, %esi 7732; X86-BMI2-NEXT: testb $32, %al 7733; X86-BMI2-NEXT: je .LBB60_2 7734; X86-BMI2-NEXT: # %bb.1: 7735; X86-BMI2-NEXT: movl %edx, %edi 7736; X86-BMI2-NEXT: xorl %edx, %edx 7737; X86-BMI2-NEXT: .LBB60_2: 7738; X86-BMI2-NEXT: movb $64, %cl 7739; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 7740; X86-BMI2-NEXT: shldl %cl, %edi, %edx 7741; X86-BMI2-NEXT: shlxl %ecx, %edi, %ebx 7742; X86-BMI2-NEXT: testb $32, %cl 7743; X86-BMI2-NEXT: je .LBB60_4 7744; X86-BMI2-NEXT: # %bb.3: 7745; X86-BMI2-NEXT: movl %ebx, %edx 7746; X86-BMI2-NEXT: movl $0, %ebx 7747; X86-BMI2-NEXT: .LBB60_4: 7748; X86-BMI2-NEXT: shrxl %ecx, %edx, %edi 7749; X86-BMI2-NEXT: jne .LBB60_6 7750; X86-BMI2-NEXT: # %bb.5: 7751; X86-BMI2-NEXT: movl %edi, %esi 7752; X86-BMI2-NEXT: .LBB60_6: 7753; X86-BMI2-NEXT: shrdl %cl, %edx, %ebx 7754; X86-BMI2-NEXT: testb $32, %cl 7755; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 7756; X86-BMI2-NEXT: jne .LBB60_8 7757; X86-BMI2-NEXT: # %bb.7: 7758; X86-BMI2-NEXT: movl %ebx, %edi 7759; X86-BMI2-NEXT: .LBB60_8: 7760; X86-BMI2-NEXT: subl $8, %esp 7761; X86-BMI2-NEXT: pushl %ecx 7762; X86-BMI2-NEXT: pushl %eax 7763; X86-BMI2-NEXT: calll use64@PLT 7764; X86-BMI2-NEXT: addl $16, %esp 7765; X86-BMI2-NEXT: movl %edi, %eax 7766; X86-BMI2-NEXT: movl %esi, %edx 7767; X86-BMI2-NEXT: popl %esi 7768; X86-BMI2-NEXT: popl %edi 7769; X86-BMI2-NEXT: popl %ebx 7770; X86-BMI2-NEXT: retl 7771; 7772; X64-NOBMI-LABEL: bextr64_d5_skipextrauses: 7773; X64-NOBMI: # %bb.0: 7774; X64-NOBMI-NEXT: pushq %rbx 7775; X64-NOBMI-NEXT: movq %rdi, %rbx 7776; X64-NOBMI-NEXT: movl %esi, %ecx 7777; X64-NOBMI-NEXT: shrq %cl, %rbx 7778; X64-NOBMI-NEXT: negb %dl 7779; X64-NOBMI-NEXT: movl %edx, %ecx 7780; X64-NOBMI-NEXT: shlq %cl, %rbx 7781; X64-NOBMI-NEXT: shrq %cl, %rbx 7782; X64-NOBMI-NEXT: movq %rsi, %rdi 7783; X64-NOBMI-NEXT: callq use64@PLT 7784; X64-NOBMI-NEXT: movq %rbx, %rax 7785; X64-NOBMI-NEXT: popq %rbx 7786; X64-NOBMI-NEXT: retq 7787; 7788; X64-BMI1-LABEL: bextr64_d5_skipextrauses: 7789; X64-BMI1: # %bb.0: 7790; X64-BMI1-NEXT: pushq %rbx 7791; X64-BMI1-NEXT: shll $8, %edx 7792; X64-BMI1-NEXT: movzbl %sil, %eax 7793; X64-BMI1-NEXT: orl %edx, %eax 7794; X64-BMI1-NEXT: bextrq %rax, %rdi, %rbx 7795; X64-BMI1-NEXT: movq %rsi, %rdi 7796; X64-BMI1-NEXT: callq use64@PLT 7797; X64-BMI1-NEXT: movq %rbx, %rax 7798; X64-BMI1-NEXT: popq %rbx 7799; X64-BMI1-NEXT: retq 7800; 7801; X64-BMI2-LABEL: bextr64_d5_skipextrauses: 7802; X64-BMI2: # %bb.0: 7803; X64-BMI2-NEXT: pushq %rbx 7804; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 7805; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rbx 7806; X64-BMI2-NEXT: movq %rsi, %rdi 7807; X64-BMI2-NEXT: callq use64@PLT 7808; X64-BMI2-NEXT: movq %rbx, %rax 7809; X64-BMI2-NEXT: popq %rbx 7810; X64-BMI2-NEXT: retq 7811 %shifted = lshr i64 %val, %numskipbits 7812 %numhighbits = sub i64 64, %numlowbits 7813 %highbitscleared = shl i64 %shifted, %numhighbits 7814 %masked = lshr i64 %highbitscleared, %numhighbits 7815 call void @use64(i64 %numskipbits) 7816 ret i64 %masked 7817} 7818 7819; 64-bit, but with 32-bit output 7820 7821; Everything done in 64-bit, truncation happens last. 7822define i32 @bextr64_32_d0(i64 %val, i64 %numskipbits, i64 %numlowbits) nounwind { 7823; X86-NOBMI-LABEL: bextr64_32_d0: 7824; X86-NOBMI: # %bb.0: 7825; X86-NOBMI-NEXT: pushl %esi 7826; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7827; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 7828; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 7829; X86-NOBMI-NEXT: movl %esi, %eax 7830; X86-NOBMI-NEXT: shrl %cl, %eax 7831; X86-NOBMI-NEXT: shrdl %cl, %esi, %edx 7832; X86-NOBMI-NEXT: testb $32, %cl 7833; X86-NOBMI-NEXT: je .LBB61_2 7834; X86-NOBMI-NEXT: # %bb.1: 7835; X86-NOBMI-NEXT: movl %eax, %edx 7836; X86-NOBMI-NEXT: xorl %eax, %eax 7837; X86-NOBMI-NEXT: .LBB61_2: 7838; X86-NOBMI-NEXT: movb $64, %cl 7839; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 7840; X86-NOBMI-NEXT: shldl %cl, %edx, %eax 7841; X86-NOBMI-NEXT: shll %cl, %edx 7842; X86-NOBMI-NEXT: testb $32, %cl 7843; X86-NOBMI-NEXT: je .LBB61_4 7844; X86-NOBMI-NEXT: # %bb.3: 7845; X86-NOBMI-NEXT: movl %edx, %eax 7846; X86-NOBMI-NEXT: xorl %edx, %edx 7847; X86-NOBMI-NEXT: .LBB61_4: 7848; X86-NOBMI-NEXT: shrdl %cl, %eax, %edx 7849; X86-NOBMI-NEXT: shrl %cl, %eax 7850; X86-NOBMI-NEXT: testb $32, %cl 7851; X86-NOBMI-NEXT: jne .LBB61_6 7852; X86-NOBMI-NEXT: # %bb.5: 7853; X86-NOBMI-NEXT: movl %edx, %eax 7854; X86-NOBMI-NEXT: .LBB61_6: 7855; X86-NOBMI-NEXT: popl %esi 7856; X86-NOBMI-NEXT: retl 7857; 7858; X86-BMI1-LABEL: bextr64_32_d0: 7859; X86-BMI1: # %bb.0: 7860; X86-BMI1-NEXT: pushl %esi 7861; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7862; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edx 7863; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 7864; X86-BMI1-NEXT: movl %esi, %eax 7865; X86-BMI1-NEXT: shrl %cl, %eax 7866; X86-BMI1-NEXT: shrdl %cl, %esi, %edx 7867; X86-BMI1-NEXT: testb $32, %cl 7868; X86-BMI1-NEXT: je .LBB61_2 7869; X86-BMI1-NEXT: # %bb.1: 7870; X86-BMI1-NEXT: movl %eax, %edx 7871; X86-BMI1-NEXT: xorl %eax, %eax 7872; X86-BMI1-NEXT: .LBB61_2: 7873; X86-BMI1-NEXT: movb $64, %cl 7874; X86-BMI1-NEXT: subb {{[0-9]+}}(%esp), %cl 7875; X86-BMI1-NEXT: shldl %cl, %edx, %eax 7876; X86-BMI1-NEXT: shll %cl, %edx 7877; X86-BMI1-NEXT: testb $32, %cl 7878; X86-BMI1-NEXT: je .LBB61_4 7879; X86-BMI1-NEXT: # %bb.3: 7880; X86-BMI1-NEXT: movl %edx, %eax 7881; X86-BMI1-NEXT: xorl %edx, %edx 7882; X86-BMI1-NEXT: .LBB61_4: 7883; X86-BMI1-NEXT: shrdl %cl, %eax, %edx 7884; X86-BMI1-NEXT: shrl %cl, %eax 7885; X86-BMI1-NEXT: testb $32, %cl 7886; X86-BMI1-NEXT: jne .LBB61_6 7887; X86-BMI1-NEXT: # %bb.5: 7888; X86-BMI1-NEXT: movl %edx, %eax 7889; X86-BMI1-NEXT: .LBB61_6: 7890; X86-BMI1-NEXT: popl %esi 7891; X86-BMI1-NEXT: retl 7892; 7893; X86-BMI2-LABEL: bextr64_32_d0: 7894; X86-BMI2: # %bb.0: 7895; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7896; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 7897; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 7898; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 7899; X86-BMI2-NEXT: shrxl %ecx, %edx, %edx 7900; X86-BMI2-NEXT: testb $32, %cl 7901; X86-BMI2-NEXT: je .LBB61_2 7902; X86-BMI2-NEXT: # %bb.1: 7903; X86-BMI2-NEXT: movl %edx, %eax 7904; X86-BMI2-NEXT: xorl %edx, %edx 7905; X86-BMI2-NEXT: .LBB61_2: 7906; X86-BMI2-NEXT: movb $64, %cl 7907; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 7908; X86-BMI2-NEXT: shldl %cl, %eax, %edx 7909; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 7910; X86-BMI2-NEXT: testb $32, %cl 7911; X86-BMI2-NEXT: je .LBB61_4 7912; X86-BMI2-NEXT: # %bb.3: 7913; X86-BMI2-NEXT: movl %eax, %edx 7914; X86-BMI2-NEXT: xorl %eax, %eax 7915; X86-BMI2-NEXT: .LBB61_4: 7916; X86-BMI2-NEXT: shrdl %cl, %edx, %eax 7917; X86-BMI2-NEXT: testb $32, %cl 7918; X86-BMI2-NEXT: je .LBB61_6 7919; X86-BMI2-NEXT: # %bb.5: 7920; X86-BMI2-NEXT: shrxl %ecx, %edx, %eax 7921; X86-BMI2-NEXT: .LBB61_6: 7922; X86-BMI2-NEXT: retl 7923; 7924; X64-NOBMI-LABEL: bextr64_32_d0: 7925; X64-NOBMI: # %bb.0: 7926; X64-NOBMI-NEXT: movq %rsi, %rcx 7927; X64-NOBMI-NEXT: movq %rdi, %rax 7928; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 7929; X64-NOBMI-NEXT: shrq %cl, %rax 7930; X64-NOBMI-NEXT: negb %dl 7931; X64-NOBMI-NEXT: movl %edx, %ecx 7932; X64-NOBMI-NEXT: shlq %cl, %rax 7933; X64-NOBMI-NEXT: shrq %cl, %rax 7934; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 7935; X64-NOBMI-NEXT: retq 7936; 7937; X64-BMI1-LABEL: bextr64_32_d0: 7938; X64-BMI1: # %bb.0: 7939; X64-BMI1-NEXT: shll $8, %edx 7940; X64-BMI1-NEXT: movzbl %sil, %eax 7941; X64-BMI1-NEXT: orl %edx, %eax 7942; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 7943; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 7944; X64-BMI1-NEXT: retq 7945; 7946; X64-BMI2-LABEL: bextr64_32_d0: 7947; X64-BMI2: # %bb.0: 7948; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 7949; X64-BMI2-NEXT: bzhiq %rdx, %rax, %rax 7950; X64-BMI2-NEXT: # kill: def $eax killed $eax killed $rax 7951; X64-BMI2-NEXT: retq 7952 %shifted = lshr i64 %val, %numskipbits 7953 %numhighbits = sub i64 64, %numlowbits 7954 %highbitscleared = shl i64 %shifted, %numhighbits 7955 %masked = lshr i64 %highbitscleared, %numhighbits 7956 %res = trunc i64 %masked to i32 7957 ret i32 %res 7958} 7959 7960; Shifting happens in 64-bit, then truncation. Masking is 32-bit. 7961define i32 @bextr64_32_d1(i64 %val, i64 %numskipbits, i32 %numlowbits) nounwind { 7962; X86-NOBMI-LABEL: bextr64_32_d1: 7963; X86-NOBMI: # %bb.0: 7964; X86-NOBMI-NEXT: pushl %esi 7965; X86-NOBMI-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7966; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx 7967; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %esi 7968; X86-NOBMI-NEXT: movl %esi, %eax 7969; X86-NOBMI-NEXT: shrl %cl, %eax 7970; X86-NOBMI-NEXT: shrdl %cl, %esi, %edx 7971; X86-NOBMI-NEXT: testb $32, %cl 7972; X86-NOBMI-NEXT: jne .LBB62_2 7973; X86-NOBMI-NEXT: # %bb.1: 7974; X86-NOBMI-NEXT: movl %edx, %eax 7975; X86-NOBMI-NEXT: .LBB62_2: 7976; X86-NOBMI-NEXT: xorl %ecx, %ecx 7977; X86-NOBMI-NEXT: subb {{[0-9]+}}(%esp), %cl 7978; X86-NOBMI-NEXT: shll %cl, %eax 7979; X86-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx 7980; X86-NOBMI-NEXT: shrl %cl, %eax 7981; X86-NOBMI-NEXT: popl %esi 7982; X86-NOBMI-NEXT: retl 7983; 7984; X86-BMI1-LABEL: bextr64_32_d1: 7985; X86-BMI1: # %bb.0: 7986; X86-BMI1-NEXT: pushl %edi 7987; X86-BMI1-NEXT: pushl %esi 7988; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %eax 7989; X86-BMI1-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 7990; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %esi 7991; X86-BMI1-NEXT: movl {{[0-9]+}}(%esp), %edi 7992; X86-BMI1-NEXT: movl %edi, %edx 7993; X86-BMI1-NEXT: shrl %cl, %edx 7994; X86-BMI1-NEXT: shrdl %cl, %edi, %esi 7995; X86-BMI1-NEXT: testb $32, %cl 7996; X86-BMI1-NEXT: jne .LBB62_2 7997; X86-BMI1-NEXT: # %bb.1: 7998; X86-BMI1-NEXT: movl %esi, %edx 7999; X86-BMI1-NEXT: .LBB62_2: 8000; X86-BMI1-NEXT: shll $8, %eax 8001; X86-BMI1-NEXT: bextrl %eax, %edx, %eax 8002; X86-BMI1-NEXT: popl %esi 8003; X86-BMI1-NEXT: popl %edi 8004; X86-BMI1-NEXT: retl 8005; 8006; X86-BMI2-LABEL: bextr64_32_d1: 8007; X86-BMI2: # %bb.0: 8008; X86-BMI2-NEXT: pushl %esi 8009; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %eax 8010; X86-BMI2-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 8011; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %edx 8012; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 8013; X86-BMI2-NEXT: shrdl %cl, %esi, %edx 8014; X86-BMI2-NEXT: testb $32, %cl 8015; X86-BMI2-NEXT: je .LBB62_2 8016; X86-BMI2-NEXT: # %bb.1: 8017; X86-BMI2-NEXT: shrxl %ecx, %esi, %edx 8018; X86-BMI2-NEXT: .LBB62_2: 8019; X86-BMI2-NEXT: bzhil %eax, %edx, %eax 8020; X86-BMI2-NEXT: popl %esi 8021; X86-BMI2-NEXT: retl 8022; 8023; X64-NOBMI-LABEL: bextr64_32_d1: 8024; X64-NOBMI: # %bb.0: 8025; X64-NOBMI-NEXT: movq %rsi, %rcx 8026; X64-NOBMI-NEXT: movq %rdi, %rax 8027; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $rcx 8028; X64-NOBMI-NEXT: shrq %cl, %rax 8029; X64-NOBMI-NEXT: negb %dl 8030; X64-NOBMI-NEXT: movl %edx, %ecx 8031; X64-NOBMI-NEXT: shll %cl, %eax 8032; X64-NOBMI-NEXT: shrl %cl, %eax 8033; X64-NOBMI-NEXT: # kill: def $eax killed $eax killed $rax 8034; X64-NOBMI-NEXT: retq 8035; 8036; X64-BMI1-LABEL: bextr64_32_d1: 8037; X64-BMI1: # %bb.0: 8038; X64-BMI1-NEXT: shll $8, %edx 8039; X64-BMI1-NEXT: movzbl %sil, %eax 8040; X64-BMI1-NEXT: orl %edx, %eax 8041; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax 8042; X64-BMI1-NEXT: # kill: def $eax killed $eax killed $rax 8043; X64-BMI1-NEXT: retq 8044; 8045; X64-BMI2-LABEL: bextr64_32_d1: 8046; X64-BMI2: # %bb.0: 8047; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 8048; X64-BMI2-NEXT: bzhil %edx, %eax, %eax 8049; X64-BMI2-NEXT: retq 8050 %shifted = lshr i64 %val, %numskipbits 8051 %truncshifted = trunc i64 %shifted to i32 8052 %numhighbits = sub i32 32, %numlowbits 8053 %highbitscleared = shl i32 %truncshifted, %numhighbits 8054 %masked = lshr i32 %highbitscleared, %numhighbits 8055 ret i32 %masked 8056} 8057 8058; ---------------------------------------------------------------------------- ; 8059; Constant 8060; ---------------------------------------------------------------------------- ; 8061 8062; https://bugs.llvm.org/show_bug.cgi?id=38938 8063define void @pr38938(ptr %a0, ptr %a1) nounwind { 8064; X86-NOBMI-LABEL: pr38938: 8065; X86-NOBMI: # %bb.0: 8066; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 8067; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx 8068; X86-NOBMI-NEXT: movl (%ecx), %ecx 8069; X86-NOBMI-NEXT: shrl $19, %ecx 8070; X86-NOBMI-NEXT: andl $4092, %ecx # imm = 0xFFC 8071; X86-NOBMI-NEXT: incl (%eax,%ecx) 8072; X86-NOBMI-NEXT: retl 8073; 8074; X86-BMINOTBM-LABEL: pr38938: 8075; X86-BMINOTBM: # %bb.0: 8076; X86-BMINOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8077; X86-BMINOTBM-NEXT: movl {{[0-9]+}}(%esp), %ecx 8078; X86-BMINOTBM-NEXT: movl $2581, %edx # imm = 0xA15 8079; X86-BMINOTBM-NEXT: bextrl %edx, (%ecx), %ecx 8080; X86-BMINOTBM-NEXT: incl (%eax,%ecx,4) 8081; X86-BMINOTBM-NEXT: retl 8082; 8083; X86-BMITBM-LABEL: pr38938: 8084; X86-BMITBM: # %bb.0: 8085; X86-BMITBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8086; X86-BMITBM-NEXT: movl {{[0-9]+}}(%esp), %ecx 8087; X86-BMITBM-NEXT: bextrl $2581, (%ecx), %ecx # imm = 0xA15 8088; X86-BMITBM-NEXT: incl (%eax,%ecx,4) 8089; X86-BMITBM-NEXT: retl 8090; 8091; X64-NOBMI-LABEL: pr38938: 8092; X64-NOBMI: # %bb.0: 8093; X64-NOBMI-NEXT: movl (%rsi), %eax 8094; X64-NOBMI-NEXT: shrl $19, %eax 8095; X64-NOBMI-NEXT: andl $4092, %eax # imm = 0xFFC 8096; X64-NOBMI-NEXT: incl (%rdi,%rax) 8097; X64-NOBMI-NEXT: retq 8098; 8099; X64-BMINOTBM-LABEL: pr38938: 8100; X64-BMINOTBM: # %bb.0: 8101; X64-BMINOTBM-NEXT: movl $2581, %eax # imm = 0xA15 8102; X64-BMINOTBM-NEXT: bextrl %eax, (%rsi), %eax 8103; X64-BMINOTBM-NEXT: incl (%rdi,%rax,4) 8104; X64-BMINOTBM-NEXT: retq 8105; 8106; X64-BMITBM-LABEL: pr38938: 8107; X64-BMITBM: # %bb.0: 8108; X64-BMITBM-NEXT: bextrl $2581, (%rsi), %eax # imm = 0xA15 8109; X64-BMITBM-NEXT: incl (%rdi,%rax,4) 8110; X64-BMITBM-NEXT: retq 8111 %tmp = load i64, ptr %a1, align 8 8112 %tmp1 = lshr i64 %tmp, 21 8113 %tmp2 = and i64 %tmp1, 1023 8114 %tmp3 = getelementptr inbounds i32, ptr %a0, i64 %tmp2 8115 %tmp4 = load i32, ptr %tmp3, align 4 8116 %tmp5 = add nsw i32 %tmp4, 1 8117 store i32 %tmp5, ptr %tmp3, align 4 8118 ret void 8119} 8120 8121; The most canonical variant 8122define i32 @c0_i32(i32 %arg) nounwind { 8123; X86-NOBMI-LABEL: c0_i32: 8124; X86-NOBMI: # %bb.0: 8125; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 8126; X86-NOBMI-NEXT: shrl $19, %eax 8127; X86-NOBMI-NEXT: andl $1023, %eax # imm = 0x3FF 8128; X86-NOBMI-NEXT: retl 8129; 8130; X86-BMINOTBM-LABEL: c0_i32: 8131; X86-BMINOTBM: # %bb.0: 8132; X86-BMINOTBM-NEXT: movl $2579, %eax # imm = 0xA13 8133; X86-BMINOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 8134; X86-BMINOTBM-NEXT: retl 8135; 8136; X86-BMITBM-LABEL: c0_i32: 8137; X86-BMITBM: # %bb.0: 8138; X86-BMITBM-NEXT: bextrl $2579, {{[0-9]+}}(%esp), %eax # imm = 0xA13 8139; X86-BMITBM-NEXT: retl 8140; 8141; X64-NOBMI-LABEL: c0_i32: 8142; X64-NOBMI: # %bb.0: 8143; X64-NOBMI-NEXT: movl %edi, %eax 8144; X64-NOBMI-NEXT: shrl $19, %eax 8145; X64-NOBMI-NEXT: andl $1023, %eax # imm = 0x3FF 8146; X64-NOBMI-NEXT: retq 8147; 8148; X64-BMINOTBM-LABEL: c0_i32: 8149; X64-BMINOTBM: # %bb.0: 8150; X64-BMINOTBM-NEXT: movl $2579, %eax # imm = 0xA13 8151; X64-BMINOTBM-NEXT: bextrl %eax, %edi, %eax 8152; X64-BMINOTBM-NEXT: retq 8153; 8154; X64-BMITBM-LABEL: c0_i32: 8155; X64-BMITBM: # %bb.0: 8156; X64-BMITBM-NEXT: bextrl $2579, %edi, %eax # imm = 0xA13 8157; X64-BMITBM-NEXT: retq 8158 %tmp0 = lshr i32 %arg, 19 8159 %tmp1 = and i32 %tmp0, 1023 8160 ret i32 %tmp1 8161} 8162 8163; Should be still fine, but the mask is shifted 8164define i32 @c1_i32(i32 %arg) nounwind { 8165; X86-LABEL: c1_i32: 8166; X86: # %bb.0: 8167; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 8168; X86-NEXT: shrl $19, %eax 8169; X86-NEXT: andl $4092, %eax # imm = 0xFFC 8170; X86-NEXT: retl 8171; 8172; X64-LABEL: c1_i32: 8173; X64: # %bb.0: 8174; X64-NEXT: movl %edi, %eax 8175; X64-NEXT: shrl $19, %eax 8176; X64-NEXT: andl $4092, %eax # imm = 0xFFC 8177; X64-NEXT: retq 8178 %tmp0 = lshr i32 %arg, 19 8179 %tmp1 = and i32 %tmp0, 4092 8180 ret i32 %tmp1 8181} 8182 8183; Should be still fine, but the result is shifted left afterwards 8184define i32 @c2_i32(i32 %arg) nounwind { 8185; X86-LABEL: c2_i32: 8186; X86: # %bb.0: 8187; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 8188; X86-NEXT: shrl $17, %eax 8189; X86-NEXT: andl $4092, %eax # imm = 0xFFC 8190; X86-NEXT: retl 8191; 8192; X64-LABEL: c2_i32: 8193; X64: # %bb.0: 8194; X64-NEXT: movl %edi, %eax 8195; X64-NEXT: shrl $17, %eax 8196; X64-NEXT: andl $4092, %eax # imm = 0xFFC 8197; X64-NEXT: retq 8198 %tmp0 = lshr i32 %arg, 19 8199 %tmp1 = and i32 %tmp0, 1023 8200 %tmp2 = shl i32 %tmp1, 2 8201 ret i32 %tmp2 8202} 8203 8204; The mask covers newly shifted-in bit 8205define i32 @c4_i32_bad(i32 %arg) nounwind { 8206; X86-LABEL: c4_i32_bad: 8207; X86: # %bb.0: 8208; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 8209; X86-NEXT: shrl $19, %eax 8210; X86-NEXT: andl $-2, %eax 8211; X86-NEXT: retl 8212; 8213; X64-LABEL: c4_i32_bad: 8214; X64: # %bb.0: 8215; X64-NEXT: movl %edi, %eax 8216; X64-NEXT: shrl $19, %eax 8217; X64-NEXT: andl $-2, %eax 8218; X64-NEXT: retq 8219 %tmp0 = lshr i32 %arg, 19 8220 %tmp1 = and i32 %tmp0, 16382 8221 ret i32 %tmp1 8222} 8223 8224; i64 8225 8226; The most canonical variant 8227define i64 @c0_i64(i64 %arg) nounwind { 8228; X86-NOBMI-LABEL: c0_i64: 8229; X86-NOBMI: # %bb.0: 8230; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 8231; X86-NOBMI-NEXT: shrl $19, %eax 8232; X86-NOBMI-NEXT: andl $1023, %eax # imm = 0x3FF 8233; X86-NOBMI-NEXT: xorl %edx, %edx 8234; X86-NOBMI-NEXT: retl 8235; 8236; X86-BMINOTBM-LABEL: c0_i64: 8237; X86-BMINOTBM: # %bb.0: 8238; X86-BMINOTBM-NEXT: movl $2579, %eax # imm = 0xA13 8239; X86-BMINOTBM-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax 8240; X86-BMINOTBM-NEXT: xorl %edx, %edx 8241; X86-BMINOTBM-NEXT: retl 8242; 8243; X86-BMITBM-LABEL: c0_i64: 8244; X86-BMITBM: # %bb.0: 8245; X86-BMITBM-NEXT: bextrl $2579, {{[0-9]+}}(%esp), %eax # imm = 0xA13 8246; X86-BMITBM-NEXT: xorl %edx, %edx 8247; X86-BMITBM-NEXT: retl 8248; 8249; X64-NOBMI-LABEL: c0_i64: 8250; X64-NOBMI: # %bb.0: 8251; X64-NOBMI-NEXT: movq %rdi, %rax 8252; X64-NOBMI-NEXT: shrq $51, %rax 8253; X64-NOBMI-NEXT: andl $1023, %eax # imm = 0x3FF 8254; X64-NOBMI-NEXT: retq 8255; 8256; X64-BMINOTBM-LABEL: c0_i64: 8257; X64-BMINOTBM: # %bb.0: 8258; X64-BMINOTBM-NEXT: movl $2611, %eax # imm = 0xA33 8259; X64-BMINOTBM-NEXT: bextrq %rax, %rdi, %rax 8260; X64-BMINOTBM-NEXT: retq 8261; 8262; X64-BMITBM-LABEL: c0_i64: 8263; X64-BMITBM: # %bb.0: 8264; X64-BMITBM-NEXT: bextrq $2611, %rdi, %rax # imm = 0xA33 8265; X64-BMITBM-NEXT: retq 8266 %tmp0 = lshr i64 %arg, 51 8267 %tmp1 = and i64 %tmp0, 1023 8268 ret i64 %tmp1 8269} 8270 8271; Should be still fine, but the mask is shifted 8272define i64 @c1_i64(i64 %arg) nounwind { 8273; X86-LABEL: c1_i64: 8274; X86: # %bb.0: 8275; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 8276; X86-NEXT: shrl $19, %eax 8277; X86-NEXT: andl $4092, %eax # imm = 0xFFC 8278; X86-NEXT: xorl %edx, %edx 8279; X86-NEXT: retl 8280; 8281; X64-LABEL: c1_i64: 8282; X64: # %bb.0: 8283; X64-NEXT: movq %rdi, %rax 8284; X64-NEXT: shrq $51, %rax 8285; X64-NEXT: andl $4092, %eax # imm = 0xFFC 8286; X64-NEXT: retq 8287 %tmp0 = lshr i64 %arg, 51 8288 %tmp1 = and i64 %tmp0, 4092 8289 ret i64 %tmp1 8290} 8291 8292; Should be still fine, but the result is shifted left afterwards 8293define i64 @c2_i64(i64 %arg) nounwind { 8294; X86-LABEL: c2_i64: 8295; X86: # %bb.0: 8296; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 8297; X86-NEXT: shrl $17, %eax 8298; X86-NEXT: andl $4092, %eax # imm = 0xFFC 8299; X86-NEXT: xorl %edx, %edx 8300; X86-NEXT: retl 8301; 8302; X64-LABEL: c2_i64: 8303; X64: # %bb.0: 8304; X64-NEXT: movq %rdi, %rax 8305; X64-NEXT: shrq $49, %rax 8306; X64-NEXT: andl $4092, %eax # imm = 0xFFC 8307; X64-NEXT: retq 8308 %tmp0 = lshr i64 %arg, 51 8309 %tmp1 = and i64 %tmp0, 1023 8310 %tmp2 = shl i64 %tmp1, 2 8311 ret i64 %tmp2 8312} 8313 8314; The mask covers newly shifted-in bit 8315define i64 @c4_i64_bad(i64 %arg) nounwind { 8316; X86-LABEL: c4_i64_bad: 8317; X86: # %bb.0: 8318; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 8319; X86-NEXT: shrl $19, %eax 8320; X86-NEXT: andl $-2, %eax 8321; X86-NEXT: xorl %edx, %edx 8322; X86-NEXT: retl 8323; 8324; X64-LABEL: c4_i64_bad: 8325; X64: # %bb.0: 8326; X64-NEXT: movq %rdi, %rax 8327; X64-NEXT: shrq $51, %rax 8328; X64-NEXT: andl $-2, %eax 8329; X64-NEXT: retq 8330 %tmp0 = lshr i64 %arg, 51 8331 %tmp1 = and i64 %tmp0, 16382 8332 ret i64 %tmp1 8333} 8334 8335; ---------------------------------------------------------------------------- ; 8336; Constant, storing the result afterwards. 8337; ---------------------------------------------------------------------------- ; 8338 8339; i32 8340 8341; The most canonical variant 8342define void @c5_i32(i32 %arg, ptr %ptr) nounwind { 8343; X86-NOBMI-LABEL: c5_i32: 8344; X86-NOBMI: # %bb.0: 8345; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 8346; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx 8347; X86-NOBMI-NEXT: shrl $19, %ecx 8348; X86-NOBMI-NEXT: andl $1023, %ecx # imm = 0x3FF 8349; X86-NOBMI-NEXT: movl %ecx, (%eax) 8350; X86-NOBMI-NEXT: retl 8351; 8352; X86-BMINOTBM-LABEL: c5_i32: 8353; X86-BMINOTBM: # %bb.0: 8354; X86-BMINOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8355; X86-BMINOTBM-NEXT: movl $2579, %ecx # imm = 0xA13 8356; X86-BMINOTBM-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %ecx 8357; X86-BMINOTBM-NEXT: movl %ecx, (%eax) 8358; X86-BMINOTBM-NEXT: retl 8359; 8360; X86-BMITBM-LABEL: c5_i32: 8361; X86-BMITBM: # %bb.0: 8362; X86-BMITBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8363; X86-BMITBM-NEXT: bextrl $2579, {{[0-9]+}}(%esp), %ecx # imm = 0xA13 8364; X86-BMITBM-NEXT: movl %ecx, (%eax) 8365; X86-BMITBM-NEXT: retl 8366; 8367; X64-NOBMI-LABEL: c5_i32: 8368; X64-NOBMI: # %bb.0: 8369; X64-NOBMI-NEXT: shrl $19, %edi 8370; X64-NOBMI-NEXT: andl $1023, %edi # imm = 0x3FF 8371; X64-NOBMI-NEXT: movl %edi, (%rsi) 8372; X64-NOBMI-NEXT: retq 8373; 8374; X64-BMINOTBM-LABEL: c5_i32: 8375; X64-BMINOTBM: # %bb.0: 8376; X64-BMINOTBM-NEXT: movl $2579, %eax # imm = 0xA13 8377; X64-BMINOTBM-NEXT: bextrl %eax, %edi, %eax 8378; X64-BMINOTBM-NEXT: movl %eax, (%rsi) 8379; X64-BMINOTBM-NEXT: retq 8380; 8381; X64-BMITBM-LABEL: c5_i32: 8382; X64-BMITBM: # %bb.0: 8383; X64-BMITBM-NEXT: bextrl $2579, %edi, %eax # imm = 0xA13 8384; X64-BMITBM-NEXT: movl %eax, (%rsi) 8385; X64-BMITBM-NEXT: retq 8386 %tmp0 = lshr i32 %arg, 19 8387 %tmp1 = and i32 %tmp0, 1023 8388 store i32 %tmp1, ptr %ptr 8389 ret void 8390} 8391 8392; Should be still fine, but the mask is shifted 8393define void @c6_i32(i32 %arg, ptr %ptr) nounwind { 8394; X86-NOBMI-LABEL: c6_i32: 8395; X86-NOBMI: # %bb.0: 8396; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 8397; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx 8398; X86-NOBMI-NEXT: shrl $19, %ecx 8399; X86-NOBMI-NEXT: andl $4095, %ecx # imm = 0xFFF 8400; X86-NOBMI-NEXT: movl %ecx, (%eax) 8401; X86-NOBMI-NEXT: retl 8402; 8403; X86-BMINOTBM-LABEL: c6_i32: 8404; X86-BMINOTBM: # %bb.0: 8405; X86-BMINOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8406; X86-BMINOTBM-NEXT: movl $3091, %ecx # imm = 0xC13 8407; X86-BMINOTBM-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %ecx 8408; X86-BMINOTBM-NEXT: movl %ecx, (%eax) 8409; X86-BMINOTBM-NEXT: retl 8410; 8411; X86-BMITBM-LABEL: c6_i32: 8412; X86-BMITBM: # %bb.0: 8413; X86-BMITBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8414; X86-BMITBM-NEXT: bextrl $3091, {{[0-9]+}}(%esp), %ecx # imm = 0xC13 8415; X86-BMITBM-NEXT: movl %ecx, (%eax) 8416; X86-BMITBM-NEXT: retl 8417; 8418; X64-NOBMI-LABEL: c6_i32: 8419; X64-NOBMI: # %bb.0: 8420; X64-NOBMI-NEXT: shrl $19, %edi 8421; X64-NOBMI-NEXT: andl $4095, %edi # imm = 0xFFF 8422; X64-NOBMI-NEXT: movl %edi, (%rsi) 8423; X64-NOBMI-NEXT: retq 8424; 8425; X64-BMINOTBM-LABEL: c6_i32: 8426; X64-BMINOTBM: # %bb.0: 8427; X64-BMINOTBM-NEXT: movl $3091, %eax # imm = 0xC13 8428; X64-BMINOTBM-NEXT: bextrl %eax, %edi, %eax 8429; X64-BMINOTBM-NEXT: movl %eax, (%rsi) 8430; X64-BMINOTBM-NEXT: retq 8431; 8432; X64-BMITBM-LABEL: c6_i32: 8433; X64-BMITBM: # %bb.0: 8434; X64-BMITBM-NEXT: bextrl $3091, %edi, %eax # imm = 0xC13 8435; X64-BMITBM-NEXT: movl %eax, (%rsi) 8436; X64-BMITBM-NEXT: retq 8437 %tmp0 = lshr i32 %arg, 19 8438 %tmp1 = and i32 %tmp0, 4095 8439 store i32 %tmp1, ptr %ptr 8440 ret void 8441} 8442 8443; Should be still fine, but the result is shifted left afterwards 8444define void @c7_i32(i32 %arg, ptr %ptr) nounwind { 8445; X86-LABEL: c7_i32: 8446; X86: # %bb.0: 8447; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 8448; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 8449; X86-NEXT: shrl $17, %ecx 8450; X86-NEXT: andl $4092, %ecx # imm = 0xFFC 8451; X86-NEXT: movl %ecx, (%eax) 8452; X86-NEXT: retl 8453; 8454; X64-LABEL: c7_i32: 8455; X64: # %bb.0: 8456; X64-NEXT: shrl $17, %edi 8457; X64-NEXT: andl $4092, %edi # imm = 0xFFC 8458; X64-NEXT: movl %edi, (%rsi) 8459; X64-NEXT: retq 8460 %tmp0 = lshr i32 %arg, 19 8461 %tmp1 = and i32 %tmp0, 1023 8462 %tmp2 = shl i32 %tmp1, 2 8463 store i32 %tmp2, ptr %ptr 8464 ret void 8465} 8466 8467; i64 8468 8469; The most canonical variant 8470define void @c5_i64(i64 %arg, ptr %ptr) nounwind { 8471; X86-NOBMI-LABEL: c5_i64: 8472; X86-NOBMI: # %bb.0: 8473; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 8474; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx 8475; X86-NOBMI-NEXT: shrl $19, %ecx 8476; X86-NOBMI-NEXT: andl $1023, %ecx # imm = 0x3FF 8477; X86-NOBMI-NEXT: movl %ecx, (%eax) 8478; X86-NOBMI-NEXT: movl $0, 4(%eax) 8479; X86-NOBMI-NEXT: retl 8480; 8481; X86-BMINOTBM-LABEL: c5_i64: 8482; X86-BMINOTBM: # %bb.0: 8483; X86-BMINOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8484; X86-BMINOTBM-NEXT: movl $2579, %ecx # imm = 0xA13 8485; X86-BMINOTBM-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %ecx 8486; X86-BMINOTBM-NEXT: movl %ecx, (%eax) 8487; X86-BMINOTBM-NEXT: movl $0, 4(%eax) 8488; X86-BMINOTBM-NEXT: retl 8489; 8490; X86-BMITBM-LABEL: c5_i64: 8491; X86-BMITBM: # %bb.0: 8492; X86-BMITBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8493; X86-BMITBM-NEXT: bextrl $2579, {{[0-9]+}}(%esp), %ecx # imm = 0xA13 8494; X86-BMITBM-NEXT: movl %ecx, (%eax) 8495; X86-BMITBM-NEXT: movl $0, 4(%eax) 8496; X86-BMITBM-NEXT: retl 8497; 8498; X64-NOBMI-LABEL: c5_i64: 8499; X64-NOBMI: # %bb.0: 8500; X64-NOBMI-NEXT: shrq $51, %rdi 8501; X64-NOBMI-NEXT: andl $1023, %edi # imm = 0x3FF 8502; X64-NOBMI-NEXT: movq %rdi, (%rsi) 8503; X64-NOBMI-NEXT: retq 8504; 8505; X64-BMINOTBM-LABEL: c5_i64: 8506; X64-BMINOTBM: # %bb.0: 8507; X64-BMINOTBM-NEXT: movl $2611, %eax # imm = 0xA33 8508; X64-BMINOTBM-NEXT: bextrq %rax, %rdi, %rax 8509; X64-BMINOTBM-NEXT: movq %rax, (%rsi) 8510; X64-BMINOTBM-NEXT: retq 8511; 8512; X64-BMITBM-LABEL: c5_i64: 8513; X64-BMITBM: # %bb.0: 8514; X64-BMITBM-NEXT: bextrq $2611, %rdi, %rax # imm = 0xA33 8515; X64-BMITBM-NEXT: movq %rax, (%rsi) 8516; X64-BMITBM-NEXT: retq 8517 %tmp0 = lshr i64 %arg, 51 8518 %tmp1 = and i64 %tmp0, 1023 8519 store i64 %tmp1, ptr %ptr 8520 ret void 8521} 8522 8523; Should be still fine, but the mask is shifted 8524define void @c6_i64(i64 %arg, ptr %ptr) nounwind { 8525; X86-NOBMI-LABEL: c6_i64: 8526; X86-NOBMI: # %bb.0: 8527; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax 8528; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx 8529; X86-NOBMI-NEXT: shrl $19, %ecx 8530; X86-NOBMI-NEXT: andl $4095, %ecx # imm = 0xFFF 8531; X86-NOBMI-NEXT: movl %ecx, (%eax) 8532; X86-NOBMI-NEXT: movl $0, 4(%eax) 8533; X86-NOBMI-NEXT: retl 8534; 8535; X86-BMINOTBM-LABEL: c6_i64: 8536; X86-BMINOTBM: # %bb.0: 8537; X86-BMINOTBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8538; X86-BMINOTBM-NEXT: movl $3091, %ecx # imm = 0xC13 8539; X86-BMINOTBM-NEXT: bextrl %ecx, {{[0-9]+}}(%esp), %ecx 8540; X86-BMINOTBM-NEXT: movl %ecx, (%eax) 8541; X86-BMINOTBM-NEXT: movl $0, 4(%eax) 8542; X86-BMINOTBM-NEXT: retl 8543; 8544; X86-BMITBM-LABEL: c6_i64: 8545; X86-BMITBM: # %bb.0: 8546; X86-BMITBM-NEXT: movl {{[0-9]+}}(%esp), %eax 8547; X86-BMITBM-NEXT: bextrl $3091, {{[0-9]+}}(%esp), %ecx # imm = 0xC13 8548; X86-BMITBM-NEXT: movl %ecx, (%eax) 8549; X86-BMITBM-NEXT: movl $0, 4(%eax) 8550; X86-BMITBM-NEXT: retl 8551; 8552; X64-NOBMI-LABEL: c6_i64: 8553; X64-NOBMI: # %bb.0: 8554; X64-NOBMI-NEXT: shrq $51, %rdi 8555; X64-NOBMI-NEXT: andl $4095, %edi # imm = 0xFFF 8556; X64-NOBMI-NEXT: movq %rdi, (%rsi) 8557; X64-NOBMI-NEXT: retq 8558; 8559; X64-BMINOTBM-LABEL: c6_i64: 8560; X64-BMINOTBM: # %bb.0: 8561; X64-BMINOTBM-NEXT: movl $3123, %eax # imm = 0xC33 8562; X64-BMINOTBM-NEXT: bextrq %rax, %rdi, %rax 8563; X64-BMINOTBM-NEXT: movq %rax, (%rsi) 8564; X64-BMINOTBM-NEXT: retq 8565; 8566; X64-BMITBM-LABEL: c6_i64: 8567; X64-BMITBM: # %bb.0: 8568; X64-BMITBM-NEXT: bextrq $3123, %rdi, %rax # imm = 0xC33 8569; X64-BMITBM-NEXT: movq %rax, (%rsi) 8570; X64-BMITBM-NEXT: retq 8571 %tmp0 = lshr i64 %arg, 51 8572 %tmp1 = and i64 %tmp0, 4095 8573 store i64 %tmp1, ptr %ptr 8574 ret void 8575} 8576 8577; Should be still fine, but the result is shifted left afterwards 8578define void @c7_i64(i64 %arg, ptr %ptr) nounwind { 8579; X86-LABEL: c7_i64: 8580; X86: # %bb.0: 8581; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 8582; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 8583; X86-NEXT: shrl $17, %ecx 8584; X86-NEXT: andl $4092, %ecx # imm = 0xFFC 8585; X86-NEXT: movl %ecx, (%eax) 8586; X86-NEXT: movl $0, 4(%eax) 8587; X86-NEXT: retl 8588; 8589; X64-LABEL: c7_i64: 8590; X64: # %bb.0: 8591; X64-NEXT: shrq $49, %rdi 8592; X64-NEXT: andl $4092, %edi # imm = 0xFFC 8593; X64-NEXT: movq %rdi, (%rsi) 8594; X64-NEXT: retq 8595 %tmp0 = lshr i64 %arg, 51 8596 %tmp1 = and i64 %tmp0, 1023 8597 %tmp2 = shl i64 %tmp1, 2 8598 store i64 %tmp2, ptr %ptr 8599 ret void 8600} 8601 8602define i64 @c8_i64(i64 %arg, ptr %ptr) nounwind { 8603; X86-LABEL: c8_i64: 8604; X86: # %bb.0: 8605; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 8606; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 8607; X86-NEXT: movl (%eax), %eax 8608; X86-NEXT: shrl $19, %eax 8609; X86-NEXT: andl $4092, %eax # imm = 0xFFC 8610; X86-NEXT: addl {{[0-9]+}}(%esp), %eax 8611; X86-NEXT: adcl $0, %edx 8612; X86-NEXT: retl 8613; 8614; X64-NOBMI-LABEL: c8_i64: 8615; X64-NOBMI: # %bb.0: 8616; X64-NOBMI-NEXT: movl (%rsi), %eax 8617; X64-NOBMI-NEXT: shrl $19, %eax 8618; X64-NOBMI-NEXT: andl $4092, %eax # imm = 0xFFC 8619; X64-NOBMI-NEXT: addq %rdi, %rax 8620; X64-NOBMI-NEXT: retq 8621; 8622; X64-BMINOTBM-LABEL: c8_i64: 8623; X64-BMINOTBM: # %bb.0: 8624; X64-BMINOTBM-NEXT: movl $2581, %eax # imm = 0xA15 8625; X64-BMINOTBM-NEXT: bextrl %eax, (%rsi), %eax 8626; X64-BMINOTBM-NEXT: leaq (%rdi,%rax,4), %rax 8627; X64-BMINOTBM-NEXT: retq 8628; 8629; X64-BMITBM-LABEL: c8_i64: 8630; X64-BMITBM: # %bb.0: 8631; X64-BMITBM-NEXT: bextrl $2581, (%rsi), %eax # imm = 0xA15 8632; X64-BMITBM-NEXT: leaq (%rdi,%rax,4), %rax 8633; X64-BMITBM-NEXT: retq 8634 %tmp = load i32, ptr %ptr, align 8 8635 %tmp1 = lshr i32 %tmp, 19 8636 %tmp2 = and i32 %tmp1, 4092 8637 %tmp3 = zext i32 %tmp2 to i64 8638 %tmp4 = add i64 %arg, %tmp3 8639 ret i64 %tmp4 8640} 8641