Skip to content

Commit fd8d593

Browse files
committed
[DAG] SimplifyDemandedBits - relax AND(CTPOP(X),1) -> PARITY(X) fold to correctly demand known zero upper bits
If we demand the lowest bit and any mixture of the upper 'known zero' bits of a CTPOP node then we can still fold to a PARITY node as we still guarantee that the upper bits will be zero.
1 parent cd17571 commit fd8d593

File tree

2 files changed

+45
-93
lines changed

2 files changed

+45
-93
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,13 +2263,16 @@ bool TargetLowering::SimplifyDemandedBits(
22632263
break;
22642264
}
22652265
case ISD::CTPOP: {
2266-
// If only 1 bit is demanded, replace with PARITY as long as we're before
2267-
// op legalization.
2266+
// If only bit0 of 'active bits' is demanded, replace with PARITY as long as
2267+
// we're before op legalization.
22682268
// FIXME: Limit to scalars for now.
2269-
if (DemandedBits.isOne() && !TLO.LegalOps && !VT.isVector())
2270-
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::PARITY, dl, VT,
2271-
Op.getOperand(0)));
2272-
2269+
if (!TLO.LegalOps && !VT.isVector()) {
2270+
APInt NonZeroMask =
2271+
APInt::getLowBitsSet(BitWidth, llvm::bit_width(BitWidth));
2272+
if ((DemandedBits & NonZeroMask).isOne())
2273+
return TLO.CombineTo(
2274+
Op, TLO.DAG.getNode(ISD::PARITY, dl, VT, Op.getOperand(0)));
2275+
}
22732276
Known = TLO.DAG.computeKnownBits(Op, DemandedElts, Depth);
22742277
break;
22752278
}

llvm/test/CodeGen/X86/parity.ll

Lines changed: 36 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -404,64 +404,39 @@ define i16 @parity_16_mask15(i16 %x) {
404404
define i16 @parity_16_shift(i16 %0) {
405405
; X86-NOPOPCNT-LABEL: parity_16_shift:
406406
; X86-NOPOPCNT: # %bb.0:
407-
; X86-NOPOPCNT-NEXT: movzwl {{[0-9]+}}(%esp), %eax
408-
; X86-NOPOPCNT-NEXT: movl %eax, %ecx
409-
; X86-NOPOPCNT-NEXT: shrl %ecx
410-
; X86-NOPOPCNT-NEXT: andl $21845, %ecx # imm = 0x5555
411-
; X86-NOPOPCNT-NEXT: subl %ecx, %eax
412-
; X86-NOPOPCNT-NEXT: movl %eax, %ecx
413-
; X86-NOPOPCNT-NEXT: andl $13107, %ecx # imm = 0x3333
414-
; X86-NOPOPCNT-NEXT: shrl $2, %eax
415-
; X86-NOPOPCNT-NEXT: andl $13107, %eax # imm = 0x3333
416-
; X86-NOPOPCNT-NEXT: addl %ecx, %eax
417-
; X86-NOPOPCNT-NEXT: movl %eax, %ecx
418-
; X86-NOPOPCNT-NEXT: shrl $4, %ecx
419-
; X86-NOPOPCNT-NEXT: addl %eax, %ecx
420-
; X86-NOPOPCNT-NEXT: movl %ecx, %eax
421-
; X86-NOPOPCNT-NEXT: shrl $8, %eax
422-
; X86-NOPOPCNT-NEXT: addl %ecx, %eax
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
423411
; X86-NOPOPCNT-NEXT: addl %eax, %eax
424-
; X86-NOPOPCNT-NEXT: andl $2, %eax
425412
; X86-NOPOPCNT-NEXT: # kill: def $ax killed $ax killed $eax
426413
; X86-NOPOPCNT-NEXT: retl
427414
;
428415
; X64-NOPOPCNT-LABEL: parity_16_shift:
429416
; X64-NOPOPCNT: # %bb.0:
430-
; X64-NOPOPCNT-NEXT: movl %edi, %eax
431-
; X64-NOPOPCNT-NEXT: shrl %eax
432-
; X64-NOPOPCNT-NEXT: andl $21845, %eax # imm = 0x5555
433-
; X64-NOPOPCNT-NEXT: subl %eax, %edi
434-
; X64-NOPOPCNT-NEXT: movl %edi, %eax
435-
; X64-NOPOPCNT-NEXT: andl $13107, %eax # imm = 0x3333
436-
; X64-NOPOPCNT-NEXT: shrl $2, %edi
437-
; X64-NOPOPCNT-NEXT: andl $13107, %edi # imm = 0x3333
438-
; X64-NOPOPCNT-NEXT: addl %edi, %eax
439-
; X64-NOPOPCNT-NEXT: movl %eax, %ecx
440-
; X64-NOPOPCNT-NEXT: shrl $4, %ecx
441-
; X64-NOPOPCNT-NEXT: addl %eax, %ecx
442-
; X64-NOPOPCNT-NEXT: movl %ecx, %eax
443-
; X64-NOPOPCNT-NEXT: shrl $8, %eax
444-
; X64-NOPOPCNT-NEXT: addl %ecx, %eax
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
445421
; X64-NOPOPCNT-NEXT: addl %eax, %eax
446-
; X64-NOPOPCNT-NEXT: andl $2, %eax
447422
; X64-NOPOPCNT-NEXT: # kill: def $ax killed $ax killed $eax
448423
; X64-NOPOPCNT-NEXT: retq
449424
;
450425
; X86-POPCNT-LABEL: parity_16_shift:
451426
; X86-POPCNT: # %bb.0:
452427
; X86-POPCNT-NEXT: movzwl {{[0-9]+}}(%esp), %eax
453428
; X86-POPCNT-NEXT: popcntl %eax, %eax
429+
; X86-POPCNT-NEXT: andl $1, %eax
454430
; X86-POPCNT-NEXT: addl %eax, %eax
455-
; X86-POPCNT-NEXT: andl $2, %eax
456431
; X86-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax
457432
; X86-POPCNT-NEXT: retl
458433
;
459434
; X64-POPCNT-LABEL: parity_16_shift:
460435
; X64-POPCNT: # %bb.0:
461436
; X64-POPCNT-NEXT: movzwl %di, %eax
462437
; X64-POPCNT-NEXT: popcntl %eax, %eax
438+
; X64-POPCNT-NEXT: andl $1, %eax
463439
; X64-POPCNT-NEXT: addl %eax, %eax
464-
; X64-POPCNT-NEXT: andl $2, %eax
465440
; X64-POPCNT-NEXT: # kill: def $ax killed $ax killed $eax
466441
; X64-POPCNT-NEXT: retq
467442
%2 = tail call i16 @llvm.ctpop.i16(i16 %0)
@@ -535,55 +510,37 @@ define i32 @parity_32_shift(i32 %0) {
535510
; X86-NOPOPCNT: # %bb.0:
536511
; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax
537512
; X86-NOPOPCNT-NEXT: movl %eax, %ecx
538-
; X86-NOPOPCNT-NEXT: shrl %ecx
539-
; X86-NOPOPCNT-NEXT: andl $1431655765, %ecx # imm = 0x55555555
540-
; X86-NOPOPCNT-NEXT: subl %ecx, %eax
541-
; X86-NOPOPCNT-NEXT: movl %eax, %ecx
542-
; X86-NOPOPCNT-NEXT: andl $858993459, %ecx # imm = 0x33333333
543-
; X86-NOPOPCNT-NEXT: shrl $2, %eax
544-
; X86-NOPOPCNT-NEXT: andl $858993459, %eax # imm = 0x33333333
545-
; X86-NOPOPCNT-NEXT: addl %ecx, %eax
546-
; X86-NOPOPCNT-NEXT: movl %eax, %ecx
547-
; X86-NOPOPCNT-NEXT: shrl $4, %ecx
548-
; X86-NOPOPCNT-NEXT: addl %eax, %ecx
549-
; X86-NOPOPCNT-NEXT: andl $17764111, %ecx # imm = 0x10F0F0F
550-
; X86-NOPOPCNT-NEXT: imull $16843009, %ecx, %eax # imm = 0x1010101
551-
; X86-NOPOPCNT-NEXT: shrl $23, %eax
552-
; X86-NOPOPCNT-NEXT: andl $2, %eax
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
553519
; X86-NOPOPCNT-NEXT: retl
554520
;
555521
; X64-NOPOPCNT-LABEL: parity_32_shift:
556522
; X64-NOPOPCNT: # %bb.0:
557-
; X64-NOPOPCNT-NEXT: movl %edi, %eax
558-
; X64-NOPOPCNT-NEXT: shrl %eax
559-
; X64-NOPOPCNT-NEXT: andl $1431655765, %eax # imm = 0x55555555
560-
; X64-NOPOPCNT-NEXT: subl %eax, %edi
561-
; X64-NOPOPCNT-NEXT: movl %edi, %eax
562-
; X64-NOPOPCNT-NEXT: andl $858993459, %eax # imm = 0x33333333
563-
; X64-NOPOPCNT-NEXT: shrl $2, %edi
564-
; X64-NOPOPCNT-NEXT: andl $858993459, %edi # imm = 0x33333333
565-
; X64-NOPOPCNT-NEXT: addl %eax, %edi
566-
; X64-NOPOPCNT-NEXT: movl %edi, %eax
567-
; X64-NOPOPCNT-NEXT: shrl $4, %eax
568-
; X64-NOPOPCNT-NEXT: addl %edi, %eax
569-
; X64-NOPOPCNT-NEXT: andl $17764111, %eax # imm = 0x10F0F0F
570-
; X64-NOPOPCNT-NEXT: imull $16843009, %eax, %eax # imm = 0x1010101
571-
; X64-NOPOPCNT-NEXT: shrl $23, %eax
572-
; X64-NOPOPCNT-NEXT: andl $2, %eax
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
573530
; X64-NOPOPCNT-NEXT: retq
574531
;
575532
; X86-POPCNT-LABEL: parity_32_shift:
576533
; X86-POPCNT: # %bb.0:
577534
; X86-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %eax
535+
; X86-POPCNT-NEXT: andl $1, %eax
578536
; X86-POPCNT-NEXT: addl %eax, %eax
579-
; X86-POPCNT-NEXT: andl $2, %eax
580537
; X86-POPCNT-NEXT: retl
581538
;
582539
; X64-POPCNT-LABEL: parity_32_shift:
583540
; X64-POPCNT: # %bb.0:
584541
; X64-POPCNT-NEXT: popcntl %edi, %eax
542+
; X64-POPCNT-NEXT: andl $1, %eax
585543
; X64-POPCNT-NEXT: addl %eax, %eax
586-
; X64-POPCNT-NEXT: andl $2, %eax
587544
; X64-POPCNT-NEXT: retq
588545
%2 = tail call i32 @llvm.ctpop.i32(i32 %0)
589546
%3 = shl nuw nsw i32 %2, 1
@@ -658,22 +615,14 @@ define i64 @parity_64_shift(i64 %0) {
658615
; X86-NOPOPCNT-LABEL: parity_64_shift:
659616
; X86-NOPOPCNT: # %bb.0:
660617
; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %eax
661-
; X86-NOPOPCNT-NEXT: movl {{[0-9]+}}(%esp), %ecx
662-
; X86-NOPOPCNT-NEXT: movl %ecx, %edx
663-
; X86-NOPOPCNT-NEXT: shrl $16, %edx
664-
; X86-NOPOPCNT-NEXT: xorl %ecx, %edx
665-
; X86-NOPOPCNT-NEXT: xorl %ecx, %ecx
666-
; X86-NOPOPCNT-NEXT: xorb %dh, %dl
667-
; X86-NOPOPCNT-NEXT: setnp %cl
668-
; X86-NOPOPCNT-NEXT: movl %eax, %edx
669-
; X86-NOPOPCNT-NEXT: shrl $16, %edx
670-
; X86-NOPOPCNT-NEXT: xorl %eax, %edx
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
671622
; X86-NOPOPCNT-NEXT: xorl %eax, %eax
672-
; X86-NOPOPCNT-NEXT: xorb %dh, %dl
623+
; X86-NOPOPCNT-NEXT: xorb %ch, %cl
673624
; X86-NOPOPCNT-NEXT: setnp %al
674-
; X86-NOPOPCNT-NEXT: addl %ecx, %eax
675625
; X86-NOPOPCNT-NEXT: addl %eax, %eax
676-
; X86-NOPOPCNT-NEXT: andl $2, %eax
677626
; X86-NOPOPCNT-NEXT: xorl %edx, %edx
678627
; X86-NOPOPCNT-NEXT: retl
679628
;
@@ -688,24 +637,24 @@ define i64 @parity_64_shift(i64 %0) {
688637
; X64-NOPOPCNT-NEXT: xorl %eax, %eax
689638
; X64-NOPOPCNT-NEXT: xorb %ch, %cl
690639
; X64-NOPOPCNT-NEXT: setnp %al
691-
; X64-NOPOPCNT-NEXT: addl %eax, %eax
640+
; X64-NOPOPCNT-NEXT: addq %rax, %rax
692641
; X64-NOPOPCNT-NEXT: retq
693642
;
694643
; X86-POPCNT-LABEL: parity_64_shift:
695644
; X86-POPCNT: # %bb.0:
696-
; X86-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %ecx
697-
; X86-POPCNT-NEXT: popcntl {{[0-9]+}}(%esp), %eax
698-
; X86-POPCNT-NEXT: addl %ecx, %eax
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
699649
; X86-POPCNT-NEXT: addl %eax, %eax
700-
; X86-POPCNT-NEXT: andl $2, %eax
701650
; X86-POPCNT-NEXT: xorl %edx, %edx
702651
; X86-POPCNT-NEXT: retl
703652
;
704653
; X64-POPCNT-LABEL: parity_64_shift:
705654
; X64-POPCNT: # %bb.0:
706655
; X64-POPCNT-NEXT: popcntq %rdi, %rax
707656
; X64-POPCNT-NEXT: andl $1, %eax
708-
; X64-POPCNT-NEXT: addl %eax, %eax
657+
; X64-POPCNT-NEXT: addq %rax, %rax
709658
; X64-POPCNT-NEXT: retq
710659
%2 = tail call i64 @llvm.ctpop.i64(i64 %0)
711660
%3 = shl nuw nsw i64 %2, 1

0 commit comments

Comments
 (0)