Skip to content

Commit 77adbb3

Browse files
committed
Relax ANDNOT requirement to be only for multiple uses of the NOT
1 parent 9ba8f81 commit 77adbb3

File tree

2 files changed

+107
-80
lines changed

2 files changed

+107
-80
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7353,20 +7353,16 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
73537353
if (SDValue R = foldLogicOfShifts(N, N1, N0, DAG))
73547354
return R;
73557355

7356-
// If the target supports ANDNOT, attempt to reconstruct an ANDNOT pattern
7357-
// that might have become separated by a bitwise-agnostic instruction.
7358-
if (TLI.hasAndNot(SDValue(N, 0))) {
7359-
SDValue X, Y;
7360-
7361-
// Fold (and X, (bswap (not Y))) -> (and X, (not (bswap Y)))
7362-
// Fold (and X, (bitreverse (not Y))) -> (and X, (not (bitreverse Y)))
7363-
for (unsigned Opc : {ISD::BSWAP, ISD::BITREVERSE})
7364-
if (sd_match(N, m_And(m_Value(X),
7365-
m_OneUse(m_UnaryOp(Opc, m_Not(m_Value(Y)))))) &&
7366-
!sd_match(X, m_Not(m_Value())))
7367-
return DAG.getNode(ISD::AND, DL, VT, X,
7368-
DAG.getNOT(DL, DAG.getNode(Opc, DL, VT, Y), VT));
7369-
}
7356+
// Fold (and X, (bswap (not Y))) -> (and X, (not (bswap Y)))
7357+
// Fold (and X, (bitreverse (not Y))) -> (and X, (not (bitreverse Y)))
7358+
SDValue X, Y, NotY;
7359+
for (unsigned Opc : {ISD::BSWAP, ISD::BITREVERSE})
7360+
if (sd_match(N,
7361+
m_And(m_Value(X), m_OneUse(m_UnaryOp(Opc, m_Value(NotY))))) &&
7362+
sd_match(NotY, m_Not(m_Value(Y))) &&
7363+
(TLI.hasAndNot(SDValue(N, 0)) || NotY->hasOneUse()))
7364+
return DAG.getNode(ISD::AND, DL, VT, X,
7365+
DAG.getNOT(DL, DAG.getNode(Opc, DL, VT, Y), VT));
73707366

73717367
// Masking the negated extension of a boolean is just the zero-extended
73727368
// boolean:

llvm/test/CodeGen/X86/andnot-patterns.ll

Lines changed: 97 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,11 @@ define i64 @andnot_bswap_i64(i64 %a0, i64 %a1) nounwind {
364364
; X86-NOBMI: # %bb.0:
365365
; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %edx
366366
; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax
367-
; X86-NOBMI-NEXT: notl %eax
368-
; X86-NOBMI-NEXT: notl %edx
369-
; X86-NOBMI-NEXT: bswapl %edx
370367
; X86-NOBMI-NEXT: bswapl %eax
368+
; X86-NOBMI-NEXT: notl %eax
371369
; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax
370+
; X86-NOBMI-NEXT: bswapl %edx
371+
; X86-NOBMI-NEXT: notl %edx
372372
; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edx
373373
; X86-NOBMI-NEXT: retl
374374
;
@@ -385,8 +385,8 @@ define i64 @andnot_bswap_i64(i64 %a0, i64 %a1) nounwind {
385385
; X64-NOBMI-LABEL: andnot_bswap_i64:
386386
; X64-NOBMI: # %bb.0:
387387
; X64-NOBMI-NEXT: movq %rsi, %rax
388-
; X64-NOBMI-NEXT: notq %rax
389388
; X64-NOBMI-NEXT: bswapq %rax
389+
; X64-NOBMI-NEXT: notq %rax
390390
; X64-NOBMI-NEXT: andq %rdi, %rax
391391
; X64-NOBMI-NEXT: retq
392392
;
@@ -405,8 +405,8 @@ define i32 @andnot_bswap_i32(i32 %a0, i32 %a1) nounwind {
405405
; X86-NOBMI-LABEL: andnot_bswap_i32:
406406
; X86-NOBMI: # %bb.0:
407407
; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax
408-
; X86-NOBMI-NEXT: notl %eax
409408
; X86-NOBMI-NEXT: bswapl %eax
409+
; X86-NOBMI-NEXT: notl %eax
410410
; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax
411411
; X86-NOBMI-NEXT: retl
412412
;
@@ -420,8 +420,8 @@ define i32 @andnot_bswap_i32(i32 %a0, i32 %a1) nounwind {
420420
; X64-NOBMI-LABEL: andnot_bswap_i32:
421421
; X64-NOBMI: # %bb.0:
422422
; X64-NOBMI-NEXT: movl %esi, %eax
423-
; X64-NOBMI-NEXT: notl %eax
424423
; X64-NOBMI-NEXT: bswapl %eax
424+
; X64-NOBMI-NEXT: notl %eax
425425
; X64-NOBMI-NEXT: andl %edi, %eax
426426
; X64-NOBMI-NEXT: retq
427427
;
@@ -439,21 +439,28 @@ define i32 @andnot_bswap_i32(i32 %a0, i32 %a1) nounwind {
439439
define i16 @andnot_bswap_i16(i16 %a0, i16 %a1) nounwind {
440440
; X86-LABEL: andnot_bswap_i16:
441441
; X86: # %bb.0:
442-
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
443-
; X86-NEXT: notl %eax
442+
; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
444443
; X86-NEXT: rolw $8, %ax
444+
; X86-NEXT: notl %eax
445445
; X86-NEXT: andw {{[0-9]+}}(%esp), %ax
446446
; X86-NEXT: # kill: def $ax killed $ax killed $eax
447447
; X86-NEXT: retl
448448
;
449-
; X64-LABEL: andnot_bswap_i16:
450-
; X64: # %bb.0:
451-
; X64-NEXT: movl %esi, %eax
452-
; X64-NEXT: notl %eax
453-
; X64-NEXT: rolw $8, %ax
454-
; X64-NEXT: andl %edi, %eax
455-
; X64-NEXT: # kill: def $ax killed $ax killed $eax
456-
; X64-NEXT: retq
449+
; X64-NOBMI-LABEL: andnot_bswap_i16:
450+
; X64-NOBMI: # %bb.0:
451+
; X64-NOBMI-NEXT: movl %esi, %eax
452+
; X64-NOBMI-NEXT: rolw $8, %ax
453+
; X64-NOBMI-NEXT: notl %eax
454+
; X64-NOBMI-NEXT: andl %edi, %eax
455+
; X64-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax
456+
; X64-NOBMI-NEXT: retq
457+
;
458+
; X64-BMI-LABEL: andnot_bswap_i16:
459+
; X64-BMI: # %bb.0:
460+
; X64-BMI-NEXT: rolw $8, %si
461+
; X64-BMI-NEXT: andnl %edi, %esi, %eax
462+
; X64-BMI-NEXT: # kill: def $ax killed $ax killed $eax
463+
; X64-BMI-NEXT: retq
457464
%not = xor i16 %a1, -1
458465
%bswap = tail call i16 @llvm.bswap.i16(i16 %not)
459466
%and = and i16 %bswap, %a0
@@ -567,8 +574,25 @@ define i64 @andnot_bitreverse_i64(i64 %a0, i64 %a1) nounwind {
567574
; X86-NOBMI: # %bb.0:
568575
; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx
569576
; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax
577+
; X86-NOBMI-NEXT: bswapl %eax
578+
; X86-NOBMI-NEXT: movl %eax, %edx
579+
; X86-NOBMI-NEXT: andl $252645135, %edx # imm = 0xF0F0F0F
580+
; X86-NOBMI-NEXT: shll $4, %edx
581+
; X86-NOBMI-NEXT: shrl $4, %eax
582+
; X86-NOBMI-NEXT: andl $252645135, %eax # imm = 0xF0F0F0F
583+
; X86-NOBMI-NEXT: orl %edx, %eax
584+
; X86-NOBMI-NEXT: movl %eax, %edx
585+
; X86-NOBMI-NEXT: andl $858993459, %edx # imm = 0x33333333
586+
; X86-NOBMI-NEXT: shrl $2, %eax
587+
; X86-NOBMI-NEXT: andl $858993459, %eax # imm = 0x33333333
588+
; X86-NOBMI-NEXT: leal (%eax,%edx,4), %eax
589+
; X86-NOBMI-NEXT: movl %eax, %edx
590+
; X86-NOBMI-NEXT: andl $1431655765, %edx # imm = 0x55555555
591+
; X86-NOBMI-NEXT: shrl %eax
592+
; X86-NOBMI-NEXT: andl $1431655765, %eax # imm = 0x55555555
593+
; X86-NOBMI-NEXT: leal (%eax,%edx,2), %eax
570594
; X86-NOBMI-NEXT: notl %eax
571-
; X86-NOBMI-NEXT: notl %ecx
595+
; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax
572596
; X86-NOBMI-NEXT: bswapl %ecx
573597
; X86-NOBMI-NEXT: movl %ecx, %edx
574598
; X86-NOBMI-NEXT: andl $252645135, %edx # imm = 0xF0F0F0F
@@ -586,24 +610,7 @@ define i64 @andnot_bitreverse_i64(i64 %a0, i64 %a1) nounwind {
586610
; X86-NOBMI-NEXT: shrl %ecx
587611
; X86-NOBMI-NEXT: andl $1431655765, %ecx # imm = 0x55555555
588612
; X86-NOBMI-NEXT: leal (%ecx,%edx,2), %edx
589-
; X86-NOBMI-NEXT: bswapl %eax
590-
; X86-NOBMI-NEXT: movl %eax, %ecx
591-
; X86-NOBMI-NEXT: andl $252645135, %ecx # imm = 0xF0F0F0F
592-
; X86-NOBMI-NEXT: shll $4, %ecx
593-
; X86-NOBMI-NEXT: shrl $4, %eax
594-
; X86-NOBMI-NEXT: andl $252645135, %eax # imm = 0xF0F0F0F
595-
; X86-NOBMI-NEXT: orl %ecx, %eax
596-
; X86-NOBMI-NEXT: movl %eax, %ecx
597-
; X86-NOBMI-NEXT: andl $858993459, %ecx # imm = 0x33333333
598-
; X86-NOBMI-NEXT: shrl $2, %eax
599-
; X86-NOBMI-NEXT: andl $858993459, %eax # imm = 0x33333333
600-
; X86-NOBMI-NEXT: leal (%eax,%ecx,4), %eax
601-
; X86-NOBMI-NEXT: movl %eax, %ecx
602-
; X86-NOBMI-NEXT: andl $1431655765, %ecx # imm = 0x55555555
603-
; X86-NOBMI-NEXT: shrl %eax
604-
; X86-NOBMI-NEXT: andl $1431655765, %eax # imm = 0x55555555
605-
; X86-NOBMI-NEXT: leal (%eax,%ecx,2), %eax
606-
; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax
613+
; X86-NOBMI-NEXT: notl %edx
607614
; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %edx
608615
; X86-NOBMI-NEXT: retl
609616
;
@@ -651,7 +658,6 @@ define i64 @andnot_bitreverse_i64(i64 %a0, i64 %a1) nounwind {
651658
;
652659
; X64-NOBMI-LABEL: andnot_bitreverse_i64:
653660
; X64-NOBMI: # %bb.0:
654-
; X64-NOBMI-NEXT: notq %rsi
655661
; X64-NOBMI-NEXT: bswapq %rsi
656662
; X64-NOBMI-NEXT: movq %rsi, %rax
657663
; X64-NOBMI-NEXT: shrq $4, %rax
@@ -672,6 +678,7 @@ define i64 @andnot_bitreverse_i64(i64 %a0, i64 %a1) nounwind {
672678
; X64-NOBMI-NEXT: shrq %rax
673679
; X64-NOBMI-NEXT: andq %rcx, %rax
674680
; X64-NOBMI-NEXT: leaq (%rax,%rdx,2), %rax
681+
; X64-NOBMI-NEXT: notq %rax
675682
; X64-NOBMI-NEXT: andq %rdi, %rax
676683
; X64-NOBMI-NEXT: retq
677684
;
@@ -709,7 +716,6 @@ define i32 @andnot_bitreverse_i32(i32 %a0, i32 %a1) nounwind {
709716
; X86-NOBMI-LABEL: andnot_bitreverse_i32:
710717
; X86-NOBMI: # %bb.0:
711718
; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %eax
712-
; X86-NOBMI-NEXT: notl %eax
713719
; X86-NOBMI-NEXT: bswapl %eax
714720
; X86-NOBMI-NEXT: movl %eax, %ecx
715721
; X86-NOBMI-NEXT: andl $252645135, %ecx # imm = 0xF0F0F0F
@@ -727,6 +733,7 @@ define i32 @andnot_bitreverse_i32(i32 %a0, i32 %a1) nounwind {
727733
; X86-NOBMI-NEXT: shrl %eax
728734
; X86-NOBMI-NEXT: andl $1431655765, %eax # imm = 0x55555555
729735
; X86-NOBMI-NEXT: leal (%eax,%ecx,2), %eax
736+
; X86-NOBMI-NEXT: notl %eax
730737
; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax
731738
; X86-NOBMI-NEXT: retl
732739
;
@@ -756,7 +763,6 @@ define i32 @andnot_bitreverse_i32(i32 %a0, i32 %a1) nounwind {
756763
; X64-NOBMI-LABEL: andnot_bitreverse_i32:
757764
; X64-NOBMI: # %bb.0:
758765
; X64-NOBMI-NEXT: # kill: def $esi killed $esi def $rsi
759-
; X64-NOBMI-NEXT: notl %esi
760766
; X64-NOBMI-NEXT: bswapl %esi
761767
; X64-NOBMI-NEXT: movl %esi, %eax
762768
; X64-NOBMI-NEXT: andl $252645135, %eax # imm = 0xF0F0F0F
@@ -774,6 +780,7 @@ define i32 @andnot_bitreverse_i32(i32 %a0, i32 %a1) nounwind {
774780
; X64-NOBMI-NEXT: shrl %eax
775781
; X64-NOBMI-NEXT: andl $1431655765, %eax # imm = 0x55555555
776782
; X64-NOBMI-NEXT: leal (%rax,%rcx,2), %eax
783+
; X64-NOBMI-NEXT: notl %eax
777784
; X64-NOBMI-NEXT: andl %edi, %eax
778785
; X64-NOBMI-NEXT: retq
779786
;
@@ -808,8 +815,7 @@ define i32 @andnot_bitreverse_i32(i32 %a0, i32 %a1) nounwind {
808815
define i16 @andnot_bitreverse_i16(i16 %a0, i16 %a1) nounwind {
809816
; X86-LABEL: andnot_bitreverse_i16:
810817
; X86: # %bb.0:
811-
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
812-
; X86-NEXT: notl %eax
818+
; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
813819
; X86-NEXT: rolw $8, %ax
814820
; X86-NEXT: movl %eax, %ecx
815821
; X86-NEXT: andl $3855, %ecx # imm = 0xF0F
@@ -827,34 +833,59 @@ define i16 @andnot_bitreverse_i16(i16 %a0, i16 %a1) nounwind {
827833
; X86-NEXT: shrl %eax
828834
; X86-NEXT: andl $21845, %eax # imm = 0x5555
829835
; X86-NEXT: leal (%eax,%ecx,2), %eax
836+
; X86-NEXT: notl %eax
830837
; X86-NEXT: andw {{[0-9]+}}(%esp), %ax
831838
; X86-NEXT: # kill: def $ax killed $ax killed $eax
832839
; X86-NEXT: retl
833840
;
834-
; X64-LABEL: andnot_bitreverse_i16:
835-
; X64: # %bb.0:
836-
; X64-NEXT: # kill: def $esi killed $esi def $rsi
837-
; X64-NEXT: notl %esi
838-
; X64-NEXT: rolw $8, %si
839-
; X64-NEXT: movl %esi, %eax
840-
; X64-NEXT: andl $3855, %eax # imm = 0xF0F
841-
; X64-NEXT: shll $4, %eax
842-
; X64-NEXT: shrl $4, %esi
843-
; X64-NEXT: andl $3855, %esi # imm = 0xF0F
844-
; X64-NEXT: orl %eax, %esi
845-
; X64-NEXT: movl %esi, %eax
846-
; X64-NEXT: andl $13107, %eax # imm = 0x3333
847-
; X64-NEXT: shrl $2, %esi
848-
; X64-NEXT: andl $13107, %esi # imm = 0x3333
849-
; X64-NEXT: leal (%rsi,%rax,4), %eax
850-
; X64-NEXT: movl %eax, %ecx
851-
; X64-NEXT: andl $21845, %ecx # imm = 0x5555
852-
; X64-NEXT: shrl %eax
853-
; X64-NEXT: andl $21845, %eax # imm = 0x5555
854-
; X64-NEXT: leal (%rax,%rcx,2), %eax
855-
; X64-NEXT: andl %edi, %eax
856-
; X64-NEXT: # kill: def $ax killed $ax killed $eax
857-
; X64-NEXT: retq
841+
; X64-NOBMI-LABEL: andnot_bitreverse_i16:
842+
; X64-NOBMI: # %bb.0:
843+
; X64-NOBMI-NEXT: # kill: def $esi killed $esi def $rsi
844+
; X64-NOBMI-NEXT: rolw $8, %si
845+
; X64-NOBMI-NEXT: movl %esi, %eax
846+
; X64-NOBMI-NEXT: andl $3855, %eax # imm = 0xF0F
847+
; X64-NOBMI-NEXT: shll $4, %eax
848+
; X64-NOBMI-NEXT: shrl $4, %esi
849+
; X64-NOBMI-NEXT: andl $3855, %esi # imm = 0xF0F
850+
; X64-NOBMI-NEXT: orl %eax, %esi
851+
; X64-NOBMI-NEXT: movl %esi, %eax
852+
; X64-NOBMI-NEXT: andl $13107, %eax # imm = 0x3333
853+
; X64-NOBMI-NEXT: shrl $2, %esi
854+
; X64-NOBMI-NEXT: andl $13107, %esi # imm = 0x3333
855+
; X64-NOBMI-NEXT: leal (%rsi,%rax,4), %eax
856+
; X64-NOBMI-NEXT: movl %eax, %ecx
857+
; X64-NOBMI-NEXT: andl $21845, %ecx # imm = 0x5555
858+
; X64-NOBMI-NEXT: shrl %eax
859+
; X64-NOBMI-NEXT: andl $21845, %eax # imm = 0x5555
860+
; X64-NOBMI-NEXT: leal (%rax,%rcx,2), %eax
861+
; X64-NOBMI-NEXT: notl %eax
862+
; X64-NOBMI-NEXT: andl %edi, %eax
863+
; X64-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax
864+
; X64-NOBMI-NEXT: retq
865+
;
866+
; X64-BMI-LABEL: andnot_bitreverse_i16:
867+
; X64-BMI: # %bb.0:
868+
; X64-BMI-NEXT: # kill: def $esi killed $esi def $rsi
869+
; X64-BMI-NEXT: rolw $8, %si
870+
; X64-BMI-NEXT: movl %esi, %eax
871+
; X64-BMI-NEXT: andl $3855, %eax # imm = 0xF0F
872+
; X64-BMI-NEXT: shll $4, %eax
873+
; X64-BMI-NEXT: shrl $4, %esi
874+
; X64-BMI-NEXT: andl $3855, %esi # imm = 0xF0F
875+
; X64-BMI-NEXT: orl %eax, %esi
876+
; X64-BMI-NEXT: movl %esi, %eax
877+
; X64-BMI-NEXT: andl $13107, %eax # imm = 0x3333
878+
; X64-BMI-NEXT: shrl $2, %esi
879+
; X64-BMI-NEXT: andl $13107, %esi # imm = 0x3333
880+
; X64-BMI-NEXT: leal (%rsi,%rax,4), %eax
881+
; X64-BMI-NEXT: movl %eax, %ecx
882+
; X64-BMI-NEXT: andl $21845, %ecx # imm = 0x5555
883+
; X64-BMI-NEXT: shrl %eax
884+
; X64-BMI-NEXT: andl $21845, %eax # imm = 0x5555
885+
; X64-BMI-NEXT: leal (%rax,%rcx,2), %eax
886+
; X64-BMI-NEXT: andnl %edi, %eax, %eax
887+
; X64-BMI-NEXT: # kill: def $ax killed $ax killed $eax
888+
; X64-BMI-NEXT: retq
858889
%not = xor i16 %a1, -1
859890
%bitrev = tail call i16 @llvm.bitreverse.i16(i16 %not)
860891
%and = and i16 %bitrev, %a0
@@ -865,7 +896,6 @@ define i8 @andnot_bitreverse_i8(i8 %a0, i8 %a1) nounwind {
865896
; X86-LABEL: andnot_bitreverse_i8:
866897
; X86: # %bb.0:
867898
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
868-
; X86-NEXT: notb %al
869899
; X86-NEXT: rolb $4, %al
870900
; X86-NEXT: movl %eax, %ecx
871901
; X86-NEXT: andb $51, %cl
@@ -879,12 +909,12 @@ define i8 @andnot_bitreverse_i8(i8 %a0, i8 %a1) nounwind {
879909
; X86-NEXT: shrb %al
880910
; X86-NEXT: andb $85, %al
881911
; X86-NEXT: orb %cl, %al
912+
; X86-NEXT: notb %al
882913
; X86-NEXT: andb {{[0-9]+}}(%esp), %al
883914
; X86-NEXT: retl
884915
;
885916
; X64-LABEL: andnot_bitreverse_i8:
886917
; X64: # %bb.0:
887-
; X64-NEXT: notb %sil
888918
; X64-NEXT: rolb $4, %sil
889919
; X64-NEXT: movl %esi, %eax
890920
; X64-NEXT: andb $51, %al
@@ -898,6 +928,7 @@ define i8 @andnot_bitreverse_i8(i8 %a0, i8 %a1) nounwind {
898928
; X64-NEXT: shrb %al
899929
; X64-NEXT: andb $85, %al
900930
; X64-NEXT: orb %cl, %al
931+
; X64-NEXT: notb %al
901932
; X64-NEXT: andb %dil, %al
902933
; X64-NEXT: retq
903934
%not = xor i8 %a1, -1

0 commit comments

Comments
 (0)