1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,NOBMI2,X86-NOBMI2,FALLBACK0,X86-FALLBACK0 3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,NOBMI2,X86-NOBMI2,FALLBACK1,X86-FALLBACK1 4; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,NOBMI2,X86-NOBMI2,FALLBACK2,X86-FALLBACK2 5; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI2,X86-BMI2,FALLBACK3,X86-FALLBACK3 6; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,BMI2,X86-BMI2,FALLBACK4,X86-FALLBACK4 7; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI2,X64-NOBMI2,FALLBACK0,X64-FALLBACK0 8; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI2,X64-NOBMI2,FALLBACK1,X64-FALLBACK1 9; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,-bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,NOBMI2,X64-NOBMI2,FALLBACK2,X64-FALLBACK2 10; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,+tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI2,X64-BMI2,FALLBACK3,X64-FALLBACK3 11; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi,-tbm,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,BMI2,X64-BMI2,FALLBACK4,X64-FALLBACK4 12 13; Patterns: 14; c) x & (-1 << y) 15; ic) x & (-1 << (32 - y)) 16; d) x >> y << y 17; id) x >> (32 - y) << (32 - y) 18; are equivalent, but we prefer the second variant if we have BMI2. 19 20; ---------------------------------------------------------------------------- ; 21; Pattern c. 22; ---------------------------------------------------------------------------- ; 23 24; 8-bit 25 26define i8 @clear_lowbits8_c0(i8 %val, i8 %numlowbits) nounwind { 27; X86-LABEL: clear_lowbits8_c0: 28; X86: # %bb.0: 29; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 30; X86-NEXT: movb {{[0-9]+}}(%esp), %al 31; X86-NEXT: shrb %cl, %al 32; X86-NEXT: shlb %cl, %al 33; X86-NEXT: retl 34; 35; X64-LABEL: clear_lowbits8_c0: 36; X64: # %bb.0: 37; X64-NEXT: movl %esi, %ecx 38; X64-NEXT: movl %edi, %eax 39; X64-NEXT: shrb %cl, %al 40; X64-NEXT: # kill: def $cl killed $cl killed $ecx 41; X64-NEXT: shlb %cl, %al 42; X64-NEXT: # kill: def $al killed $al killed $eax 43; X64-NEXT: retq 44 %mask = shl i8 -1, %numlowbits 45 %masked = and i8 %mask, %val 46 ret i8 %masked 47} 48 49define i8 @clear_lowbits8_c2_load(i8* %w, i8 %numlowbits) nounwind { 50; X86-LABEL: clear_lowbits8_c2_load: 51; X86: # %bb.0: 52; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 53; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 54; X86-NEXT: movb (%eax), %al 55; X86-NEXT: shrb %cl, %al 56; X86-NEXT: shlb %cl, %al 57; X86-NEXT: retl 58; 59; X64-LABEL: clear_lowbits8_c2_load: 60; X64: # %bb.0: 61; X64-NEXT: movl %esi, %ecx 62; X64-NEXT: movb (%rdi), %al 63; X64-NEXT: shrb %cl, %al 64; X64-NEXT: # kill: def $cl killed $cl killed $ecx 65; X64-NEXT: shlb %cl, %al 66; X64-NEXT: retq 67 %val = load i8, i8* %w 68 %mask = shl i8 -1, %numlowbits 69 %masked = and i8 %mask, %val 70 ret i8 %masked 71} 72 73define i8 @clear_lowbits8_c4_commutative(i8 %val, i8 %numlowbits) nounwind { 74; X86-LABEL: clear_lowbits8_c4_commutative: 75; X86: # %bb.0: 76; X86-NEXT: movb {{[0-9]+}}(%esp), %cl 77; X86-NEXT: movb {{[0-9]+}}(%esp), %al 78; X86-NEXT: shrb %cl, %al 79; X86-NEXT: shlb %cl, %al 80; X86-NEXT: retl 81; 82; X64-LABEL: clear_lowbits8_c4_commutative: 83; X64: # %bb.0: 84; X64-NEXT: movl %esi, %ecx 85; X64-NEXT: movl %edi, %eax 86; X64-NEXT: shrb %cl, %al 87; X64-NEXT: # kill: def $cl killed $cl killed $ecx 88; X64-NEXT: shlb %cl, %al 89; X64-NEXT: # kill: def $al killed $al killed $eax 90; X64-NEXT: retq 91 %mask = shl i8 -1, %numlowbits 92 %masked = and i8 %val, %mask ; swapped order 93 ret i8 %masked 94} 95 96; 16-bit 97 98define i16 @clear_lowbits16_c0(i16 %val, i16 %numlowbits) nounwind { 99; X86-NOBMI2-LABEL: clear_lowbits16_c0: 100; X86-NOBMI2: # %bb.0: 101; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 102; X86-NOBMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 103; X86-NOBMI2-NEXT: shrl %cl, %eax 104; X86-NOBMI2-NEXT: shll %cl, %eax 105; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 106; X86-NOBMI2-NEXT: retl 107; 108; X86-BMI2-LABEL: clear_lowbits16_c0: 109; X86-BMI2: # %bb.0: 110; X86-BMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 111; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 112; X86-BMI2-NEXT: shrxl %ecx, %eax, %eax 113; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 114; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 115; X86-BMI2-NEXT: retl 116; 117; X64-NOBMI2-LABEL: clear_lowbits16_c0: 118; X64-NOBMI2: # %bb.0: 119; X64-NOBMI2-NEXT: movl %esi, %ecx 120; X64-NOBMI2-NEXT: movzwl %di, %eax 121; X64-NOBMI2-NEXT: shrl %cl, %eax 122; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 123; X64-NOBMI2-NEXT: shll %cl, %eax 124; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 125; X64-NOBMI2-NEXT: retq 126; 127; X64-BMI2-LABEL: clear_lowbits16_c0: 128; X64-BMI2: # %bb.0: 129; X64-BMI2-NEXT: movzwl %di, %eax 130; X64-BMI2-NEXT: shrxl %esi, %eax, %eax 131; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 132; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 133; X64-BMI2-NEXT: retq 134 %mask = shl i16 -1, %numlowbits 135 %masked = and i16 %mask, %val 136 ret i16 %masked 137} 138 139define i16 @clear_lowbits16_c1_indexzext(i16 %val, i8 %numlowbits) nounwind { 140; X86-NOBMI2-LABEL: clear_lowbits16_c1_indexzext: 141; X86-NOBMI2: # %bb.0: 142; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 143; X86-NOBMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 144; X86-NOBMI2-NEXT: shrl %cl, %eax 145; X86-NOBMI2-NEXT: shll %cl, %eax 146; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 147; X86-NOBMI2-NEXT: retl 148; 149; X86-BMI2-LABEL: clear_lowbits16_c1_indexzext: 150; X86-BMI2: # %bb.0: 151; X86-BMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 152; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 153; X86-BMI2-NEXT: shrxl %ecx, %eax, %eax 154; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 155; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 156; X86-BMI2-NEXT: retl 157; 158; X64-NOBMI2-LABEL: clear_lowbits16_c1_indexzext: 159; X64-NOBMI2: # %bb.0: 160; X64-NOBMI2-NEXT: movl %esi, %ecx 161; X64-NOBMI2-NEXT: movzwl %di, %eax 162; X64-NOBMI2-NEXT: shrl %cl, %eax 163; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 164; X64-NOBMI2-NEXT: shll %cl, %eax 165; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 166; X64-NOBMI2-NEXT: retq 167; 168; X64-BMI2-LABEL: clear_lowbits16_c1_indexzext: 169; X64-BMI2: # %bb.0: 170; X64-BMI2-NEXT: movzwl %di, %eax 171; X64-BMI2-NEXT: shrxl %esi, %eax, %eax 172; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 173; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 174; X64-BMI2-NEXT: retq 175 %sh_prom = zext i8 %numlowbits to i16 176 %mask = shl i16 -1, %sh_prom 177 %masked = and i16 %mask, %val 178 ret i16 %masked 179} 180 181define i16 @clear_lowbits16_c2_load(i16* %w, i16 %numlowbits) nounwind { 182; X86-NOBMI2-LABEL: clear_lowbits16_c2_load: 183; X86-NOBMI2: # %bb.0: 184; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 185; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 186; X86-NOBMI2-NEXT: movzwl (%eax), %eax 187; X86-NOBMI2-NEXT: shrl %cl, %eax 188; X86-NOBMI2-NEXT: shll %cl, %eax 189; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 190; X86-NOBMI2-NEXT: retl 191; 192; X86-BMI2-LABEL: clear_lowbits16_c2_load: 193; X86-BMI2: # %bb.0: 194; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 195; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 196; X86-BMI2-NEXT: movzwl (%ecx), %ecx 197; X86-BMI2-NEXT: shrxl %eax, %ecx, %ecx 198; X86-BMI2-NEXT: shlxl %eax, %ecx, %eax 199; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 200; X86-BMI2-NEXT: retl 201; 202; X64-NOBMI2-LABEL: clear_lowbits16_c2_load: 203; X64-NOBMI2: # %bb.0: 204; X64-NOBMI2-NEXT: movl %esi, %ecx 205; X64-NOBMI2-NEXT: movzwl (%rdi), %eax 206; X64-NOBMI2-NEXT: shrl %cl, %eax 207; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 208; X64-NOBMI2-NEXT: shll %cl, %eax 209; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 210; X64-NOBMI2-NEXT: retq 211; 212; X64-BMI2-LABEL: clear_lowbits16_c2_load: 213; X64-BMI2: # %bb.0: 214; X64-BMI2-NEXT: movzwl (%rdi), %eax 215; X64-BMI2-NEXT: shrxl %esi, %eax, %eax 216; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 217; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 218; X64-BMI2-NEXT: retq 219 %val = load i16, i16* %w 220 %mask = shl i16 -1, %numlowbits 221 %masked = and i16 %mask, %val 222 ret i16 %masked 223} 224 225define i16 @clear_lowbits16_c3_load_indexzext(i16* %w, i8 %numlowbits) nounwind { 226; X86-NOBMI2-LABEL: clear_lowbits16_c3_load_indexzext: 227; X86-NOBMI2: # %bb.0: 228; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 229; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 230; X86-NOBMI2-NEXT: movzwl (%eax), %eax 231; X86-NOBMI2-NEXT: shrl %cl, %eax 232; X86-NOBMI2-NEXT: shll %cl, %eax 233; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 234; X86-NOBMI2-NEXT: retl 235; 236; X86-BMI2-LABEL: clear_lowbits16_c3_load_indexzext: 237; X86-BMI2: # %bb.0: 238; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 239; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %ecx 240; X86-BMI2-NEXT: movzwl (%ecx), %ecx 241; X86-BMI2-NEXT: shrxl %eax, %ecx, %ecx 242; X86-BMI2-NEXT: shlxl %eax, %ecx, %eax 243; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 244; X86-BMI2-NEXT: retl 245; 246; X64-NOBMI2-LABEL: clear_lowbits16_c3_load_indexzext: 247; X64-NOBMI2: # %bb.0: 248; X64-NOBMI2-NEXT: movl %esi, %ecx 249; X64-NOBMI2-NEXT: movzwl (%rdi), %eax 250; X64-NOBMI2-NEXT: shrl %cl, %eax 251; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 252; X64-NOBMI2-NEXT: shll %cl, %eax 253; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 254; X64-NOBMI2-NEXT: retq 255; 256; X64-BMI2-LABEL: clear_lowbits16_c3_load_indexzext: 257; X64-BMI2: # %bb.0: 258; X64-BMI2-NEXT: movzwl (%rdi), %eax 259; X64-BMI2-NEXT: shrxl %esi, %eax, %eax 260; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 261; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 262; X64-BMI2-NEXT: retq 263 %val = load i16, i16* %w 264 %sh_prom = zext i8 %numlowbits to i16 265 %mask = shl i16 -1, %sh_prom 266 %masked = and i16 %mask, %val 267 ret i16 %masked 268} 269 270define i16 @clear_lowbits16_c4_commutative(i16 %val, i16 %numlowbits) nounwind { 271; X86-NOBMI2-LABEL: clear_lowbits16_c4_commutative: 272; X86-NOBMI2: # %bb.0: 273; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 274; X86-NOBMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 275; X86-NOBMI2-NEXT: shrl %cl, %eax 276; X86-NOBMI2-NEXT: shll %cl, %eax 277; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 278; X86-NOBMI2-NEXT: retl 279; 280; X86-BMI2-LABEL: clear_lowbits16_c4_commutative: 281; X86-BMI2: # %bb.0: 282; X86-BMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 283; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 284; X86-BMI2-NEXT: shrxl %ecx, %eax, %eax 285; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 286; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 287; X86-BMI2-NEXT: retl 288; 289; X64-NOBMI2-LABEL: clear_lowbits16_c4_commutative: 290; X64-NOBMI2: # %bb.0: 291; X64-NOBMI2-NEXT: movl %esi, %ecx 292; X64-NOBMI2-NEXT: movzwl %di, %eax 293; X64-NOBMI2-NEXT: shrl %cl, %eax 294; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 295; X64-NOBMI2-NEXT: shll %cl, %eax 296; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 297; X64-NOBMI2-NEXT: retq 298; 299; X64-BMI2-LABEL: clear_lowbits16_c4_commutative: 300; X64-BMI2: # %bb.0: 301; X64-BMI2-NEXT: movzwl %di, %eax 302; X64-BMI2-NEXT: shrxl %esi, %eax, %eax 303; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 304; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 305; X64-BMI2-NEXT: retq 306 %mask = shl i16 -1, %numlowbits 307 %masked = and i16 %val, %mask ; swapped order 308 ret i16 %masked 309} 310 311; 32-bit 312 313define i32 @clear_lowbits32_c0(i32 %val, i32 %numlowbits) nounwind { 314; X86-NOBMI2-LABEL: clear_lowbits32_c0: 315; X86-NOBMI2: # %bb.0: 316; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 317; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 318; X86-NOBMI2-NEXT: shrl %cl, %eax 319; X86-NOBMI2-NEXT: shll %cl, %eax 320; X86-NOBMI2-NEXT: retl 321; 322; X86-BMI2-LABEL: clear_lowbits32_c0: 323; X86-BMI2: # %bb.0: 324; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 325; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %ecx 326; X86-BMI2-NEXT: shlxl %eax, %ecx, %eax 327; X86-BMI2-NEXT: retl 328; 329; X64-NOBMI2-LABEL: clear_lowbits32_c0: 330; X64-NOBMI2: # %bb.0: 331; X64-NOBMI2-NEXT: movl %esi, %ecx 332; X64-NOBMI2-NEXT: movl %edi, %eax 333; X64-NOBMI2-NEXT: shrl %cl, %eax 334; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 335; X64-NOBMI2-NEXT: shll %cl, %eax 336; X64-NOBMI2-NEXT: retq 337; 338; X64-BMI2-LABEL: clear_lowbits32_c0: 339; X64-BMI2: # %bb.0: 340; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 341; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 342; X64-BMI2-NEXT: retq 343 %mask = shl i32 -1, %numlowbits 344 %masked = and i32 %mask, %val 345 ret i32 %masked 346} 347 348define i32 @clear_lowbits32_c1_indexzext(i32 %val, i8 %numlowbits) nounwind { 349; X86-NOBMI2-LABEL: clear_lowbits32_c1_indexzext: 350; X86-NOBMI2: # %bb.0: 351; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 352; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 353; X86-NOBMI2-NEXT: shrl %cl, %eax 354; X86-NOBMI2-NEXT: shll %cl, %eax 355; X86-NOBMI2-NEXT: retl 356; 357; X86-BMI2-LABEL: clear_lowbits32_c1_indexzext: 358; X86-BMI2: # %bb.0: 359; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 360; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %ecx 361; X86-BMI2-NEXT: shlxl %eax, %ecx, %eax 362; X86-BMI2-NEXT: retl 363; 364; X64-NOBMI2-LABEL: clear_lowbits32_c1_indexzext: 365; X64-NOBMI2: # %bb.0: 366; X64-NOBMI2-NEXT: movl %esi, %ecx 367; X64-NOBMI2-NEXT: movl %edi, %eax 368; X64-NOBMI2-NEXT: shrl %cl, %eax 369; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 370; X64-NOBMI2-NEXT: shll %cl, %eax 371; X64-NOBMI2-NEXT: retq 372; 373; X64-BMI2-LABEL: clear_lowbits32_c1_indexzext: 374; X64-BMI2: # %bb.0: 375; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 376; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 377; X64-BMI2-NEXT: retq 378 %sh_prom = zext i8 %numlowbits to i32 379 %mask = shl i32 -1, %sh_prom 380 %masked = and i32 %mask, %val 381 ret i32 %masked 382} 383 384define i32 @clear_lowbits32_c2_load(i32* %w, i32 %numlowbits) nounwind { 385; X86-NOBMI2-LABEL: clear_lowbits32_c2_load: 386; X86-NOBMI2: # %bb.0: 387; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 388; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 389; X86-NOBMI2-NEXT: movl (%eax), %eax 390; X86-NOBMI2-NEXT: shrl %cl, %eax 391; X86-NOBMI2-NEXT: shll %cl, %eax 392; X86-NOBMI2-NEXT: retl 393; 394; X86-BMI2-LABEL: clear_lowbits32_c2_load: 395; X86-BMI2: # %bb.0: 396; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 397; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 398; X86-BMI2-NEXT: shrxl %ecx, (%eax), %eax 399; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 400; X86-BMI2-NEXT: retl 401; 402; X64-NOBMI2-LABEL: clear_lowbits32_c2_load: 403; X64-NOBMI2: # %bb.0: 404; X64-NOBMI2-NEXT: movl %esi, %ecx 405; X64-NOBMI2-NEXT: movl (%rdi), %eax 406; X64-NOBMI2-NEXT: shrl %cl, %eax 407; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 408; X64-NOBMI2-NEXT: shll %cl, %eax 409; X64-NOBMI2-NEXT: retq 410; 411; X64-BMI2-LABEL: clear_lowbits32_c2_load: 412; X64-BMI2: # %bb.0: 413; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 414; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 415; X64-BMI2-NEXT: retq 416 %val = load i32, i32* %w 417 %mask = shl i32 -1, %numlowbits 418 %masked = and i32 %mask, %val 419 ret i32 %masked 420} 421 422define i32 @clear_lowbits32_c3_load_indexzext(i32* %w, i8 %numlowbits) nounwind { 423; X86-NOBMI2-LABEL: clear_lowbits32_c3_load_indexzext: 424; X86-NOBMI2: # %bb.0: 425; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 426; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 427; X86-NOBMI2-NEXT: movl (%eax), %eax 428; X86-NOBMI2-NEXT: shrl %cl, %eax 429; X86-NOBMI2-NEXT: shll %cl, %eax 430; X86-NOBMI2-NEXT: retl 431; 432; X86-BMI2-LABEL: clear_lowbits32_c3_load_indexzext: 433; X86-BMI2: # %bb.0: 434; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 435; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 436; X86-BMI2-NEXT: shrxl %ecx, (%eax), %eax 437; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 438; X86-BMI2-NEXT: retl 439; 440; X64-NOBMI2-LABEL: clear_lowbits32_c3_load_indexzext: 441; X64-NOBMI2: # %bb.0: 442; X64-NOBMI2-NEXT: movl %esi, %ecx 443; X64-NOBMI2-NEXT: movl (%rdi), %eax 444; X64-NOBMI2-NEXT: shrl %cl, %eax 445; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 446; X64-NOBMI2-NEXT: shll %cl, %eax 447; X64-NOBMI2-NEXT: retq 448; 449; X64-BMI2-LABEL: clear_lowbits32_c3_load_indexzext: 450; X64-BMI2: # %bb.0: 451; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 452; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 453; X64-BMI2-NEXT: retq 454 %val = load i32, i32* %w 455 %sh_prom = zext i8 %numlowbits to i32 456 %mask = shl i32 -1, %sh_prom 457 %masked = and i32 %mask, %val 458 ret i32 %masked 459} 460 461define i32 @clear_lowbits32_c4_commutative(i32 %val, i32 %numlowbits) nounwind { 462; X86-NOBMI2-LABEL: clear_lowbits32_c4_commutative: 463; X86-NOBMI2: # %bb.0: 464; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 465; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 466; X86-NOBMI2-NEXT: shrl %cl, %eax 467; X86-NOBMI2-NEXT: shll %cl, %eax 468; X86-NOBMI2-NEXT: retl 469; 470; X86-BMI2-LABEL: clear_lowbits32_c4_commutative: 471; X86-BMI2: # %bb.0: 472; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 473; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %ecx 474; X86-BMI2-NEXT: shlxl %eax, %ecx, %eax 475; X86-BMI2-NEXT: retl 476; 477; X64-NOBMI2-LABEL: clear_lowbits32_c4_commutative: 478; X64-NOBMI2: # %bb.0: 479; X64-NOBMI2-NEXT: movl %esi, %ecx 480; X64-NOBMI2-NEXT: movl %edi, %eax 481; X64-NOBMI2-NEXT: shrl %cl, %eax 482; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 483; X64-NOBMI2-NEXT: shll %cl, %eax 484; X64-NOBMI2-NEXT: retq 485; 486; X64-BMI2-LABEL: clear_lowbits32_c4_commutative: 487; X64-BMI2: # %bb.0: 488; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 489; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 490; X64-BMI2-NEXT: retq 491 %mask = shl i32 -1, %numlowbits 492 %masked = and i32 %val, %mask ; swapped order 493 ret i32 %masked 494} 495 496; 64-bit 497 498define i64 @clear_lowbits64_c0(i64 %val, i64 %numlowbits) nounwind { 499; X86-NOBMI2-LABEL: clear_lowbits64_c0: 500; X86-NOBMI2: # %bb.0: 501; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 502; X86-NOBMI2-NEXT: movl $-1, %edx 503; X86-NOBMI2-NEXT: movl $-1, %eax 504; X86-NOBMI2-NEXT: shll %cl, %eax 505; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 506; X86-NOBMI2-NEXT: testb $32, %cl 507; X86-NOBMI2-NEXT: je .LBB13_2 508; X86-NOBMI2-NEXT: # %bb.1: 509; X86-NOBMI2-NEXT: movl %eax, %edx 510; X86-NOBMI2-NEXT: xorl %eax, %eax 511; X86-NOBMI2-NEXT: .LBB13_2: 512; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 513; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 514; X86-NOBMI2-NEXT: retl 515; 516; X86-BMI2-LABEL: clear_lowbits64_c0: 517; X86-BMI2: # %bb.0: 518; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 519; X86-BMI2-NEXT: movl $-1, %edx 520; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 521; X86-BMI2-NEXT: shldl %cl, %edx, %edx 522; X86-BMI2-NEXT: testb $32, %cl 523; X86-BMI2-NEXT: je .LBB13_2 524; X86-BMI2-NEXT: # %bb.1: 525; X86-BMI2-NEXT: movl %eax, %edx 526; X86-BMI2-NEXT: xorl %eax, %eax 527; X86-BMI2-NEXT: .LBB13_2: 528; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 529; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 530; X86-BMI2-NEXT: retl 531; 532; X64-NOBMI2-LABEL: clear_lowbits64_c0: 533; X64-NOBMI2: # %bb.0: 534; X64-NOBMI2-NEXT: movq %rsi, %rcx 535; X64-NOBMI2-NEXT: movq %rdi, %rax 536; X64-NOBMI2-NEXT: shrq %cl, %rax 537; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx 538; X64-NOBMI2-NEXT: shlq %cl, %rax 539; X64-NOBMI2-NEXT: retq 540; 541; X64-BMI2-LABEL: clear_lowbits64_c0: 542; X64-BMI2: # %bb.0: 543; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 544; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 545; X64-BMI2-NEXT: retq 546 %mask = shl i64 -1, %numlowbits 547 %masked = and i64 %mask, %val 548 ret i64 %masked 549} 550 551define i64 @clear_lowbits64_c1_indexzext(i64 %val, i8 %numlowbits) nounwind { 552; X86-NOBMI2-LABEL: clear_lowbits64_c1_indexzext: 553; X86-NOBMI2: # %bb.0: 554; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 555; X86-NOBMI2-NEXT: movl $-1, %edx 556; X86-NOBMI2-NEXT: movl $-1, %eax 557; X86-NOBMI2-NEXT: shll %cl, %eax 558; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 559; X86-NOBMI2-NEXT: testb $32, %cl 560; X86-NOBMI2-NEXT: je .LBB14_2 561; X86-NOBMI2-NEXT: # %bb.1: 562; X86-NOBMI2-NEXT: movl %eax, %edx 563; X86-NOBMI2-NEXT: xorl %eax, %eax 564; X86-NOBMI2-NEXT: .LBB14_2: 565; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 566; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 567; X86-NOBMI2-NEXT: retl 568; 569; X86-BMI2-LABEL: clear_lowbits64_c1_indexzext: 570; X86-BMI2: # %bb.0: 571; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 572; X86-BMI2-NEXT: movl $-1, %edx 573; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 574; X86-BMI2-NEXT: shldl %cl, %edx, %edx 575; X86-BMI2-NEXT: testb $32, %cl 576; X86-BMI2-NEXT: je .LBB14_2 577; X86-BMI2-NEXT: # %bb.1: 578; X86-BMI2-NEXT: movl %eax, %edx 579; X86-BMI2-NEXT: xorl %eax, %eax 580; X86-BMI2-NEXT: .LBB14_2: 581; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 582; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 583; X86-BMI2-NEXT: retl 584; 585; X64-NOBMI2-LABEL: clear_lowbits64_c1_indexzext: 586; X64-NOBMI2: # %bb.0: 587; X64-NOBMI2-NEXT: movl %esi, %ecx 588; X64-NOBMI2-NEXT: movq %rdi, %rax 589; X64-NOBMI2-NEXT: shrq %cl, %rax 590; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 591; X64-NOBMI2-NEXT: shlq %cl, %rax 592; X64-NOBMI2-NEXT: retq 593; 594; X64-BMI2-LABEL: clear_lowbits64_c1_indexzext: 595; X64-BMI2: # %bb.0: 596; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 597; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 598; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 599; X64-BMI2-NEXT: retq 600 %sh_prom = zext i8 %numlowbits to i64 601 %mask = shl i64 -1, %sh_prom 602 %masked = and i64 %mask, %val 603 ret i64 %masked 604} 605 606define i64 @clear_lowbits64_c2_load(i64* %w, i64 %numlowbits) nounwind { 607; X86-NOBMI2-LABEL: clear_lowbits64_c2_load: 608; X86-NOBMI2: # %bb.0: 609; X86-NOBMI2-NEXT: pushl %esi 610; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 611; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 612; X86-NOBMI2-NEXT: movl $-1, %edx 613; X86-NOBMI2-NEXT: movl $-1, %eax 614; X86-NOBMI2-NEXT: shll %cl, %eax 615; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 616; X86-NOBMI2-NEXT: testb $32, %cl 617; X86-NOBMI2-NEXT: je .LBB15_2 618; X86-NOBMI2-NEXT: # %bb.1: 619; X86-NOBMI2-NEXT: movl %eax, %edx 620; X86-NOBMI2-NEXT: xorl %eax, %eax 621; X86-NOBMI2-NEXT: .LBB15_2: 622; X86-NOBMI2-NEXT: andl 4(%esi), %edx 623; X86-NOBMI2-NEXT: andl (%esi), %eax 624; X86-NOBMI2-NEXT: popl %esi 625; X86-NOBMI2-NEXT: retl 626; 627; X86-BMI2-LABEL: clear_lowbits64_c2_load: 628; X86-BMI2: # %bb.0: 629; X86-BMI2-NEXT: pushl %esi 630; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 631; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 632; X86-BMI2-NEXT: movl $-1, %edx 633; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 634; X86-BMI2-NEXT: shldl %cl, %edx, %edx 635; X86-BMI2-NEXT: testb $32, %cl 636; X86-BMI2-NEXT: je .LBB15_2 637; X86-BMI2-NEXT: # %bb.1: 638; X86-BMI2-NEXT: movl %eax, %edx 639; X86-BMI2-NEXT: xorl %eax, %eax 640; X86-BMI2-NEXT: .LBB15_2: 641; X86-BMI2-NEXT: andl 4(%esi), %edx 642; X86-BMI2-NEXT: andl (%esi), %eax 643; X86-BMI2-NEXT: popl %esi 644; X86-BMI2-NEXT: retl 645; 646; X64-NOBMI2-LABEL: clear_lowbits64_c2_load: 647; X64-NOBMI2: # %bb.0: 648; X64-NOBMI2-NEXT: movq %rsi, %rcx 649; X64-NOBMI2-NEXT: movq (%rdi), %rax 650; X64-NOBMI2-NEXT: shrq %cl, %rax 651; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx 652; X64-NOBMI2-NEXT: shlq %cl, %rax 653; X64-NOBMI2-NEXT: retq 654; 655; X64-BMI2-LABEL: clear_lowbits64_c2_load: 656; X64-BMI2: # %bb.0: 657; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 658; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 659; X64-BMI2-NEXT: retq 660 %val = load i64, i64* %w 661 %mask = shl i64 -1, %numlowbits 662 %masked = and i64 %mask, %val 663 ret i64 %masked 664} 665 666define i64 @clear_lowbits64_c3_load_indexzext(i64* %w, i8 %numlowbits) nounwind { 667; X86-NOBMI2-LABEL: clear_lowbits64_c3_load_indexzext: 668; X86-NOBMI2: # %bb.0: 669; X86-NOBMI2-NEXT: pushl %esi 670; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 671; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 672; X86-NOBMI2-NEXT: movl $-1, %edx 673; X86-NOBMI2-NEXT: movl $-1, %eax 674; X86-NOBMI2-NEXT: shll %cl, %eax 675; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 676; X86-NOBMI2-NEXT: testb $32, %cl 677; X86-NOBMI2-NEXT: je .LBB16_2 678; X86-NOBMI2-NEXT: # %bb.1: 679; X86-NOBMI2-NEXT: movl %eax, %edx 680; X86-NOBMI2-NEXT: xorl %eax, %eax 681; X86-NOBMI2-NEXT: .LBB16_2: 682; X86-NOBMI2-NEXT: andl 4(%esi), %edx 683; X86-NOBMI2-NEXT: andl (%esi), %eax 684; X86-NOBMI2-NEXT: popl %esi 685; X86-NOBMI2-NEXT: retl 686; 687; X86-BMI2-LABEL: clear_lowbits64_c3_load_indexzext: 688; X86-BMI2: # %bb.0: 689; X86-BMI2-NEXT: pushl %esi 690; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 691; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 692; X86-BMI2-NEXT: movl $-1, %edx 693; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 694; X86-BMI2-NEXT: shldl %cl, %edx, %edx 695; X86-BMI2-NEXT: testb $32, %cl 696; X86-BMI2-NEXT: je .LBB16_2 697; X86-BMI2-NEXT: # %bb.1: 698; X86-BMI2-NEXT: movl %eax, %edx 699; X86-BMI2-NEXT: xorl %eax, %eax 700; X86-BMI2-NEXT: .LBB16_2: 701; X86-BMI2-NEXT: andl 4(%esi), %edx 702; X86-BMI2-NEXT: andl (%esi), %eax 703; X86-BMI2-NEXT: popl %esi 704; X86-BMI2-NEXT: retl 705; 706; X64-NOBMI2-LABEL: clear_lowbits64_c3_load_indexzext: 707; X64-NOBMI2: # %bb.0: 708; X64-NOBMI2-NEXT: movl %esi, %ecx 709; X64-NOBMI2-NEXT: movq (%rdi), %rax 710; X64-NOBMI2-NEXT: shrq %cl, %rax 711; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 712; X64-NOBMI2-NEXT: shlq %cl, %rax 713; X64-NOBMI2-NEXT: retq 714; 715; X64-BMI2-LABEL: clear_lowbits64_c3_load_indexzext: 716; X64-BMI2: # %bb.0: 717; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 718; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 719; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 720; X64-BMI2-NEXT: retq 721 %val = load i64, i64* %w 722 %sh_prom = zext i8 %numlowbits to i64 723 %mask = shl i64 -1, %sh_prom 724 %masked = and i64 %mask, %val 725 ret i64 %masked 726} 727 728define i64 @clear_lowbits64_c4_commutative(i64 %val, i64 %numlowbits) nounwind { 729; X86-NOBMI2-LABEL: clear_lowbits64_c4_commutative: 730; X86-NOBMI2: # %bb.0: 731; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 732; X86-NOBMI2-NEXT: movl $-1, %edx 733; X86-NOBMI2-NEXT: movl $-1, %eax 734; X86-NOBMI2-NEXT: shll %cl, %eax 735; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 736; X86-NOBMI2-NEXT: testb $32, %cl 737; X86-NOBMI2-NEXT: je .LBB17_2 738; X86-NOBMI2-NEXT: # %bb.1: 739; X86-NOBMI2-NEXT: movl %eax, %edx 740; X86-NOBMI2-NEXT: xorl %eax, %eax 741; X86-NOBMI2-NEXT: .LBB17_2: 742; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 743; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 744; X86-NOBMI2-NEXT: retl 745; 746; X86-BMI2-LABEL: clear_lowbits64_c4_commutative: 747; X86-BMI2: # %bb.0: 748; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 749; X86-BMI2-NEXT: movl $-1, %edx 750; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 751; X86-BMI2-NEXT: shldl %cl, %edx, %edx 752; X86-BMI2-NEXT: testb $32, %cl 753; X86-BMI2-NEXT: je .LBB17_2 754; X86-BMI2-NEXT: # %bb.1: 755; X86-BMI2-NEXT: movl %eax, %edx 756; X86-BMI2-NEXT: xorl %eax, %eax 757; X86-BMI2-NEXT: .LBB17_2: 758; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 759; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 760; X86-BMI2-NEXT: retl 761; 762; X64-NOBMI2-LABEL: clear_lowbits64_c4_commutative: 763; X64-NOBMI2: # %bb.0: 764; X64-NOBMI2-NEXT: movq %rsi, %rcx 765; X64-NOBMI2-NEXT: movq %rdi, %rax 766; X64-NOBMI2-NEXT: shrq %cl, %rax 767; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx 768; X64-NOBMI2-NEXT: shlq %cl, %rax 769; X64-NOBMI2-NEXT: retq 770; 771; X64-BMI2-LABEL: clear_lowbits64_c4_commutative: 772; X64-BMI2: # %bb.0: 773; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 774; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 775; X64-BMI2-NEXT: retq 776 %mask = shl i64 -1, %numlowbits 777 %masked = and i64 %val, %mask ; swapped order 778 ret i64 %masked 779} 780 781; ---------------------------------------------------------------------------- ; 782; Pattern ic. 783; ---------------------------------------------------------------------------- ; 784 785; 8-bit 786 787define i8 @clear_lowbits8_ic0(i8 %val, i8 %numlowbits) nounwind { 788; X86-LABEL: clear_lowbits8_ic0: 789; X86: # %bb.0: 790; X86-NEXT: movb {{[0-9]+}}(%esp), %al 791; X86-NEXT: movb $8, %cl 792; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 793; X86-NEXT: shrb %cl, %al 794; X86-NEXT: shlb %cl, %al 795; X86-NEXT: retl 796; 797; X64-LABEL: clear_lowbits8_ic0: 798; X64: # %bb.0: 799; X64-NEXT: movl %edi, %eax 800; X64-NEXT: movb $8, %cl 801; X64-NEXT: subb %sil, %cl 802; X64-NEXT: shrb %cl, %al 803; X64-NEXT: shlb %cl, %al 804; X64-NEXT: # kill: def $al killed $al killed $eax 805; X64-NEXT: retq 806 %numhighbits = sub i8 8, %numlowbits 807 %mask = shl i8 -1, %numhighbits 808 %masked = and i8 %mask, %val 809 ret i8 %masked 810} 811 812define i8 @clear_lowbits8_ic2_load(i8* %w, i8 %numlowbits) nounwind { 813; X86-LABEL: clear_lowbits8_ic2_load: 814; X86: # %bb.0: 815; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 816; X86-NEXT: movb (%eax), %al 817; X86-NEXT: movb $8, %cl 818; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 819; X86-NEXT: shrb %cl, %al 820; X86-NEXT: shlb %cl, %al 821; X86-NEXT: retl 822; 823; X64-LABEL: clear_lowbits8_ic2_load: 824; X64: # %bb.0: 825; X64-NEXT: movb (%rdi), %al 826; X64-NEXT: movb $8, %cl 827; X64-NEXT: subb %sil, %cl 828; X64-NEXT: shrb %cl, %al 829; X64-NEXT: shlb %cl, %al 830; X64-NEXT: retq 831 %val = load i8, i8* %w 832 %numhighbits = sub i8 8, %numlowbits 833 %mask = shl i8 -1, %numhighbits 834 %masked = and i8 %mask, %val 835 ret i8 %masked 836} 837 838define i8 @clear_lowbits8_ic4_commutative(i8 %val, i8 %numlowbits) nounwind { 839; X86-LABEL: clear_lowbits8_ic4_commutative: 840; X86: # %bb.0: 841; X86-NEXT: movb {{[0-9]+}}(%esp), %al 842; X86-NEXT: movb $8, %cl 843; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 844; X86-NEXT: shrb %cl, %al 845; X86-NEXT: shlb %cl, %al 846; X86-NEXT: retl 847; 848; X64-LABEL: clear_lowbits8_ic4_commutative: 849; X64: # %bb.0: 850; X64-NEXT: movl %edi, %eax 851; X64-NEXT: movb $8, %cl 852; X64-NEXT: subb %sil, %cl 853; X64-NEXT: shrb %cl, %al 854; X64-NEXT: shlb %cl, %al 855; X64-NEXT: # kill: def $al killed $al killed $eax 856; X64-NEXT: retq 857 %numhighbits = sub i8 8, %numlowbits 858 %mask = shl i8 -1, %numhighbits 859 %masked = and i8 %val, %mask ; swapped order 860 ret i8 %masked 861} 862 863; 16-bit 864 865define i16 @clear_lowbits16_ic0(i16 %val, i16 %numlowbits) nounwind { 866; X86-NOBMI2-LABEL: clear_lowbits16_ic0: 867; X86-NOBMI2: # %bb.0: 868; X86-NOBMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 869; X86-NOBMI2-NEXT: movb $16, %cl 870; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 871; X86-NOBMI2-NEXT: shrl %cl, %eax 872; X86-NOBMI2-NEXT: shll %cl, %eax 873; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 874; X86-NOBMI2-NEXT: retl 875; 876; X86-BMI2-LABEL: clear_lowbits16_ic0: 877; X86-BMI2: # %bb.0: 878; X86-BMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 879; X86-BMI2-NEXT: movb $16, %cl 880; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 881; X86-BMI2-NEXT: shrxl %ecx, %eax, %eax 882; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 883; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 884; X86-BMI2-NEXT: retl 885; 886; X64-NOBMI2-LABEL: clear_lowbits16_ic0: 887; X64-NOBMI2: # %bb.0: 888; X64-NOBMI2-NEXT: movzwl %di, %eax 889; X64-NOBMI2-NEXT: movb $16, %cl 890; X64-NOBMI2-NEXT: subb %sil, %cl 891; X64-NOBMI2-NEXT: shrl %cl, %eax 892; X64-NOBMI2-NEXT: shll %cl, %eax 893; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 894; X64-NOBMI2-NEXT: retq 895; 896; X64-BMI2-LABEL: clear_lowbits16_ic0: 897; X64-BMI2: # %bb.0: 898; X64-BMI2-NEXT: movzwl %di, %eax 899; X64-BMI2-NEXT: movb $16, %cl 900; X64-BMI2-NEXT: subb %sil, %cl 901; X64-BMI2-NEXT: shrxl %ecx, %eax, %eax 902; X64-BMI2-NEXT: shlxl %ecx, %eax, %eax 903; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 904; X64-BMI2-NEXT: retq 905 %numhighbits = sub i16 16, %numlowbits 906 %mask = shl i16 -1, %numhighbits 907 %masked = and i16 %mask, %val 908 ret i16 %masked 909} 910 911define i16 @clear_lowbits16_ic1_indexzext(i16 %val, i8 %numlowbits) nounwind { 912; X86-NOBMI2-LABEL: clear_lowbits16_ic1_indexzext: 913; X86-NOBMI2: # %bb.0: 914; X86-NOBMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 915; X86-NOBMI2-NEXT: movb $16, %cl 916; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 917; X86-NOBMI2-NEXT: shrl %cl, %eax 918; X86-NOBMI2-NEXT: shll %cl, %eax 919; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 920; X86-NOBMI2-NEXT: retl 921; 922; X86-BMI2-LABEL: clear_lowbits16_ic1_indexzext: 923; X86-BMI2: # %bb.0: 924; X86-BMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 925; X86-BMI2-NEXT: movb $16, %cl 926; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 927; X86-BMI2-NEXT: shrxl %ecx, %eax, %eax 928; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 929; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 930; X86-BMI2-NEXT: retl 931; 932; X64-NOBMI2-LABEL: clear_lowbits16_ic1_indexzext: 933; X64-NOBMI2: # %bb.0: 934; X64-NOBMI2-NEXT: movzwl %di, %eax 935; X64-NOBMI2-NEXT: movb $16, %cl 936; X64-NOBMI2-NEXT: subb %sil, %cl 937; X64-NOBMI2-NEXT: shrl %cl, %eax 938; X64-NOBMI2-NEXT: shll %cl, %eax 939; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 940; X64-NOBMI2-NEXT: retq 941; 942; X64-BMI2-LABEL: clear_lowbits16_ic1_indexzext: 943; X64-BMI2: # %bb.0: 944; X64-BMI2-NEXT: movzwl %di, %eax 945; X64-BMI2-NEXT: movb $16, %cl 946; X64-BMI2-NEXT: subb %sil, %cl 947; X64-BMI2-NEXT: shrxl %ecx, %eax, %eax 948; X64-BMI2-NEXT: shlxl %ecx, %eax, %eax 949; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 950; X64-BMI2-NEXT: retq 951 %numhighbits = sub i8 16, %numlowbits 952 %sh_prom = zext i8 %numhighbits to i16 953 %mask = shl i16 -1, %sh_prom 954 %masked = and i16 %mask, %val 955 ret i16 %masked 956} 957 958define i16 @clear_lowbits16_ic2_load(i16* %w, i16 %numlowbits) nounwind { 959; X86-NOBMI2-LABEL: clear_lowbits16_ic2_load: 960; X86-NOBMI2: # %bb.0: 961; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 962; X86-NOBMI2-NEXT: movzwl (%eax), %eax 963; X86-NOBMI2-NEXT: movb $16, %cl 964; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 965; X86-NOBMI2-NEXT: shrl %cl, %eax 966; X86-NOBMI2-NEXT: shll %cl, %eax 967; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 968; X86-NOBMI2-NEXT: retl 969; 970; X86-BMI2-LABEL: clear_lowbits16_ic2_load: 971; X86-BMI2: # %bb.0: 972; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 973; X86-BMI2-NEXT: movzwl (%eax), %eax 974; X86-BMI2-NEXT: movb $16, %cl 975; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 976; X86-BMI2-NEXT: shrxl %ecx, %eax, %eax 977; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 978; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 979; X86-BMI2-NEXT: retl 980; 981; X64-NOBMI2-LABEL: clear_lowbits16_ic2_load: 982; X64-NOBMI2: # %bb.0: 983; X64-NOBMI2-NEXT: movzwl (%rdi), %eax 984; X64-NOBMI2-NEXT: movb $16, %cl 985; X64-NOBMI2-NEXT: subb %sil, %cl 986; X64-NOBMI2-NEXT: shrl %cl, %eax 987; X64-NOBMI2-NEXT: shll %cl, %eax 988; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 989; X64-NOBMI2-NEXT: retq 990; 991; X64-BMI2-LABEL: clear_lowbits16_ic2_load: 992; X64-BMI2: # %bb.0: 993; X64-BMI2-NEXT: movzwl (%rdi), %eax 994; X64-BMI2-NEXT: movb $16, %cl 995; X64-BMI2-NEXT: subb %sil, %cl 996; X64-BMI2-NEXT: shrxl %ecx, %eax, %eax 997; X64-BMI2-NEXT: shlxl %ecx, %eax, %eax 998; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 999; X64-BMI2-NEXT: retq 1000 %val = load i16, i16* %w 1001 %numhighbits = sub i16 16, %numlowbits 1002 %mask = shl i16 -1, %numhighbits 1003 %masked = and i16 %mask, %val 1004 ret i16 %masked 1005} 1006 1007define i16 @clear_lowbits16_ic3_load_indexzext(i16* %w, i8 %numlowbits) nounwind { 1008; X86-NOBMI2-LABEL: clear_lowbits16_ic3_load_indexzext: 1009; X86-NOBMI2: # %bb.0: 1010; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1011; X86-NOBMI2-NEXT: movzwl (%eax), %eax 1012; X86-NOBMI2-NEXT: movb $16, %cl 1013; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1014; X86-NOBMI2-NEXT: shrl %cl, %eax 1015; X86-NOBMI2-NEXT: shll %cl, %eax 1016; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 1017; X86-NOBMI2-NEXT: retl 1018; 1019; X86-BMI2-LABEL: clear_lowbits16_ic3_load_indexzext: 1020; X86-BMI2: # %bb.0: 1021; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1022; X86-BMI2-NEXT: movzwl (%eax), %eax 1023; X86-BMI2-NEXT: movb $16, %cl 1024; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1025; X86-BMI2-NEXT: shrxl %ecx, %eax, %eax 1026; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 1027; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 1028; X86-BMI2-NEXT: retl 1029; 1030; X64-NOBMI2-LABEL: clear_lowbits16_ic3_load_indexzext: 1031; X64-NOBMI2: # %bb.0: 1032; X64-NOBMI2-NEXT: movzwl (%rdi), %eax 1033; X64-NOBMI2-NEXT: movb $16, %cl 1034; X64-NOBMI2-NEXT: subb %sil, %cl 1035; X64-NOBMI2-NEXT: shrl %cl, %eax 1036; X64-NOBMI2-NEXT: shll %cl, %eax 1037; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 1038; X64-NOBMI2-NEXT: retq 1039; 1040; X64-BMI2-LABEL: clear_lowbits16_ic3_load_indexzext: 1041; X64-BMI2: # %bb.0: 1042; X64-BMI2-NEXT: movzwl (%rdi), %eax 1043; X64-BMI2-NEXT: movb $16, %cl 1044; X64-BMI2-NEXT: subb %sil, %cl 1045; X64-BMI2-NEXT: shrxl %ecx, %eax, %eax 1046; X64-BMI2-NEXT: shlxl %ecx, %eax, %eax 1047; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 1048; X64-BMI2-NEXT: retq 1049 %val = load i16, i16* %w 1050 %numhighbits = sub i8 16, %numlowbits 1051 %sh_prom = zext i8 %numhighbits to i16 1052 %mask = shl i16 -1, %sh_prom 1053 %masked = and i16 %mask, %val 1054 ret i16 %masked 1055} 1056 1057define i16 @clear_lowbits16_ic4_commutative(i16 %val, i16 %numlowbits) nounwind { 1058; X86-NOBMI2-LABEL: clear_lowbits16_ic4_commutative: 1059; X86-NOBMI2: # %bb.0: 1060; X86-NOBMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 1061; X86-NOBMI2-NEXT: movb $16, %cl 1062; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1063; X86-NOBMI2-NEXT: shrl %cl, %eax 1064; X86-NOBMI2-NEXT: shll %cl, %eax 1065; X86-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 1066; X86-NOBMI2-NEXT: retl 1067; 1068; X86-BMI2-LABEL: clear_lowbits16_ic4_commutative: 1069; X86-BMI2: # %bb.0: 1070; X86-BMI2-NEXT: movzwl {{[0-9]+}}(%esp), %eax 1071; X86-BMI2-NEXT: movb $16, %cl 1072; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1073; X86-BMI2-NEXT: shrxl %ecx, %eax, %eax 1074; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 1075; X86-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 1076; X86-BMI2-NEXT: retl 1077; 1078; X64-NOBMI2-LABEL: clear_lowbits16_ic4_commutative: 1079; X64-NOBMI2: # %bb.0: 1080; X64-NOBMI2-NEXT: movzwl %di, %eax 1081; X64-NOBMI2-NEXT: movb $16, %cl 1082; X64-NOBMI2-NEXT: subb %sil, %cl 1083; X64-NOBMI2-NEXT: shrl %cl, %eax 1084; X64-NOBMI2-NEXT: shll %cl, %eax 1085; X64-NOBMI2-NEXT: # kill: def $ax killed $ax killed $eax 1086; X64-NOBMI2-NEXT: retq 1087; 1088; X64-BMI2-LABEL: clear_lowbits16_ic4_commutative: 1089; X64-BMI2: # %bb.0: 1090; X64-BMI2-NEXT: movzwl %di, %eax 1091; X64-BMI2-NEXT: movb $16, %cl 1092; X64-BMI2-NEXT: subb %sil, %cl 1093; X64-BMI2-NEXT: shrxl %ecx, %eax, %eax 1094; X64-BMI2-NEXT: shlxl %ecx, %eax, %eax 1095; X64-BMI2-NEXT: # kill: def $ax killed $ax killed $eax 1096; X64-BMI2-NEXT: retq 1097 %numhighbits = sub i16 16, %numlowbits 1098 %mask = shl i16 -1, %numhighbits 1099 %masked = and i16 %val, %mask ; swapped order 1100 ret i16 %masked 1101} 1102 1103; 32-bit 1104 1105define i32 @clear_lowbits32_ic0(i32 %val, i32 %numlowbits) nounwind { 1106; X86-NOBMI2-LABEL: clear_lowbits32_ic0: 1107; X86-NOBMI2: # %bb.0: 1108; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1109; X86-NOBMI2-NEXT: xorl %ecx, %ecx 1110; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1111; X86-NOBMI2-NEXT: shrl %cl, %eax 1112; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1113; X86-NOBMI2-NEXT: shll %cl, %eax 1114; X86-NOBMI2-NEXT: retl 1115; 1116; X86-BMI2-LABEL: clear_lowbits32_ic0: 1117; X86-BMI2: # %bb.0: 1118; X86-BMI2-NEXT: xorl %eax, %eax 1119; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al 1120; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %ecx 1121; X86-BMI2-NEXT: shlxl %eax, %ecx, %eax 1122; X86-BMI2-NEXT: retl 1123; 1124; X64-NOBMI2-LABEL: clear_lowbits32_ic0: 1125; X64-NOBMI2: # %bb.0: 1126; X64-NOBMI2-NEXT: movl %esi, %ecx 1127; X64-NOBMI2-NEXT: movl %edi, %eax 1128; X64-NOBMI2-NEXT: negb %cl 1129; X64-NOBMI2-NEXT: shrl %cl, %eax 1130; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1131; X64-NOBMI2-NEXT: shll %cl, %eax 1132; X64-NOBMI2-NEXT: retq 1133; 1134; X64-BMI2-LABEL: clear_lowbits32_ic0: 1135; X64-BMI2: # %bb.0: 1136; X64-BMI2-NEXT: negb %sil 1137; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 1138; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 1139; X64-BMI2-NEXT: retq 1140 %numhighbits = sub i32 32, %numlowbits 1141 %mask = shl i32 -1, %numhighbits 1142 %masked = and i32 %mask, %val 1143 ret i32 %masked 1144} 1145 1146define i32 @clear_lowbits32_ic1_indexzext(i32 %val, i8 %numlowbits) nounwind { 1147; X86-NOBMI2-LABEL: clear_lowbits32_ic1_indexzext: 1148; X86-NOBMI2: # %bb.0: 1149; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1150; X86-NOBMI2-NEXT: xorl %ecx, %ecx 1151; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1152; X86-NOBMI2-NEXT: shrl %cl, %eax 1153; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1154; X86-NOBMI2-NEXT: shll %cl, %eax 1155; X86-NOBMI2-NEXT: retl 1156; 1157; X86-BMI2-LABEL: clear_lowbits32_ic1_indexzext: 1158; X86-BMI2: # %bb.0: 1159; X86-BMI2-NEXT: xorl %eax, %eax 1160; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al 1161; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %ecx 1162; X86-BMI2-NEXT: shlxl %eax, %ecx, %eax 1163; X86-BMI2-NEXT: retl 1164; 1165; X64-NOBMI2-LABEL: clear_lowbits32_ic1_indexzext: 1166; X64-NOBMI2: # %bb.0: 1167; X64-NOBMI2-NEXT: movl %esi, %ecx 1168; X64-NOBMI2-NEXT: movl %edi, %eax 1169; X64-NOBMI2-NEXT: negb %cl 1170; X64-NOBMI2-NEXT: shrl %cl, %eax 1171; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1172; X64-NOBMI2-NEXT: shll %cl, %eax 1173; X64-NOBMI2-NEXT: retq 1174; 1175; X64-BMI2-LABEL: clear_lowbits32_ic1_indexzext: 1176; X64-BMI2: # %bb.0: 1177; X64-BMI2-NEXT: negb %sil 1178; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 1179; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 1180; X64-BMI2-NEXT: retq 1181 %numhighbits = sub i8 32, %numlowbits 1182 %sh_prom = zext i8 %numhighbits to i32 1183 %mask = shl i32 -1, %sh_prom 1184 %masked = and i32 %mask, %val 1185 ret i32 %masked 1186} 1187 1188define i32 @clear_lowbits32_ic2_load(i32* %w, i32 %numlowbits) nounwind { 1189; X86-NOBMI2-LABEL: clear_lowbits32_ic2_load: 1190; X86-NOBMI2: # %bb.0: 1191; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1192; X86-NOBMI2-NEXT: movl (%eax), %eax 1193; X86-NOBMI2-NEXT: xorl %ecx, %ecx 1194; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1195; X86-NOBMI2-NEXT: shrl %cl, %eax 1196; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1197; X86-NOBMI2-NEXT: shll %cl, %eax 1198; X86-NOBMI2-NEXT: retl 1199; 1200; X86-BMI2-LABEL: clear_lowbits32_ic2_load: 1201; X86-BMI2: # %bb.0: 1202; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1203; X86-BMI2-NEXT: xorl %ecx, %ecx 1204; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1205; X86-BMI2-NEXT: shrxl %ecx, (%eax), %eax 1206; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 1207; X86-BMI2-NEXT: retl 1208; 1209; X64-NOBMI2-LABEL: clear_lowbits32_ic2_load: 1210; X64-NOBMI2: # %bb.0: 1211; X64-NOBMI2-NEXT: movl %esi, %ecx 1212; X64-NOBMI2-NEXT: movl (%rdi), %eax 1213; X64-NOBMI2-NEXT: negb %cl 1214; X64-NOBMI2-NEXT: shrl %cl, %eax 1215; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1216; X64-NOBMI2-NEXT: shll %cl, %eax 1217; X64-NOBMI2-NEXT: retq 1218; 1219; X64-BMI2-LABEL: clear_lowbits32_ic2_load: 1220; X64-BMI2: # %bb.0: 1221; X64-BMI2-NEXT: negb %sil 1222; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 1223; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 1224; X64-BMI2-NEXT: retq 1225 %val = load i32, i32* %w 1226 %numhighbits = sub i32 32, %numlowbits 1227 %mask = shl i32 -1, %numhighbits 1228 %masked = and i32 %mask, %val 1229 ret i32 %masked 1230} 1231 1232define i32 @clear_lowbits32_ic3_load_indexzext(i32* %w, i8 %numlowbits) nounwind { 1233; X86-NOBMI2-LABEL: clear_lowbits32_ic3_load_indexzext: 1234; X86-NOBMI2: # %bb.0: 1235; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1236; X86-NOBMI2-NEXT: movl (%eax), %eax 1237; X86-NOBMI2-NEXT: xorl %ecx, %ecx 1238; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1239; X86-NOBMI2-NEXT: shrl %cl, %eax 1240; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1241; X86-NOBMI2-NEXT: shll %cl, %eax 1242; X86-NOBMI2-NEXT: retl 1243; 1244; X86-BMI2-LABEL: clear_lowbits32_ic3_load_indexzext: 1245; X86-BMI2: # %bb.0: 1246; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1247; X86-BMI2-NEXT: xorl %ecx, %ecx 1248; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1249; X86-BMI2-NEXT: shrxl %ecx, (%eax), %eax 1250; X86-BMI2-NEXT: shlxl %ecx, %eax, %eax 1251; X86-BMI2-NEXT: retl 1252; 1253; X64-NOBMI2-LABEL: clear_lowbits32_ic3_load_indexzext: 1254; X64-NOBMI2: # %bb.0: 1255; X64-NOBMI2-NEXT: movl %esi, %ecx 1256; X64-NOBMI2-NEXT: movl (%rdi), %eax 1257; X64-NOBMI2-NEXT: negb %cl 1258; X64-NOBMI2-NEXT: shrl %cl, %eax 1259; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1260; X64-NOBMI2-NEXT: shll %cl, %eax 1261; X64-NOBMI2-NEXT: retq 1262; 1263; X64-BMI2-LABEL: clear_lowbits32_ic3_load_indexzext: 1264; X64-BMI2: # %bb.0: 1265; X64-BMI2-NEXT: negb %sil 1266; X64-BMI2-NEXT: shrxl %esi, (%rdi), %eax 1267; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 1268; X64-BMI2-NEXT: retq 1269 %val = load i32, i32* %w 1270 %numhighbits = sub i8 32, %numlowbits 1271 %sh_prom = zext i8 %numhighbits to i32 1272 %mask = shl i32 -1, %sh_prom 1273 %masked = and i32 %mask, %val 1274 ret i32 %masked 1275} 1276 1277define i32 @clear_lowbits32_ic4_commutative(i32 %val, i32 %numlowbits) nounwind { 1278; X86-NOBMI2-LABEL: clear_lowbits32_ic4_commutative: 1279; X86-NOBMI2: # %bb.0: 1280; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %eax 1281; X86-NOBMI2-NEXT: xorl %ecx, %ecx 1282; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1283; X86-NOBMI2-NEXT: shrl %cl, %eax 1284; X86-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1285; X86-NOBMI2-NEXT: shll %cl, %eax 1286; X86-NOBMI2-NEXT: retl 1287; 1288; X86-BMI2-LABEL: clear_lowbits32_ic4_commutative: 1289; X86-BMI2: # %bb.0: 1290; X86-BMI2-NEXT: xorl %eax, %eax 1291; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %al 1292; X86-BMI2-NEXT: shrxl %eax, {{[0-9]+}}(%esp), %ecx 1293; X86-BMI2-NEXT: shlxl %eax, %ecx, %eax 1294; X86-BMI2-NEXT: retl 1295; 1296; X64-NOBMI2-LABEL: clear_lowbits32_ic4_commutative: 1297; X64-NOBMI2: # %bb.0: 1298; X64-NOBMI2-NEXT: movl %esi, %ecx 1299; X64-NOBMI2-NEXT: movl %edi, %eax 1300; X64-NOBMI2-NEXT: negb %cl 1301; X64-NOBMI2-NEXT: shrl %cl, %eax 1302; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1303; X64-NOBMI2-NEXT: shll %cl, %eax 1304; X64-NOBMI2-NEXT: retq 1305; 1306; X64-BMI2-LABEL: clear_lowbits32_ic4_commutative: 1307; X64-BMI2: # %bb.0: 1308; X64-BMI2-NEXT: negb %sil 1309; X64-BMI2-NEXT: shrxl %esi, %edi, %eax 1310; X64-BMI2-NEXT: shlxl %esi, %eax, %eax 1311; X64-BMI2-NEXT: retq 1312 %numhighbits = sub i32 32, %numlowbits 1313 %mask = shl i32 -1, %numhighbits 1314 %masked = and i32 %val, %mask ; swapped order 1315 ret i32 %masked 1316} 1317 1318; 64-bit 1319 1320define i64 @clear_lowbits64_ic0(i64 %val, i64 %numlowbits) nounwind { 1321; X86-NOBMI2-LABEL: clear_lowbits64_ic0: 1322; X86-NOBMI2: # %bb.0: 1323; X86-NOBMI2-NEXT: movb $64, %cl 1324; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1325; X86-NOBMI2-NEXT: movl $-1, %edx 1326; X86-NOBMI2-NEXT: movl $-1, %eax 1327; X86-NOBMI2-NEXT: shll %cl, %eax 1328; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 1329; X86-NOBMI2-NEXT: testb $32, %cl 1330; X86-NOBMI2-NEXT: je .LBB31_2 1331; X86-NOBMI2-NEXT: # %bb.1: 1332; X86-NOBMI2-NEXT: movl %eax, %edx 1333; X86-NOBMI2-NEXT: xorl %eax, %eax 1334; X86-NOBMI2-NEXT: .LBB31_2: 1335; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 1336; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 1337; X86-NOBMI2-NEXT: retl 1338; 1339; X86-BMI2-LABEL: clear_lowbits64_ic0: 1340; X86-BMI2: # %bb.0: 1341; X86-BMI2-NEXT: movb $64, %cl 1342; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1343; X86-BMI2-NEXT: movl $-1, %edx 1344; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 1345; X86-BMI2-NEXT: shldl %cl, %edx, %edx 1346; X86-BMI2-NEXT: testb $32, %cl 1347; X86-BMI2-NEXT: je .LBB31_2 1348; X86-BMI2-NEXT: # %bb.1: 1349; X86-BMI2-NEXT: movl %eax, %edx 1350; X86-BMI2-NEXT: xorl %eax, %eax 1351; X86-BMI2-NEXT: .LBB31_2: 1352; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 1353; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 1354; X86-BMI2-NEXT: retl 1355; 1356; X64-NOBMI2-LABEL: clear_lowbits64_ic0: 1357; X64-NOBMI2: # %bb.0: 1358; X64-NOBMI2-NEXT: movq %rsi, %rcx 1359; X64-NOBMI2-NEXT: movq %rdi, %rax 1360; X64-NOBMI2-NEXT: negb %cl 1361; X64-NOBMI2-NEXT: shrq %cl, %rax 1362; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx 1363; X64-NOBMI2-NEXT: shlq %cl, %rax 1364; X64-NOBMI2-NEXT: retq 1365; 1366; X64-BMI2-LABEL: clear_lowbits64_ic0: 1367; X64-BMI2: # %bb.0: 1368; X64-BMI2-NEXT: negb %sil 1369; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 1370; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 1371; X64-BMI2-NEXT: retq 1372 %numhighbits = sub i64 64, %numlowbits 1373 %mask = shl i64 -1, %numhighbits 1374 %masked = and i64 %mask, %val 1375 ret i64 %masked 1376} 1377 1378define i64 @clear_lowbits64_ic1_indexzext(i64 %val, i8 %numlowbits) nounwind { 1379; X86-NOBMI2-LABEL: clear_lowbits64_ic1_indexzext: 1380; X86-NOBMI2: # %bb.0: 1381; X86-NOBMI2-NEXT: movb $64, %cl 1382; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1383; X86-NOBMI2-NEXT: movl $-1, %edx 1384; X86-NOBMI2-NEXT: movl $-1, %eax 1385; X86-NOBMI2-NEXT: shll %cl, %eax 1386; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 1387; X86-NOBMI2-NEXT: testb $32, %cl 1388; X86-NOBMI2-NEXT: je .LBB32_2 1389; X86-NOBMI2-NEXT: # %bb.1: 1390; X86-NOBMI2-NEXT: movl %eax, %edx 1391; X86-NOBMI2-NEXT: xorl %eax, %eax 1392; X86-NOBMI2-NEXT: .LBB32_2: 1393; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 1394; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 1395; X86-NOBMI2-NEXT: retl 1396; 1397; X86-BMI2-LABEL: clear_lowbits64_ic1_indexzext: 1398; X86-BMI2: # %bb.0: 1399; X86-BMI2-NEXT: movb $64, %cl 1400; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1401; X86-BMI2-NEXT: movl $-1, %edx 1402; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 1403; X86-BMI2-NEXT: shldl %cl, %edx, %edx 1404; X86-BMI2-NEXT: testb $32, %cl 1405; X86-BMI2-NEXT: je .LBB32_2 1406; X86-BMI2-NEXT: # %bb.1: 1407; X86-BMI2-NEXT: movl %eax, %edx 1408; X86-BMI2-NEXT: xorl %eax, %eax 1409; X86-BMI2-NEXT: .LBB32_2: 1410; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 1411; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 1412; X86-BMI2-NEXT: retl 1413; 1414; X64-NOBMI2-LABEL: clear_lowbits64_ic1_indexzext: 1415; X64-NOBMI2: # %bb.0: 1416; X64-NOBMI2-NEXT: movl %esi, %ecx 1417; X64-NOBMI2-NEXT: movq %rdi, %rax 1418; X64-NOBMI2-NEXT: negb %cl 1419; X64-NOBMI2-NEXT: shrq %cl, %rax 1420; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1421; X64-NOBMI2-NEXT: shlq %cl, %rax 1422; X64-NOBMI2-NEXT: retq 1423; 1424; X64-BMI2-LABEL: clear_lowbits64_ic1_indexzext: 1425; X64-BMI2: # %bb.0: 1426; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 1427; X64-BMI2-NEXT: negb %sil 1428; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 1429; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 1430; X64-BMI2-NEXT: retq 1431 %numhighbits = sub i8 64, %numlowbits 1432 %sh_prom = zext i8 %numhighbits to i64 1433 %mask = shl i64 -1, %sh_prom 1434 %masked = and i64 %mask, %val 1435 ret i64 %masked 1436} 1437 1438define i64 @clear_lowbits64_ic2_load(i64* %w, i64 %numlowbits) nounwind { 1439; X86-NOBMI2-LABEL: clear_lowbits64_ic2_load: 1440; X86-NOBMI2: # %bb.0: 1441; X86-NOBMI2-NEXT: pushl %esi 1442; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 1443; X86-NOBMI2-NEXT: movb $64, %cl 1444; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1445; X86-NOBMI2-NEXT: movl $-1, %edx 1446; X86-NOBMI2-NEXT: movl $-1, %eax 1447; X86-NOBMI2-NEXT: shll %cl, %eax 1448; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 1449; X86-NOBMI2-NEXT: testb $32, %cl 1450; X86-NOBMI2-NEXT: je .LBB33_2 1451; X86-NOBMI2-NEXT: # %bb.1: 1452; X86-NOBMI2-NEXT: movl %eax, %edx 1453; X86-NOBMI2-NEXT: xorl %eax, %eax 1454; X86-NOBMI2-NEXT: .LBB33_2: 1455; X86-NOBMI2-NEXT: andl 4(%esi), %edx 1456; X86-NOBMI2-NEXT: andl (%esi), %eax 1457; X86-NOBMI2-NEXT: popl %esi 1458; X86-NOBMI2-NEXT: retl 1459; 1460; X86-BMI2-LABEL: clear_lowbits64_ic2_load: 1461; X86-BMI2: # %bb.0: 1462; X86-BMI2-NEXT: pushl %esi 1463; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 1464; X86-BMI2-NEXT: movb $64, %cl 1465; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1466; X86-BMI2-NEXT: movl $-1, %edx 1467; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 1468; X86-BMI2-NEXT: shldl %cl, %edx, %edx 1469; X86-BMI2-NEXT: testb $32, %cl 1470; X86-BMI2-NEXT: je .LBB33_2 1471; X86-BMI2-NEXT: # %bb.1: 1472; X86-BMI2-NEXT: movl %eax, %edx 1473; X86-BMI2-NEXT: xorl %eax, %eax 1474; X86-BMI2-NEXT: .LBB33_2: 1475; X86-BMI2-NEXT: andl 4(%esi), %edx 1476; X86-BMI2-NEXT: andl (%esi), %eax 1477; X86-BMI2-NEXT: popl %esi 1478; X86-BMI2-NEXT: retl 1479; 1480; X64-NOBMI2-LABEL: clear_lowbits64_ic2_load: 1481; X64-NOBMI2: # %bb.0: 1482; X64-NOBMI2-NEXT: movq %rsi, %rcx 1483; X64-NOBMI2-NEXT: movq (%rdi), %rax 1484; X64-NOBMI2-NEXT: negb %cl 1485; X64-NOBMI2-NEXT: shrq %cl, %rax 1486; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx 1487; X64-NOBMI2-NEXT: shlq %cl, %rax 1488; X64-NOBMI2-NEXT: retq 1489; 1490; X64-BMI2-LABEL: clear_lowbits64_ic2_load: 1491; X64-BMI2: # %bb.0: 1492; X64-BMI2-NEXT: negb %sil 1493; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 1494; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 1495; X64-BMI2-NEXT: retq 1496 %val = load i64, i64* %w 1497 %numhighbits = sub i64 64, %numlowbits 1498 %mask = shl i64 -1, %numhighbits 1499 %masked = and i64 %mask, %val 1500 ret i64 %masked 1501} 1502 1503define i64 @clear_lowbits64_ic3_load_indexzext(i64* %w, i8 %numlowbits) nounwind { 1504; X86-NOBMI2-LABEL: clear_lowbits64_ic3_load_indexzext: 1505; X86-NOBMI2: # %bb.0: 1506; X86-NOBMI2-NEXT: pushl %esi 1507; X86-NOBMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 1508; X86-NOBMI2-NEXT: movb $64, %cl 1509; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1510; X86-NOBMI2-NEXT: movl $-1, %edx 1511; X86-NOBMI2-NEXT: movl $-1, %eax 1512; X86-NOBMI2-NEXT: shll %cl, %eax 1513; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 1514; X86-NOBMI2-NEXT: testb $32, %cl 1515; X86-NOBMI2-NEXT: je .LBB34_2 1516; X86-NOBMI2-NEXT: # %bb.1: 1517; X86-NOBMI2-NEXT: movl %eax, %edx 1518; X86-NOBMI2-NEXT: xorl %eax, %eax 1519; X86-NOBMI2-NEXT: .LBB34_2: 1520; X86-NOBMI2-NEXT: andl 4(%esi), %edx 1521; X86-NOBMI2-NEXT: andl (%esi), %eax 1522; X86-NOBMI2-NEXT: popl %esi 1523; X86-NOBMI2-NEXT: retl 1524; 1525; X86-BMI2-LABEL: clear_lowbits64_ic3_load_indexzext: 1526; X86-BMI2: # %bb.0: 1527; X86-BMI2-NEXT: pushl %esi 1528; X86-BMI2-NEXT: movl {{[0-9]+}}(%esp), %esi 1529; X86-BMI2-NEXT: movb $64, %cl 1530; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1531; X86-BMI2-NEXT: movl $-1, %edx 1532; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 1533; X86-BMI2-NEXT: shldl %cl, %edx, %edx 1534; X86-BMI2-NEXT: testb $32, %cl 1535; X86-BMI2-NEXT: je .LBB34_2 1536; X86-BMI2-NEXT: # %bb.1: 1537; X86-BMI2-NEXT: movl %eax, %edx 1538; X86-BMI2-NEXT: xorl %eax, %eax 1539; X86-BMI2-NEXT: .LBB34_2: 1540; X86-BMI2-NEXT: andl 4(%esi), %edx 1541; X86-BMI2-NEXT: andl (%esi), %eax 1542; X86-BMI2-NEXT: popl %esi 1543; X86-BMI2-NEXT: retl 1544; 1545; X64-NOBMI2-LABEL: clear_lowbits64_ic3_load_indexzext: 1546; X64-NOBMI2: # %bb.0: 1547; X64-NOBMI2-NEXT: movl %esi, %ecx 1548; X64-NOBMI2-NEXT: movq (%rdi), %rax 1549; X64-NOBMI2-NEXT: negb %cl 1550; X64-NOBMI2-NEXT: shrq %cl, %rax 1551; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1552; X64-NOBMI2-NEXT: shlq %cl, %rax 1553; X64-NOBMI2-NEXT: retq 1554; 1555; X64-BMI2-LABEL: clear_lowbits64_ic3_load_indexzext: 1556; X64-BMI2: # %bb.0: 1557; X64-BMI2-NEXT: # kill: def $esi killed $esi def $rsi 1558; X64-BMI2-NEXT: negb %sil 1559; X64-BMI2-NEXT: shrxq %rsi, (%rdi), %rax 1560; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 1561; X64-BMI2-NEXT: retq 1562 %val = load i64, i64* %w 1563 %numhighbits = sub i8 64, %numlowbits 1564 %sh_prom = zext i8 %numhighbits to i64 1565 %mask = shl i64 -1, %sh_prom 1566 %masked = and i64 %mask, %val 1567 ret i64 %masked 1568} 1569 1570define i64 @clear_lowbits64_ic4_commutative(i64 %val, i64 %numlowbits) nounwind { 1571; X86-NOBMI2-LABEL: clear_lowbits64_ic4_commutative: 1572; X86-NOBMI2: # %bb.0: 1573; X86-NOBMI2-NEXT: movb $64, %cl 1574; X86-NOBMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1575; X86-NOBMI2-NEXT: movl $-1, %edx 1576; X86-NOBMI2-NEXT: movl $-1, %eax 1577; X86-NOBMI2-NEXT: shll %cl, %eax 1578; X86-NOBMI2-NEXT: shldl %cl, %edx, %edx 1579; X86-NOBMI2-NEXT: testb $32, %cl 1580; X86-NOBMI2-NEXT: je .LBB35_2 1581; X86-NOBMI2-NEXT: # %bb.1: 1582; X86-NOBMI2-NEXT: movl %eax, %edx 1583; X86-NOBMI2-NEXT: xorl %eax, %eax 1584; X86-NOBMI2-NEXT: .LBB35_2: 1585; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 1586; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 1587; X86-NOBMI2-NEXT: retl 1588; 1589; X86-BMI2-LABEL: clear_lowbits64_ic4_commutative: 1590; X86-BMI2: # %bb.0: 1591; X86-BMI2-NEXT: movb $64, %cl 1592; X86-BMI2-NEXT: subb {{[0-9]+}}(%esp), %cl 1593; X86-BMI2-NEXT: movl $-1, %edx 1594; X86-BMI2-NEXT: shlxl %ecx, %edx, %eax 1595; X86-BMI2-NEXT: shldl %cl, %edx, %edx 1596; X86-BMI2-NEXT: testb $32, %cl 1597; X86-BMI2-NEXT: je .LBB35_2 1598; X86-BMI2-NEXT: # %bb.1: 1599; X86-BMI2-NEXT: movl %eax, %edx 1600; X86-BMI2-NEXT: xorl %eax, %eax 1601; X86-BMI2-NEXT: .LBB35_2: 1602; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edx 1603; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %eax 1604; X86-BMI2-NEXT: retl 1605; 1606; X64-NOBMI2-LABEL: clear_lowbits64_ic4_commutative: 1607; X64-NOBMI2: # %bb.0: 1608; X64-NOBMI2-NEXT: movq %rsi, %rcx 1609; X64-NOBMI2-NEXT: movq %rdi, %rax 1610; X64-NOBMI2-NEXT: negb %cl 1611; X64-NOBMI2-NEXT: shrq %cl, %rax 1612; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx 1613; X64-NOBMI2-NEXT: shlq %cl, %rax 1614; X64-NOBMI2-NEXT: retq 1615; 1616; X64-BMI2-LABEL: clear_lowbits64_ic4_commutative: 1617; X64-BMI2: # %bb.0: 1618; X64-BMI2-NEXT: negb %sil 1619; X64-BMI2-NEXT: shrxq %rsi, %rdi, %rax 1620; X64-BMI2-NEXT: shlxq %rsi, %rax, %rax 1621; X64-BMI2-NEXT: retq 1622 %numhighbits = sub i64 64, %numlowbits 1623 %mask = shl i64 -1, %numhighbits 1624 %masked = and i64 %val, %mask ; swapped order 1625 ret i64 %masked 1626} 1627 1628; ---------------------------------------------------------------------------- ; 1629; Multi-use tests 1630; ---------------------------------------------------------------------------- ; 1631 1632declare void @use32(i32) 1633declare void @use64(i64) 1634 1635define i32 @oneuse32(i32 %val, i32 %numlowbits) nounwind { 1636; X86-NOBMI2-LABEL: oneuse32: 1637; X86-NOBMI2: # %bb.0: 1638; X86-NOBMI2-NEXT: pushl %esi 1639; X86-NOBMI2-NEXT: subl $8, %esp 1640; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1641; X86-NOBMI2-NEXT: movl $-1, %esi 1642; X86-NOBMI2-NEXT: shll %cl, %esi 1643; X86-NOBMI2-NEXT: movl %esi, (%esp) 1644; X86-NOBMI2-NEXT: calll use32 1645; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %esi 1646; X86-NOBMI2-NEXT: movl %esi, %eax 1647; X86-NOBMI2-NEXT: addl $8, %esp 1648; X86-NOBMI2-NEXT: popl %esi 1649; X86-NOBMI2-NEXT: retl 1650; 1651; X86-BMI2-LABEL: oneuse32: 1652; X86-BMI2: # %bb.0: 1653; X86-BMI2-NEXT: pushl %esi 1654; X86-BMI2-NEXT: subl $8, %esp 1655; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %al 1656; X86-BMI2-NEXT: movl $-1, %ecx 1657; X86-BMI2-NEXT: shlxl %eax, %ecx, %esi 1658; X86-BMI2-NEXT: movl %esi, (%esp) 1659; X86-BMI2-NEXT: calll use32 1660; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %esi 1661; X86-BMI2-NEXT: movl %esi, %eax 1662; X86-BMI2-NEXT: addl $8, %esp 1663; X86-BMI2-NEXT: popl %esi 1664; X86-BMI2-NEXT: retl 1665; 1666; X64-NOBMI2-LABEL: oneuse32: 1667; X64-NOBMI2: # %bb.0: 1668; X64-NOBMI2-NEXT: pushq %rbp 1669; X64-NOBMI2-NEXT: pushq %rbx 1670; X64-NOBMI2-NEXT: pushq %rax 1671; X64-NOBMI2-NEXT: movl %esi, %ecx 1672; X64-NOBMI2-NEXT: movl %edi, %ebx 1673; X64-NOBMI2-NEXT: movl $-1, %ebp 1674; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $ecx 1675; X64-NOBMI2-NEXT: shll %cl, %ebp 1676; X64-NOBMI2-NEXT: movl %ebp, %edi 1677; X64-NOBMI2-NEXT: callq use32 1678; X64-NOBMI2-NEXT: andl %ebx, %ebp 1679; X64-NOBMI2-NEXT: movl %ebp, %eax 1680; X64-NOBMI2-NEXT: addq $8, %rsp 1681; X64-NOBMI2-NEXT: popq %rbx 1682; X64-NOBMI2-NEXT: popq %rbp 1683; X64-NOBMI2-NEXT: retq 1684; 1685; X64-BMI2-LABEL: oneuse32: 1686; X64-BMI2: # %bb.0: 1687; X64-BMI2-NEXT: pushq %rbp 1688; X64-BMI2-NEXT: pushq %rbx 1689; X64-BMI2-NEXT: pushq %rax 1690; X64-BMI2-NEXT: movl %edi, %ebx 1691; X64-BMI2-NEXT: movl $-1, %eax 1692; X64-BMI2-NEXT: shlxl %esi, %eax, %ebp 1693; X64-BMI2-NEXT: movl %ebp, %edi 1694; X64-BMI2-NEXT: callq use32 1695; X64-BMI2-NEXT: andl %ebx, %ebp 1696; X64-BMI2-NEXT: movl %ebp, %eax 1697; X64-BMI2-NEXT: addq $8, %rsp 1698; X64-BMI2-NEXT: popq %rbx 1699; X64-BMI2-NEXT: popq %rbp 1700; X64-BMI2-NEXT: retq 1701 %mask = shl i32 -1, %numlowbits 1702 call void @use32(i32 %mask) 1703 %masked = and i32 %mask, %val 1704 ret i32 %masked 1705} 1706 1707define i64 @oneuse64(i64 %val, i64 %numlowbits) nounwind { 1708; X86-NOBMI2-LABEL: oneuse64: 1709; X86-NOBMI2: # %bb.0: 1710; X86-NOBMI2-NEXT: pushl %edi 1711; X86-NOBMI2-NEXT: pushl %esi 1712; X86-NOBMI2-NEXT: pushl %eax 1713; X86-NOBMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1714; X86-NOBMI2-NEXT: movl $-1, %esi 1715; X86-NOBMI2-NEXT: movl $-1, %edi 1716; X86-NOBMI2-NEXT: shll %cl, %edi 1717; X86-NOBMI2-NEXT: shldl %cl, %esi, %esi 1718; X86-NOBMI2-NEXT: testb $32, %cl 1719; X86-NOBMI2-NEXT: je .LBB37_2 1720; X86-NOBMI2-NEXT: # %bb.1: 1721; X86-NOBMI2-NEXT: movl %edi, %esi 1722; X86-NOBMI2-NEXT: xorl %edi, %edi 1723; X86-NOBMI2-NEXT: .LBB37_2: 1724; X86-NOBMI2-NEXT: subl $8, %esp 1725; X86-NOBMI2-NEXT: pushl %esi 1726; X86-NOBMI2-NEXT: pushl %edi 1727; X86-NOBMI2-NEXT: calll use64 1728; X86-NOBMI2-NEXT: addl $16, %esp 1729; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %esi 1730; X86-NOBMI2-NEXT: andl {{[0-9]+}}(%esp), %edi 1731; X86-NOBMI2-NEXT: movl %edi, %eax 1732; X86-NOBMI2-NEXT: movl %esi, %edx 1733; X86-NOBMI2-NEXT: addl $4, %esp 1734; X86-NOBMI2-NEXT: popl %esi 1735; X86-NOBMI2-NEXT: popl %edi 1736; X86-NOBMI2-NEXT: retl 1737; 1738; X86-BMI2-LABEL: oneuse64: 1739; X86-BMI2: # %bb.0: 1740; X86-BMI2-NEXT: pushl %edi 1741; X86-BMI2-NEXT: pushl %esi 1742; X86-BMI2-NEXT: pushl %eax 1743; X86-BMI2-NEXT: movb {{[0-9]+}}(%esp), %cl 1744; X86-BMI2-NEXT: movl $-1, %esi 1745; X86-BMI2-NEXT: shlxl %ecx, %esi, %edi 1746; X86-BMI2-NEXT: shldl %cl, %esi, %esi 1747; X86-BMI2-NEXT: testb $32, %cl 1748; X86-BMI2-NEXT: je .LBB37_2 1749; X86-BMI2-NEXT: # %bb.1: 1750; X86-BMI2-NEXT: movl %edi, %esi 1751; X86-BMI2-NEXT: xorl %edi, %edi 1752; X86-BMI2-NEXT: .LBB37_2: 1753; X86-BMI2-NEXT: subl $8, %esp 1754; X86-BMI2-NEXT: pushl %esi 1755; X86-BMI2-NEXT: pushl %edi 1756; X86-BMI2-NEXT: calll use64 1757; X86-BMI2-NEXT: addl $16, %esp 1758; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %esi 1759; X86-BMI2-NEXT: andl {{[0-9]+}}(%esp), %edi 1760; X86-BMI2-NEXT: movl %edi, %eax 1761; X86-BMI2-NEXT: movl %esi, %edx 1762; X86-BMI2-NEXT: addl $4, %esp 1763; X86-BMI2-NEXT: popl %esi 1764; X86-BMI2-NEXT: popl %edi 1765; X86-BMI2-NEXT: retl 1766; 1767; X64-NOBMI2-LABEL: oneuse64: 1768; X64-NOBMI2: # %bb.0: 1769; X64-NOBMI2-NEXT: pushq %r14 1770; X64-NOBMI2-NEXT: pushq %rbx 1771; X64-NOBMI2-NEXT: pushq %rax 1772; X64-NOBMI2-NEXT: movq %rsi, %rcx 1773; X64-NOBMI2-NEXT: movq %rdi, %r14 1774; X64-NOBMI2-NEXT: movq $-1, %rbx 1775; X64-NOBMI2-NEXT: # kill: def $cl killed $cl killed $rcx 1776; X64-NOBMI2-NEXT: shlq %cl, %rbx 1777; X64-NOBMI2-NEXT: movq %rbx, %rdi 1778; X64-NOBMI2-NEXT: callq use64 1779; X64-NOBMI2-NEXT: andq %r14, %rbx 1780; X64-NOBMI2-NEXT: movq %rbx, %rax 1781; X64-NOBMI2-NEXT: addq $8, %rsp 1782; X64-NOBMI2-NEXT: popq %rbx 1783; X64-NOBMI2-NEXT: popq %r14 1784; X64-NOBMI2-NEXT: retq 1785; 1786; X64-BMI2-LABEL: oneuse64: 1787; X64-BMI2: # %bb.0: 1788; X64-BMI2-NEXT: pushq %r14 1789; X64-BMI2-NEXT: pushq %rbx 1790; X64-BMI2-NEXT: pushq %rax 1791; X64-BMI2-NEXT: movq %rdi, %r14 1792; X64-BMI2-NEXT: movq $-1, %rax 1793; X64-BMI2-NEXT: shlxq %rsi, %rax, %rbx 1794; X64-BMI2-NEXT: movq %rbx, %rdi 1795; X64-BMI2-NEXT: callq use64 1796; X64-BMI2-NEXT: andq %r14, %rbx 1797; X64-BMI2-NEXT: movq %rbx, %rax 1798; X64-BMI2-NEXT: addq $8, %rsp 1799; X64-BMI2-NEXT: popq %rbx 1800; X64-BMI2-NEXT: popq %r14 1801; X64-BMI2-NEXT: retq 1802 %mask = shl i64 -1, %numlowbits 1803 call void @use64(i64 %mask) 1804 %masked = and i64 %mask, %val 1805 ret i64 %masked 1806} 1807