Skip to content

Commit 2e3de99

Browse files
committed
[DAG] Generalize setcc(setcc) fold to use known bits.
If we have a `SETCC (SETCC), 0, NE` and ZeroOrOneBooleanContent, we can remove the outer setcc as it will produce the same value as the inner. This can be generalized to anything where the top bits are known to be 0, as the value will remain as 1 or 0.
1 parent 29fa64f commit 2e3de99

File tree

6 files changed

+52
-48
lines changed

6 files changed

+52
-48
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4718,21 +4718,25 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
47184718
DAG.getConstant(C1 & Imm, dl, ExtDstTy), Cond);
47194719
} else if ((N1C->isZero() || N1C->isOne()) &&
47204720
(Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
4721-
// SETCC (SETCC), [0|1], [EQ|NE] -> SETCC
4722-
if (N0.getOpcode() == ISD::SETCC &&
4721+
// SETCC (X), [0|1], [EQ|NE] -> X if X is known 0/1. i1 types are
4722+
// excluded as they are handled below whilst checking for foldBooleans.
4723+
if ((N0.getOpcode() == ISD::SETCC || VT.getScalarType() != MVT::i1) &&
47234724
isTypeLegal(VT) && VT.bitsLE(N0.getValueType()) &&
47244725
(N0.getValueType() == MVT::i1 ||
4725-
getBooleanContents(N0.getOperand(0).getValueType()) ==
4726-
ZeroOrOneBooleanContent)) {
4726+
getBooleanContents(N0.getValueType()) == ZeroOrOneBooleanContent) &&
4727+
DAG.MaskedValueIsZero(
4728+
N0, APInt::getBitsSetFrom(N0.getValueSizeInBits(), 1))) {
47274729
bool TrueWhenTrue = (Cond == ISD::SETEQ) ^ (!N1C->isOne());
47284730
if (TrueWhenTrue)
47294731
return DAG.getNode(ISD::TRUNCATE, dl, VT, N0);
47304732
// Invert the condition.
4731-
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
4732-
CC = ISD::getSetCCInverse(CC, N0.getOperand(0).getValueType());
4733-
if (DCI.isBeforeLegalizeOps() ||
4734-
isCondCodeLegal(CC, N0.getOperand(0).getSimpleValueType()))
4735-
return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
4733+
if (N0.getOpcode() == ISD::SETCC) {
4734+
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
4735+
CC = ISD::getSetCCInverse(CC, N0.getOperand(0).getValueType());
4736+
if (DCI.isBeforeLegalizeOps() ||
4737+
isCondCodeLegal(CC, N0.getOperand(0).getSimpleValueType()))
4738+
return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
4739+
}
47364740
}
47374741

47384742
if ((N0.getOpcode() == ISD::XOR ||

llvm/test/CodeGen/AArch64/setcc_knownbits.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ define i1 @lshr_ctlz_undef_cmpeq_one_i64(i64 %in) {
4949
; CHECK-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
5050
; CHECK: // %bb.0:
5151
; CHECK-NEXT: clz x8, x0
52-
; CHECK-NEXT: lsr x8, x8, #6
53-
; CHECK-NEXT: cmp x8, #1
54-
; CHECK-NEXT: cset w0, eq
52+
; CHECK-NEXT: lsr x0, x8, #6
53+
; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
5554
; CHECK-NEXT: ret
5655
%ctlz = call i64 @llvm.ctlz.i64(i64 %in, i1 -1)
5756
%lshr = lshr i64 %ctlz, 6

llvm/test/CodeGen/WebAssembly/xor_reassociate.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ define i32 @reassociate_xor(float %x, float %y) {
1717
; CHECK-NEXT: local.get 0
1818
; CHECK-NEXT: f32.const 0x1p-23
1919
; CHECK-NEXT: f32.gt
20-
; CHECK-NEXT: i32.ne
20+
; CHECK-NEXT: i32.xor
2121
; CHECK-NEXT: br_if 0 # 0: down to label0
2222
; CHECK-NEXT: # %bb.1: # %if.then.i
2323
; CHECK-NEXT: i32.const 0

llvm/test/CodeGen/X86/lzcnt-cmp.ll

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,35 +50,33 @@ define i1 @lshr_ctlz_undef_cmpeq_one_i64(i64 %in) nounwind {
5050
; X86-BSR-NEXT: xorl $31, %eax
5151
; X86-BSR-NEXT: addl $32, %eax
5252
; X86-BSR-NEXT: .LBB1_2:
53-
; X86-BSR-NEXT: testl $-64, %eax
54-
; X86-BSR-NEXT: setne %al
53+
; X86-BSR-NEXT: shrl $6, %eax
54+
; X86-BSR-NEXT: # kill: def $al killed $al killed $eax
5555
; X86-BSR-NEXT: retl
5656
;
5757
; X86-LZCNT-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
5858
; X86-LZCNT: # %bb.0:
59-
; X86-LZCNT-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
60-
; X86-LZCNT-NEXT: addl $32, %eax
61-
; X86-LZCNT-NEXT: xorl %ecx, %ecx
59+
; X86-LZCNT-NEXT: lzcntl {{[0-9]+}}(%esp), %ecx
60+
; X86-LZCNT-NEXT: addl $32, %ecx
61+
; X86-LZCNT-NEXT: xorl %eax, %eax
6262
; X86-LZCNT-NEXT: cmpl $0, {{[0-9]+}}(%esp)
63-
; X86-LZCNT-NEXT: cmovel %eax, %ecx
64-
; X86-LZCNT-NEXT: testb $64, %cl
65-
; X86-LZCNT-NEXT: setne %al
63+
; X86-LZCNT-NEXT: cmovel %ecx, %eax
64+
; X86-LZCNT-NEXT: shrl $6, %eax
65+
; X86-LZCNT-NEXT: # kill: def $al killed $al killed $eax
6666
; X86-LZCNT-NEXT: retl
6767
;
6868
; X64-BSR-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
6969
; X64-BSR: # %bb.0:
7070
; X64-BSR-NEXT: bsrq %rdi, %rax
7171
; X64-BSR-NEXT: shrl $6, %eax
72-
; X64-BSR-NEXT: cmpl $1, %eax
73-
; X64-BSR-NEXT: sete %al
72+
; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
7473
; X64-BSR-NEXT: retq
7574
;
7675
; X64-LZCNT-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
7776
; X64-LZCNT: # %bb.0:
7877
; X64-LZCNT-NEXT: lzcntq %rdi, %rax
7978
; X64-LZCNT-NEXT: shrl $6, %eax
80-
; X64-LZCNT-NEXT: cmpl $1, %eax
81-
; X64-LZCNT-NEXT: sete %al
79+
; X64-LZCNT-NEXT: # kill: def $al killed $al killed $rax
8280
; X64-LZCNT-NEXT: retq
8381
%ctlz = call i64 @llvm.ctlz.i64(i64 %in, i1 -1)
8482
%lshr = lshr i64 %ctlz, 6
@@ -131,33 +129,33 @@ define i1 @lshr_ctlz_undef_cmpne_zero_i64(i64 %in) nounwind {
131129
; X86-BSR-NEXT: xorl $31, %eax
132130
; X86-BSR-NEXT: addl $32, %eax
133131
; X86-BSR-NEXT: .LBB3_2:
134-
; X86-BSR-NEXT: testl $-64, %eax
135-
; X86-BSR-NEXT: setne %al
132+
; X86-BSR-NEXT: shrl $6, %eax
133+
; X86-BSR-NEXT: # kill: def $al killed $al killed $eax
136134
; X86-BSR-NEXT: retl
137135
;
138136
; X86-LZCNT-LABEL: lshr_ctlz_undef_cmpne_zero_i64:
139137
; X86-LZCNT: # %bb.0:
140-
; X86-LZCNT-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
141-
; X86-LZCNT-NEXT: addl $32, %eax
142-
; X86-LZCNT-NEXT: xorl %ecx, %ecx
138+
; X86-LZCNT-NEXT: lzcntl {{[0-9]+}}(%esp), %ecx
139+
; X86-LZCNT-NEXT: addl $32, %ecx
140+
; X86-LZCNT-NEXT: xorl %eax, %eax
143141
; X86-LZCNT-NEXT: cmpl $0, {{[0-9]+}}(%esp)
144-
; X86-LZCNT-NEXT: cmovel %eax, %ecx
145-
; X86-LZCNT-NEXT: testb $64, %cl
146-
; X86-LZCNT-NEXT: setne %al
142+
; X86-LZCNT-NEXT: cmovel %ecx, %eax
143+
; X86-LZCNT-NEXT: shrl $6, %eax
144+
; X86-LZCNT-NEXT: # kill: def $al killed $al killed $eax
147145
; X86-LZCNT-NEXT: retl
148146
;
149147
; X64-BSR-LABEL: lshr_ctlz_undef_cmpne_zero_i64:
150148
; X64-BSR: # %bb.0:
151149
; X64-BSR-NEXT: bsrq %rdi, %rax
152-
; X64-BSR-NEXT: testl $-64, %eax
153-
; X64-BSR-NEXT: setne %al
150+
; X64-BSR-NEXT: shrl $6, %eax
151+
; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
154152
; X64-BSR-NEXT: retq
155153
;
156154
; X64-LZCNT-LABEL: lshr_ctlz_undef_cmpne_zero_i64:
157155
; X64-LZCNT: # %bb.0:
158156
; X64-LZCNT-NEXT: lzcntq %rdi, %rax
159-
; X64-LZCNT-NEXT: testb $64, %al
160-
; X64-LZCNT-NEXT: setne %al
157+
; X64-LZCNT-NEXT: shrl $6, %eax
158+
; X64-LZCNT-NEXT: # kill: def $al killed $al killed $rax
161159
; X64-LZCNT-NEXT: retq
162160
%ctlz = call i64 @llvm.ctlz.i64(i64 %in, i1 -1)
163161
%lshr = lshr i64 %ctlz, 6

llvm/test/CodeGen/X86/umul_fix_sat.ll

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -517,15 +517,13 @@ define i64 @func8(i64 %x, i64 %y) nounwind {
517517
; X86-NEXT: adcl $0, %ecx
518518
; X86-NEXT: addl %ebp, %edx
519519
; X86-NEXT: adcl $0, %ecx
520+
; X86-NEXT: shldl $1, %edx, %ecx
520521
; X86-NEXT: shrdl $31, %edx, %eax
521-
; X86-NEXT: movl %edx, %esi
522-
; X86-NEXT: shrl $31, %esi
523-
; X86-NEXT: xorl %edi, %edi
524-
; X86-NEXT: negl %esi
525-
; X86-NEXT: sbbl %edi, %edi
526-
; X86-NEXT: orl %edi, %eax
527-
; X86-NEXT: shrdl $31, %ecx, %edx
528-
; X86-NEXT: orl %edi, %edx
522+
; X86-NEXT: testl $-2147483648, %edx # imm = 0x80000000
523+
; X86-NEXT: movl $-1, %edx
524+
; X86-NEXT: cmovnel %edx, %eax
525+
; X86-NEXT: cmovnel %edx, %ecx
526+
; X86-NEXT: movl %ecx, %edx
529527
; X86-NEXT: popl %esi
530528
; X86-NEXT: popl %edi
531529
; X86-NEXT: popl %ebx

llvm/test/CodeGen/X86/xor.ll

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,14 +403,19 @@ define i32 @PR17487(i1 %tobool) {
403403
;
404404
; X64-LIN-LABEL: PR17487:
405405
; X64-LIN: # %bb.0:
406-
; X64-LIN-NEXT: movl %edi, %eax
407-
; X64-LIN-NEXT: andl $1, %eax
406+
; X64-LIN-NEXT: movd %edi, %xmm0
407+
; X64-LIN-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
408+
; X64-LIN-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
409+
; X64-LIN-NEXT: pextrw $4, %xmm0, %eax
408410
; X64-LIN-NEXT: retq
409411
;
410412
; X64-WIN-LABEL: PR17487:
411413
; X64-WIN: # %bb.0:
412-
; X64-WIN-NEXT: andb $1, %cl
413414
; X64-WIN-NEXT: movzbl %cl, %eax
415+
; X64-WIN-NEXT: movd %eax, %xmm0
416+
; X64-WIN-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
417+
; X64-WIN-NEXT: pand __xmm@00000000000000010000000000000001(%rip), %xmm0
418+
; X64-WIN-NEXT: pextrw $4, %xmm0, %eax
414419
; X64-WIN-NEXT: retq
415420
%tmp = insertelement <2 x i1> undef, i1 %tobool, i32 1
416421
%tmp1 = zext <2 x i1> %tmp to <2 x i64>

0 commit comments

Comments
 (0)