1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=-popcnt | FileCheck %s --check-prefixes=X86,X86-NOPOPCNT 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=-popcnt | FileCheck %s --check-prefixes=X64,X64-NOPOPCNT 4; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+popcnt | FileCheck %s --check-prefixes=X86,X86-POPCNT 5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+popcnt | FileCheck %s --check-prefixes=X64,X64-POPCNT 6 7define i4 @parity_4(i4 %x) { 8; X86-LABEL: parity_4: 9; X86: # %bb.0: 10; X86-NEXT: testb $15, {{[0-9]+}}(%esp) 11; X86-NEXT: setnp %al 12; X86-NEXT: retl 13; 14; X64-LABEL: parity_4: 15; X64: # %bb.0: 16; X64-NEXT: testb $15, %dil 17; X64-NEXT: setnp %al 18; X64-NEXT: retq 19 %1 = tail call i4 @llvm.ctpop.i4(i4 %x) 20 %2 = and i4 %1, 1 21 ret i4 %2 22} 23 24define i8 @parity_8(i8 %x) { 25; X86-LABEL: parity_8: 26; X86: # %bb.0: 27; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) 28; X86-NEXT: setnp %al 29; X86-NEXT: retl 30; 31; X64-LABEL: parity_8: 32; X64: # %bb.0: 33; X64-NEXT: testb %dil, %dil 34; X64-NEXT: setnp %al 35; X64-NEXT: retq 36 %1 = tail call i8 @llvm.ctpop.i8(i8 %x) 37 %2 = and i8 %1, 1 38 ret i8 %2 39} 40 41define i16 @parity_16(i16 %x) { 42; X86-NOPOPCNT-LABEL: parity_16: 43; X86-NOPOPCNT: # %bb.0: 44; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %ecx 45; X86-NOPOPCNT-NEXT: xorl %eax, %eax 46; X86-NOPOPCNT-NEXT: xorb %ch, %cl 47; X86-NOPOPCNT-NEXT: setnp %al 48; X86-NOPOPCNT-NEXT: # kill: def $ax killed $ax killed $eax 49; X86-NOPOPCNT-NEXT: retl 50; 51; X64-NOPOPCNT-LABEL: parity_16: 52; X64-NOPOPCNT: # %bb.0: 53; X64-NOPOPCNT-NEXT: movl %edi, %ecx 54; X64-NOPOPCNT-NEXT: xorl %eax, %eax 55; X64-NOPOPCNT-NEXT: xorb %ch, %cl 56; X64-NOPOPCNT-NEXT: setnp %al 57; X64-NOPOPCNT-NEXT: # kill: def $ax killed $ax killed $eax 58; X64-NOPOPCNT-NEXT: retq 59; 60; X86-POPCNT-LABEL: parity_16: 61; X86-POPCNT: # %bb.0: 62; X86-POPCNT-NEXT: movzwl {{[0-9]+}}(%esp), %eax 63; X86-POPCNT-NEXT: popcntl %eax, %eax 64; X86-POPCNT-NEXT: andl $1, %eax 65; X86-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax 66; X86-POPCNT-NEXT: retl 67; 68; X64-POPCNT-LABEL: parity_16: 69; X64-POPCNT: # %bb.0: 70; X64-POPCNT-NEXT: movzwl %di, %eax 71; X64-POPCNT-NEXT: popcntl %eax, %eax 72; X64-POPCNT-NEXT: andl $1, %eax 73; X64-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax 74; X64-POPCNT-NEXT: retq 75 %1 = tail call i16 @llvm.ctpop.i16(i16 %x) 76 %2 = and i16 %1, 1 77 ret i16 %2 78} 79 80define i16 @parity_16_load(ptr %x) { 81; X86-NOPOPCNT-LABEL: parity_16_load: 82; X86-NOPOPCNT: # %bb.0: 83; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 84; X86-NOPOPCNT-NEXT: movzwl (%eax), %ecx 85; X86-NOPOPCNT-NEXT: xorl %eax, %eax 86; X86-NOPOPCNT-NEXT: xorb %ch, %cl 87; X86-NOPOPCNT-NEXT: setnp %al 88; X86-NOPOPCNT-NEXT: # kill: def $ax killed $ax killed $eax 89; X86-NOPOPCNT-NEXT: retl 90; 91; X64-NOPOPCNT-LABEL: parity_16_load: 92; X64-NOPOPCNT: # %bb.0: 93; X64-NOPOPCNT-NEXT: movzwl (%rdi), %ecx 94; X64-NOPOPCNT-NEXT: xorl %eax, %eax 95; X64-NOPOPCNT-NEXT: xorb %ch, %cl 96; X64-NOPOPCNT-NEXT: setnp %al 97; X64-NOPOPCNT-NEXT: # kill: def $ax killed $ax killed $eax 98; X64-NOPOPCNT-NEXT: retq 99; 100; X86-POPCNT-LABEL: parity_16_load: 101; X86-POPCNT: # %bb.0: 102; X86-POPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 103; X86-POPCNT-NEXT: movzwl (%eax), %eax 104; X86-POPCNT-NEXT: popcntl %eax, %eax 105; X86-POPCNT-NEXT: andl $1, %eax 106; X86-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax 107; X86-POPCNT-NEXT: retl 108; 109; X64-POPCNT-LABEL: parity_16_load: 110; X64-POPCNT: # %bb.0: 111; X64-POPCNT-NEXT: movzwl (%rdi), %eax 112; X64-POPCNT-NEXT: popcntl %eax, %eax 113; X64-POPCNT-NEXT: andl $1, %eax 114; X64-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax 115; X64-POPCNT-NEXT: retq 116 %1 = load i16, ptr %x 117 %2 = tail call i16 @llvm.ctpop.i16(i16 %1) 118 %3 = and i16 %2, 1 119 ret i16 %3 120} 121 122define i17 @parity_17(i17 %x) { 123; X86-NOPOPCNT-LABEL: parity_17: 124; X86-NOPOPCNT: # %bb.0: 125; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %ecx 126; X86-NOPOPCNT-NEXT: movl %ecx, %eax 127; X86-NOPOPCNT-NEXT: andl $131071, %eax # imm = 0x1FFFF 128; X86-NOPOPCNT-NEXT: movl %eax, %edx 129; X86-NOPOPCNT-NEXT: shrl $16, %edx 130; X86-NOPOPCNT-NEXT: xorl %eax, %edx 131; X86-NOPOPCNT-NEXT: xorl %eax, %eax 132; X86-NOPOPCNT-NEXT: xorb %dl, %ch 133; X86-NOPOPCNT-NEXT: setnp %al 134; X86-NOPOPCNT-NEXT: retl 135; 136; X64-NOPOPCNT-LABEL: parity_17: 137; X64-NOPOPCNT: # %bb.0: 138; X64-NOPOPCNT-NEXT: movl %edi, %eax 139; X64-NOPOPCNT-NEXT: andl $131071, %eax # imm = 0x1FFFF 140; X64-NOPOPCNT-NEXT: movl %eax, %ecx 141; X64-NOPOPCNT-NEXT: shrl $16, %ecx 142; X64-NOPOPCNT-NEXT: xorl %eax, %ecx 143; X64-NOPOPCNT-NEXT: shrl $8, %edi 144; X64-NOPOPCNT-NEXT: xorl %eax, %eax 145; X64-NOPOPCNT-NEXT: xorb %cl, %dil 146; X64-NOPOPCNT-NEXT: setnp %al 147; X64-NOPOPCNT-NEXT: retq 148; 149; X86-POPCNT-LABEL: parity_17: 150; X86-POPCNT: # %bb.0: 151; X86-POPCNT-NEXT: movl $131071, %eax # imm = 0x1FFFF 152; X86-POPCNT-NEXT: andl {{[0-9]+}}(%esp), %eax 153; X86-POPCNT-NEXT: popcntl %eax, %eax 154; X86-POPCNT-NEXT: andl $1, %eax 155; X86-POPCNT-NEXT: retl 156; 157; X64-POPCNT-LABEL: parity_17: 158; X64-POPCNT: # %bb.0: 159; X64-POPCNT-NEXT: andl $131071, %edi # imm = 0x1FFFF 160; X64-POPCNT-NEXT: popcntl %edi, %eax 161; X64-POPCNT-NEXT: andl $1, %eax 162; X64-POPCNT-NEXT: retq 163 %1 = tail call i17 @llvm.ctpop.i17(i17 %x) 164 %2 = and i17 %1, 1 165 ret i17 %2 166} 167 168define i32 @parity_32(i32 %x) { 169; X86-NOPOPCNT-LABEL: parity_32: 170; X86-NOPOPCNT: # %bb.0: 171; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 172; X86-NOPOPCNT-NEXT: movl %eax, %ecx 173; X86-NOPOPCNT-NEXT: shrl $16, %ecx 174; X86-NOPOPCNT-NEXT: xorl %eax, %ecx 175; X86-NOPOPCNT-NEXT: xorl %eax, %eax 176; X86-NOPOPCNT-NEXT: xorb %ch, %cl 177; X86-NOPOPCNT-NEXT: setnp %al 178; X86-NOPOPCNT-NEXT: retl 179; 180; X64-NOPOPCNT-LABEL: parity_32: 181; X64-NOPOPCNT: # %bb.0: 182; X64-NOPOPCNT-NEXT: movl %edi, %ecx 183; X64-NOPOPCNT-NEXT: shrl $16, %ecx 184; X64-NOPOPCNT-NEXT: xorl %edi, %ecx 185; X64-NOPOPCNT-NEXT: xorl %eax, %eax 186; X64-NOPOPCNT-NEXT: xorb %ch, %cl 187; X64-NOPOPCNT-NEXT: setnp %al 188; X64-NOPOPCNT-NEXT: retq 189; 190; X86-POPCNT-LABEL: parity_32: 191; X86-POPCNT: # %bb.0: 192; X86-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %eax 193; X86-POPCNT-NEXT: andl $1, %eax 194; X86-POPCNT-NEXT: retl 195; 196; X64-POPCNT-LABEL: parity_32: 197; X64-POPCNT: # %bb.0: 198; X64-POPCNT-NEXT: popcntl %edi, %eax 199; X64-POPCNT-NEXT: andl $1, %eax 200; X64-POPCNT-NEXT: retq 201 %1 = tail call i32 @llvm.ctpop.i32(i32 %x) 202 %2 = and i32 %1, 1 203 ret i32 %2 204} 205 206define i64 @parity_64(i64 %x) { 207; X86-NOPOPCNT-LABEL: parity_64: 208; X86-NOPOPCNT: # %bb.0: 209; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 210; X86-NOPOPCNT-NEXT: xorl {{[0-9]+}}(%esp), %eax 211; X86-NOPOPCNT-NEXT: movl %eax, %ecx 212; X86-NOPOPCNT-NEXT: shrl $16, %ecx 213; X86-NOPOPCNT-NEXT: xorl %eax, %ecx 214; X86-NOPOPCNT-NEXT: xorl %eax, %eax 215; X86-NOPOPCNT-NEXT: xorb %ch, %cl 216; X86-NOPOPCNT-NEXT: setnp %al 217; X86-NOPOPCNT-NEXT: xorl %edx, %edx 218; X86-NOPOPCNT-NEXT: retl 219; 220; X64-NOPOPCNT-LABEL: parity_64: 221; X64-NOPOPCNT: # %bb.0: 222; X64-NOPOPCNT-NEXT: movq %rdi, %rax 223; X64-NOPOPCNT-NEXT: shrq $32, %rax 224; X64-NOPOPCNT-NEXT: xorl %edi, %eax 225; X64-NOPOPCNT-NEXT: movl %eax, %ecx 226; X64-NOPOPCNT-NEXT: shrl $16, %ecx 227; X64-NOPOPCNT-NEXT: xorl %eax, %ecx 228; X64-NOPOPCNT-NEXT: xorl %eax, %eax 229; X64-NOPOPCNT-NEXT: xorb %ch, %cl 230; X64-NOPOPCNT-NEXT: setnp %al 231; X64-NOPOPCNT-NEXT: retq 232; 233; X86-POPCNT-LABEL: parity_64: 234; X86-POPCNT: # %bb.0: 235; X86-POPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 236; X86-POPCNT-NEXT: xorl {{[0-9]+}}(%esp), %eax 237; X86-POPCNT-NEXT: popcntl %eax, %eax 238; X86-POPCNT-NEXT: andl $1, %eax 239; X86-POPCNT-NEXT: xorl %edx, %edx 240; X86-POPCNT-NEXT: retl 241; 242; X64-POPCNT-LABEL: parity_64: 243; X64-POPCNT: # %bb.0: 244; X64-POPCNT-NEXT: popcntq %rdi, %rax 245; X64-POPCNT-NEXT: andl $1, %eax 246; X64-POPCNT-NEXT: retq 247 %1 = tail call i64 @llvm.ctpop.i64(i64 %x) 248 %2 = and i64 %1, 1 249 ret i64 %2 250} 251 252define i32 @parity_64_trunc(i64 %x) { 253; X86-NOPOPCNT-LABEL: parity_64_trunc: 254; X86-NOPOPCNT: # %bb.0: 255; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 256; X86-NOPOPCNT-NEXT: xorl {{[0-9]+}}(%esp), %eax 257; X86-NOPOPCNT-NEXT: movl %eax, %ecx 258; X86-NOPOPCNT-NEXT: shrl $16, %ecx 259; X86-NOPOPCNT-NEXT: xorl %eax, %ecx 260; X86-NOPOPCNT-NEXT: xorl %eax, %eax 261; X86-NOPOPCNT-NEXT: xorb %ch, %cl 262; X86-NOPOPCNT-NEXT: setnp %al 263; X86-NOPOPCNT-NEXT: retl 264; 265; X64-NOPOPCNT-LABEL: parity_64_trunc: 266; X64-NOPOPCNT: # %bb.0: 267; X64-NOPOPCNT-NEXT: movq %rdi, %rax 268; X64-NOPOPCNT-NEXT: shrq $32, %rax 269; X64-NOPOPCNT-NEXT: xorl %edi, %eax 270; X64-NOPOPCNT-NEXT: movl %eax, %ecx 271; X64-NOPOPCNT-NEXT: shrl $16, %ecx 272; X64-NOPOPCNT-NEXT: xorl %eax, %ecx 273; X64-NOPOPCNT-NEXT: xorl %eax, %eax 274; X64-NOPOPCNT-NEXT: xorb %ch, %cl 275; X64-NOPOPCNT-NEXT: setnp %al 276; X64-NOPOPCNT-NEXT: retq 277; 278; X86-POPCNT-LABEL: parity_64_trunc: 279; X86-POPCNT: # %bb.0: 280; X86-POPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 281; X86-POPCNT-NEXT: xorl {{[0-9]+}}(%esp), %eax 282; X86-POPCNT-NEXT: popcntl %eax, %eax 283; X86-POPCNT-NEXT: andl $1, %eax 284; X86-POPCNT-NEXT: retl 285; 286; X64-POPCNT-LABEL: parity_64_trunc: 287; X64-POPCNT: # %bb.0: 288; X64-POPCNT-NEXT: popcntq %rdi, %rax 289; X64-POPCNT-NEXT: andl $1, %eax 290; X64-POPCNT-NEXT: # kill: def $eax killed $eax killed $rax 291; X64-POPCNT-NEXT: retq 292 %1 = tail call i64 @llvm.ctpop.i64(i64 %x) 293 %2 = trunc i64 %1 to i32 294 %3 = and i32 %2, 1 295 ret i32 %3 296} 297 298define i8 @parity_32_trunc(i32 %x) { 299; X86-NOPOPCNT-LABEL: parity_32_trunc: 300; X86-NOPOPCNT: # %bb.0: 301; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 302; X86-NOPOPCNT-NEXT: movl %eax, %ecx 303; X86-NOPOPCNT-NEXT: shrl $16, %ecx 304; X86-NOPOPCNT-NEXT: xorl %eax, %ecx 305; X86-NOPOPCNT-NEXT: xorb %ch, %cl 306; X86-NOPOPCNT-NEXT: setnp %al 307; X86-NOPOPCNT-NEXT: retl 308; 309; X64-NOPOPCNT-LABEL: parity_32_trunc: 310; X64-NOPOPCNT: # %bb.0: 311; X64-NOPOPCNT-NEXT: movl %edi, %eax 312; X64-NOPOPCNT-NEXT: shrl $16, %eax 313; X64-NOPOPCNT-NEXT: xorl %edi, %eax 314; X64-NOPOPCNT-NEXT: xorb %ah, %al 315; X64-NOPOPCNT-NEXT: setnp %al 316; X64-NOPOPCNT-NEXT: retq 317; 318; X86-POPCNT-LABEL: parity_32_trunc: 319; X86-POPCNT: # %bb.0: 320; X86-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %eax 321; X86-POPCNT-NEXT: andl $1, %eax 322; X86-POPCNT-NEXT: # kill: def $al killed $al killed $eax 323; X86-POPCNT-NEXT: retl 324; 325; X64-POPCNT-LABEL: parity_32_trunc: 326; X64-POPCNT: # %bb.0: 327; X64-POPCNT-NEXT: popcntl %edi, %eax 328; X64-POPCNT-NEXT: andl $1, %eax 329; X64-POPCNT-NEXT: # kill: def $al killed $al killed $eax 330; X64-POPCNT-NEXT: retq 331 %1 = tail call i32 @llvm.ctpop.i32(i32 %x) 332 %2 = trunc i32 %1 to i8 333 %3 = and i8 %2, 1 334 ret i8 %3 335} 336 337define i16 @parity_16_zexti8(i8 %x) { 338; X86-LABEL: parity_16_zexti8: 339; X86: # %bb.0: 340; X86-NEXT: xorl %eax, %eax 341; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) 342; X86-NEXT: setnp %al 343; X86-NEXT: # kill: def $ax killed $ax killed $eax 344; X86-NEXT: retl 345; 346; X64-LABEL: parity_16_zexti8: 347; X64: # %bb.0: 348; X64-NEXT: xorl %eax, %eax 349; X64-NEXT: testb %dil, %dil 350; X64-NEXT: setnp %al 351; X64-NEXT: # kill: def $ax killed $ax killed $eax 352; X64-NEXT: retq 353 %a = zext i8 %x to i16 354 %b = tail call i16 @llvm.ctpop.i16(i16 %a) 355 %c = and i16 %b, 1 356 ret i16 %c 357} 358 359define i16 @parity_16_mask255(i16 %x) { 360; X86-LABEL: parity_16_mask255: 361; X86: # %bb.0: 362; X86-NEXT: xorl %eax, %eax 363; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) 364; X86-NEXT: setnp %al 365; X86-NEXT: # kill: def $ax killed $ax killed $eax 366; X86-NEXT: retl 367; 368; X64-LABEL: parity_16_mask255: 369; X64: # %bb.0: 370; X64-NEXT: xorl %eax, %eax 371; X64-NEXT: testb %dil, %dil 372; X64-NEXT: setnp %al 373; X64-NEXT: # kill: def $ax killed $ax killed $eax 374; X64-NEXT: retq 375 %a = and i16 %x, 255 376 %b = tail call i16 @llvm.ctpop.i16(i16 %a) 377 %c = and i16 %b, 1 378 ret i16 %c 379} 380 381define i16 @parity_16_mask15(i16 %x) { 382; X86-LABEL: parity_16_mask15: 383; X86: # %bb.0: 384; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 385; X86-NEXT: xorl %eax, %eax 386; X86-NEXT: testb $15, %cl 387; X86-NEXT: setnp %al 388; X86-NEXT: # kill: def $ax killed $ax killed $eax 389; X86-NEXT: retl 390; 391; X64-LABEL: parity_16_mask15: 392; X64: # %bb.0: 393; X64-NEXT: xorl %eax, %eax 394; X64-NEXT: testb $15, %dil 395; X64-NEXT: setnp %al 396; X64-NEXT: # kill: def $ax killed $ax killed $eax 397; X64-NEXT: retq 398 %a = and i16 %x, 15 399 %b = tail call i16 @llvm.ctpop.i16(i16 %a) 400 %c = and i16 %b, 1 401 ret i16 %c 402} 403 404define i16 @parity_16_shift(i16 %0) { 405; X86-NOPOPCNT-LABEL: parity_16_shift: 406; X86-NOPOPCNT: # %bb.0: 407; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %ecx 408; X86-NOPOPCNT-NEXT: xorl %eax, %eax 409; X86-NOPOPCNT-NEXT: xorb %ch, %cl 410; X86-NOPOPCNT-NEXT: setnp %al 411; X86-NOPOPCNT-NEXT: addl %eax, %eax 412; X86-NOPOPCNT-NEXT: # kill: def $ax killed $ax killed $eax 413; X86-NOPOPCNT-NEXT: retl 414; 415; X64-NOPOPCNT-LABEL: parity_16_shift: 416; X64-NOPOPCNT: # %bb.0: 417; X64-NOPOPCNT-NEXT: movl %edi, %ecx 418; X64-NOPOPCNT-NEXT: xorl %eax, %eax 419; X64-NOPOPCNT-NEXT: xorb %ch, %cl 420; X64-NOPOPCNT-NEXT: setnp %al 421; X64-NOPOPCNT-NEXT: addl %eax, %eax 422; X64-NOPOPCNT-NEXT: # kill: def $ax killed $ax killed $eax 423; X64-NOPOPCNT-NEXT: retq 424; 425; X86-POPCNT-LABEL: parity_16_shift: 426; X86-POPCNT: # %bb.0: 427; X86-POPCNT-NEXT: movzwl {{[0-9]+}}(%esp), %eax 428; X86-POPCNT-NEXT: popcntl %eax, %eax 429; X86-POPCNT-NEXT: andl $1, %eax 430; X86-POPCNT-NEXT: addl %eax, %eax 431; X86-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax 432; X86-POPCNT-NEXT: retl 433; 434; X64-POPCNT-LABEL: parity_16_shift: 435; X64-POPCNT: # %bb.0: 436; X64-POPCNT-NEXT: movzwl %di, %eax 437; X64-POPCNT-NEXT: popcntl %eax, %eax 438; X64-POPCNT-NEXT: andl $1, %eax 439; X64-POPCNT-NEXT: addl %eax, %eax 440; X64-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax 441; X64-POPCNT-NEXT: retq 442 %2 = tail call i16 @llvm.ctpop.i16(i16 %0) 443 %3 = shl nuw nsw i16 %2, 1 444 %4 = and i16 %3, 2 445 ret i16 %4 446} 447 448define i32 @parity_32_zexti8(i8 %x) { 449; X86-LABEL: parity_32_zexti8: 450; X86: # %bb.0: 451; X86-NEXT: xorl %eax, %eax 452; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) 453; X86-NEXT: setnp %al 454; X86-NEXT: retl 455; 456; X64-LABEL: parity_32_zexti8: 457; X64: # %bb.0: 458; X64-NEXT: xorl %eax, %eax 459; X64-NEXT: testb %dil, %dil 460; X64-NEXT: setnp %al 461; X64-NEXT: retq 462 %a = zext i8 %x to i32 463 %b = tail call i32 @llvm.ctpop.i32(i32 %a) 464 %c = and i32 %b, 1 465 ret i32 %c 466} 467 468define i32 @parity_32_mask255(i32 %x) { 469; X86-LABEL: parity_32_mask255: 470; X86: # %bb.0: 471; X86-NEXT: xorl %eax, %eax 472; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) 473; X86-NEXT: setnp %al 474; X86-NEXT: retl 475; 476; X64-LABEL: parity_32_mask255: 477; X64: # %bb.0: 478; X64-NEXT: xorl %eax, %eax 479; X64-NEXT: testb %dil, %dil 480; X64-NEXT: setnp %al 481; X64-NEXT: retq 482 %a = and i32 %x, 255 483 %b = tail call i32 @llvm.ctpop.i32(i32 %a) 484 %c = and i32 %b, 1 485 ret i32 %c 486} 487 488define i32 @parity_32_mask15(i32 %x) { 489; X86-LABEL: parity_32_mask15: 490; X86: # %bb.0: 491; X86-NEXT: xorl %eax, %eax 492; X86-NEXT: testb $15, {{[0-9]+}}(%esp) 493; X86-NEXT: setnp %al 494; X86-NEXT: retl 495; 496; X64-LABEL: parity_32_mask15: 497; X64: # %bb.0: 498; X64-NEXT: xorl %eax, %eax 499; X64-NEXT: testb $15, %dil 500; X64-NEXT: setnp %al 501; X64-NEXT: retq 502 %a = and i32 %x, 15 503 %b = tail call i32 @llvm.ctpop.i32(i32 %a) 504 %c = and i32 %b, 1 505 ret i32 %c 506} 507 508define i32 @parity_32_shift(i32 %0) { 509; X86-NOPOPCNT-LABEL: parity_32_shift: 510; X86-NOPOPCNT: # %bb.0: 511; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 512; X86-NOPOPCNT-NEXT: movl %eax, %ecx 513; X86-NOPOPCNT-NEXT: shrl $16, %ecx 514; X86-NOPOPCNT-NEXT: xorl %eax, %ecx 515; X86-NOPOPCNT-NEXT: xorl %eax, %eax 516; X86-NOPOPCNT-NEXT: xorb %ch, %cl 517; X86-NOPOPCNT-NEXT: setnp %al 518; X86-NOPOPCNT-NEXT: addl %eax, %eax 519; X86-NOPOPCNT-NEXT: retl 520; 521; X64-NOPOPCNT-LABEL: parity_32_shift: 522; X64-NOPOPCNT: # %bb.0: 523; X64-NOPOPCNT-NEXT: movl %edi, %ecx 524; X64-NOPOPCNT-NEXT: shrl $16, %ecx 525; X64-NOPOPCNT-NEXT: xorl %edi, %ecx 526; X64-NOPOPCNT-NEXT: xorl %eax, %eax 527; X64-NOPOPCNT-NEXT: xorb %ch, %cl 528; X64-NOPOPCNT-NEXT: setnp %al 529; X64-NOPOPCNT-NEXT: addl %eax, %eax 530; X64-NOPOPCNT-NEXT: retq 531; 532; X86-POPCNT-LABEL: parity_32_shift: 533; X86-POPCNT: # %bb.0: 534; X86-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %eax 535; X86-POPCNT-NEXT: andl $1, %eax 536; X86-POPCNT-NEXT: addl %eax, %eax 537; X86-POPCNT-NEXT: retl 538; 539; X64-POPCNT-LABEL: parity_32_shift: 540; X64-POPCNT: # %bb.0: 541; X64-POPCNT-NEXT: popcntl %edi, %eax 542; X64-POPCNT-NEXT: andl $1, %eax 543; X64-POPCNT-NEXT: addl %eax, %eax 544; X64-POPCNT-NEXT: retq 545 %2 = tail call i32 @llvm.ctpop.i32(i32 %0) 546 %3 = shl nuw nsw i32 %2, 1 547 %4 = and i32 %3, 2 548 ret i32 %4 549} 550 551define i64 @parity_64_zexti8(i8 %x) { 552; X86-LABEL: parity_64_zexti8: 553; X86: # %bb.0: 554; X86-NEXT: xorl %eax, %eax 555; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) 556; X86-NEXT: setnp %al 557; X86-NEXT: xorl %edx, %edx 558; X86-NEXT: retl 559; 560; X64-LABEL: parity_64_zexti8: 561; X64: # %bb.0: 562; X64-NEXT: xorl %eax, %eax 563; X64-NEXT: testb %dil, %dil 564; X64-NEXT: setnp %al 565; X64-NEXT: retq 566 %a = zext i8 %x to i64 567 %b = tail call i64 @llvm.ctpop.i64(i64 %a) 568 %c = and i64 %b, 1 569 ret i64 %c 570} 571 572define i64 @parity_64_mask255(i64 %x) { 573; X86-LABEL: parity_64_mask255: 574; X86: # %bb.0: 575; X86-NEXT: xorl %eax, %eax 576; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp) 577; X86-NEXT: setnp %al 578; X86-NEXT: xorl %edx, %edx 579; X86-NEXT: retl 580; 581; X64-LABEL: parity_64_mask255: 582; X64: # %bb.0: 583; X64-NEXT: xorl %eax, %eax 584; X64-NEXT: testb %dil, %dil 585; X64-NEXT: setnp %al 586; X64-NEXT: retq 587 %a = and i64 %x, 255 588 %b = tail call i64 @llvm.ctpop.i64(i64 %a) 589 %c = and i64 %b, 1 590 ret i64 %c 591} 592 593define i64 @parity_64_mask15(i64 %x) { 594; X86-LABEL: parity_64_mask15: 595; X86: # %bb.0: 596; X86-NEXT: xorl %eax, %eax 597; X86-NEXT: testb $15, {{[0-9]+}}(%esp) 598; X86-NEXT: setnp %al 599; X86-NEXT: xorl %edx, %edx 600; X86-NEXT: retl 601; 602; X64-LABEL: parity_64_mask15: 603; X64: # %bb.0: 604; X64-NEXT: xorl %eax, %eax 605; X64-NEXT: testb $15, %dil 606; X64-NEXT: setnp %al 607; X64-NEXT: retq 608 %a = and i64 %x, 15 609 %b = tail call i64 @llvm.ctpop.i64(i64 %a) 610 %c = and i64 %b, 1 611 ret i64 %c 612} 613 614define i64 @parity_64_shift(i64 %0) { 615; X86-NOPOPCNT-LABEL: parity_64_shift: 616; X86-NOPOPCNT: # %bb.0: 617; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 618; X86-NOPOPCNT-NEXT: xorl {{[0-9]+}}(%esp), %eax 619; X86-NOPOPCNT-NEXT: movl %eax, %ecx 620; X86-NOPOPCNT-NEXT: shrl $16, %ecx 621; X86-NOPOPCNT-NEXT: xorl %eax, %ecx 622; X86-NOPOPCNT-NEXT: xorl %eax, %eax 623; X86-NOPOPCNT-NEXT: xorb %ch, %cl 624; X86-NOPOPCNT-NEXT: setnp %al 625; X86-NOPOPCNT-NEXT: addl %eax, %eax 626; X86-NOPOPCNT-NEXT: xorl %edx, %edx 627; X86-NOPOPCNT-NEXT: retl 628; 629; X64-NOPOPCNT-LABEL: parity_64_shift: 630; X64-NOPOPCNT: # %bb.0: 631; X64-NOPOPCNT-NEXT: movq %rdi, %rax 632; X64-NOPOPCNT-NEXT: shrq $32, %rax 633; X64-NOPOPCNT-NEXT: xorl %edi, %eax 634; X64-NOPOPCNT-NEXT: movl %eax, %ecx 635; X64-NOPOPCNT-NEXT: shrl $16, %ecx 636; X64-NOPOPCNT-NEXT: xorl %eax, %ecx 637; X64-NOPOPCNT-NEXT: xorl %eax, %eax 638; X64-NOPOPCNT-NEXT: xorb %ch, %cl 639; X64-NOPOPCNT-NEXT: setnp %al 640; X64-NOPOPCNT-NEXT: addl %eax, %eax 641; X64-NOPOPCNT-NEXT: retq 642; 643; X86-POPCNT-LABEL: parity_64_shift: 644; X86-POPCNT: # %bb.0: 645; X86-POPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax 646; X86-POPCNT-NEXT: xorl {{[0-9]+}}(%esp), %eax 647; X86-POPCNT-NEXT: popcntl %eax, %eax 648; X86-POPCNT-NEXT: andl $1, %eax 649; X86-POPCNT-NEXT: addl %eax, %eax 650; X86-POPCNT-NEXT: xorl %edx, %edx 651; X86-POPCNT-NEXT: retl 652; 653; X64-POPCNT-LABEL: parity_64_shift: 654; X64-POPCNT: # %bb.0: 655; X64-POPCNT-NEXT: popcntq %rdi, %rax 656; X64-POPCNT-NEXT: andl $1, %eax 657; X64-POPCNT-NEXT: addl %eax, %eax 658; X64-POPCNT-NEXT: retq 659 %2 = tail call i64 @llvm.ctpop.i64(i64 %0) 660 %3 = shl nuw nsw i64 %2, 1 661 %4 = and i64 %3, 2 662 ret i64 %4 663} 664 665declare i4 @llvm.ctpop.i4(i4 %x) 666declare i8 @llvm.ctpop.i8(i8 %x) 667declare i16 @llvm.ctpop.i16(i16 %x) 668declare i17 @llvm.ctpop.i17(i17 %x) 669declare i32 @llvm.ctpop.i32(i32 %x) 670declare i64 @llvm.ctpop.i64(i64 %x) 671