[llvm] 2e3de99 - [DAG] Generalize setcc(setcc) fold to use known bits.
David Green via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 6 04:39:53 PST 2024
Author: David Green
Date: 2024-02-06T12:39:48Z
New Revision: 2e3de997ab7cd8728c484bc39e24fecbb97dfae8
URL: https://github.com/llvm/llvm-project/commit/2e3de997ab7cd8728c484bc39e24fecbb97dfae8
DIFF: https://github.com/llvm/llvm-project/commit/2e3de997ab7cd8728c484bc39e24fecbb97dfae8.diff
LOG: [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.
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/test/CodeGen/AArch64/setcc_knownbits.ll
llvm/test/CodeGen/WebAssembly/xor_reassociate.ll
llvm/test/CodeGen/X86/lzcnt-cmp.ll
llvm/test/CodeGen/X86/umul_fix_sat.ll
llvm/test/CodeGen/X86/xor.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index b15f62bc3aae7..a4987de43779a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -4718,21 +4718,25 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
DAG.getConstant(C1 & Imm, dl, ExtDstTy), Cond);
} else if ((N1C->isZero() || N1C->isOne()) &&
(Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
- // SETCC (SETCC), [0|1], [EQ|NE] -> SETCC
- if (N0.getOpcode() == ISD::SETCC &&
+ // SETCC (X), [0|1], [EQ|NE] -> X if X is known 0/1. i1 types are
+ // excluded as they are handled below whilst checking for foldBooleans.
+ if ((N0.getOpcode() == ISD::SETCC || VT.getScalarType() != MVT::i1) &&
isTypeLegal(VT) && VT.bitsLE(N0.getValueType()) &&
(N0.getValueType() == MVT::i1 ||
- getBooleanContents(N0.getOperand(0).getValueType()) ==
- ZeroOrOneBooleanContent)) {
+ getBooleanContents(N0.getValueType()) == ZeroOrOneBooleanContent) &&
+ DAG.MaskedValueIsZero(
+ N0, APInt::getBitsSetFrom(N0.getValueSizeInBits(), 1))) {
bool TrueWhenTrue = (Cond == ISD::SETEQ) ^ (!N1C->isOne());
if (TrueWhenTrue)
return DAG.getNode(ISD::TRUNCATE, dl, VT, N0);
// Invert the condition.
- ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
- CC = ISD::getSetCCInverse(CC, N0.getOperand(0).getValueType());
- if (DCI.isBeforeLegalizeOps() ||
- isCondCodeLegal(CC, N0.getOperand(0).getSimpleValueType()))
- return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
+ if (N0.getOpcode() == ISD::SETCC) {
+ ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
+ CC = ISD::getSetCCInverse(CC, N0.getOperand(0).getValueType());
+ if (DCI.isBeforeLegalizeOps() ||
+ isCondCodeLegal(CC, N0.getOperand(0).getSimpleValueType()))
+ return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
+ }
}
if ((N0.getOpcode() == ISD::XOR ||
diff --git a/llvm/test/CodeGen/AArch64/setcc_knownbits.ll b/llvm/test/CodeGen/AArch64/setcc_knownbits.ll
index af5c1586a4c67..9e9c814be0266 100644
--- a/llvm/test/CodeGen/AArch64/setcc_knownbits.ll
+++ b/llvm/test/CodeGen/AArch64/setcc_knownbits.ll
@@ -49,9 +49,8 @@ define i1 @lshr_ctlz_undef_cmpeq_one_i64(i64 %in) {
; CHECK-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
; CHECK: // %bb.0:
; CHECK-NEXT: clz x8, x0
-; CHECK-NEXT: lsr x8, x8, #6
-; CHECK-NEXT: cmp x8, #1
-; CHECK-NEXT: cset w0, eq
+; CHECK-NEXT: lsr x0, x8, #6
+; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
; CHECK-NEXT: ret
%ctlz = call i64 @llvm.ctlz.i64(i64 %in, i1 -1)
%lshr = lshr i64 %ctlz, 6
diff --git a/llvm/test/CodeGen/WebAssembly/xor_reassociate.ll b/llvm/test/CodeGen/WebAssembly/xor_reassociate.ll
index 9ef9c14084a7d..3dd8463d9dd10 100644
--- a/llvm/test/CodeGen/WebAssembly/xor_reassociate.ll
+++ b/llvm/test/CodeGen/WebAssembly/xor_reassociate.ll
@@ -17,7 +17,7 @@ define i32 @reassociate_xor(float %x, float %y) {
; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32.const 0x1p-23
; CHECK-NEXT: f32.gt
-; CHECK-NEXT: i32.ne
+; CHECK-NEXT: i32.xor
; CHECK-NEXT: br_if 0 # 0: down to label0
; CHECK-NEXT: # %bb.1: # %if.then.i
; CHECK-NEXT: i32.const 0
diff --git a/llvm/test/CodeGen/X86/lzcnt-cmp.ll b/llvm/test/CodeGen/X86/lzcnt-cmp.ll
index c1cce6f5d8ca1..6c8d5c9d55a6d 100644
--- a/llvm/test/CodeGen/X86/lzcnt-cmp.ll
+++ b/llvm/test/CodeGen/X86/lzcnt-cmp.ll
@@ -50,35 +50,33 @@ define i1 @lshr_ctlz_undef_cmpeq_one_i64(i64 %in) nounwind {
; X86-BSR-NEXT: xorl $31, %eax
; X86-BSR-NEXT: addl $32, %eax
; X86-BSR-NEXT: .LBB1_2:
-; X86-BSR-NEXT: testl $-64, %eax
-; X86-BSR-NEXT: setne %al
+; X86-BSR-NEXT: shrl $6, %eax
+; X86-BSR-NEXT: # kill: def $al killed $al killed $eax
; X86-BSR-NEXT: retl
;
; X86-LZCNT-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
; X86-LZCNT: # %bb.0:
-; X86-LZCNT-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
-; X86-LZCNT-NEXT: addl $32, %eax
-; X86-LZCNT-NEXT: xorl %ecx, %ecx
+; X86-LZCNT-NEXT: lzcntl {{[0-9]+}}(%esp), %ecx
+; X86-LZCNT-NEXT: addl $32, %ecx
+; X86-LZCNT-NEXT: xorl %eax, %eax
; X86-LZCNT-NEXT: cmpl $0, {{[0-9]+}}(%esp)
-; X86-LZCNT-NEXT: cmovel %eax, %ecx
-; X86-LZCNT-NEXT: testb $64, %cl
-; X86-LZCNT-NEXT: setne %al
+; X86-LZCNT-NEXT: cmovel %ecx, %eax
+; X86-LZCNT-NEXT: shrl $6, %eax
+; X86-LZCNT-NEXT: # kill: def $al killed $al killed $eax
; X86-LZCNT-NEXT: retl
;
; X64-BSR-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
; X64-BSR: # %bb.0:
; X64-BSR-NEXT: bsrq %rdi, %rax
; X64-BSR-NEXT: shrl $6, %eax
-; X64-BSR-NEXT: cmpl $1, %eax
-; X64-BSR-NEXT: sete %al
+; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
; X64-BSR-NEXT: retq
;
; X64-LZCNT-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
; X64-LZCNT: # %bb.0:
; X64-LZCNT-NEXT: lzcntq %rdi, %rax
; X64-LZCNT-NEXT: shrl $6, %eax
-; X64-LZCNT-NEXT: cmpl $1, %eax
-; X64-LZCNT-NEXT: sete %al
+; X64-LZCNT-NEXT: # kill: def $al killed $al killed $rax
; X64-LZCNT-NEXT: retq
%ctlz = call i64 @llvm.ctlz.i64(i64 %in, i1 -1)
%lshr = lshr i64 %ctlz, 6
@@ -131,33 +129,33 @@ define i1 @lshr_ctlz_undef_cmpne_zero_i64(i64 %in) nounwind {
; X86-BSR-NEXT: xorl $31, %eax
; X86-BSR-NEXT: addl $32, %eax
; X86-BSR-NEXT: .LBB3_2:
-; X86-BSR-NEXT: testl $-64, %eax
-; X86-BSR-NEXT: setne %al
+; X86-BSR-NEXT: shrl $6, %eax
+; X86-BSR-NEXT: # kill: def $al killed $al killed $eax
; X86-BSR-NEXT: retl
;
; X86-LZCNT-LABEL: lshr_ctlz_undef_cmpne_zero_i64:
; X86-LZCNT: # %bb.0:
-; X86-LZCNT-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
-; X86-LZCNT-NEXT: addl $32, %eax
-; X86-LZCNT-NEXT: xorl %ecx, %ecx
+; X86-LZCNT-NEXT: lzcntl {{[0-9]+}}(%esp), %ecx
+; X86-LZCNT-NEXT: addl $32, %ecx
+; X86-LZCNT-NEXT: xorl %eax, %eax
; X86-LZCNT-NEXT: cmpl $0, {{[0-9]+}}(%esp)
-; X86-LZCNT-NEXT: cmovel %eax, %ecx
-; X86-LZCNT-NEXT: testb $64, %cl
-; X86-LZCNT-NEXT: setne %al
+; X86-LZCNT-NEXT: cmovel %ecx, %eax
+; X86-LZCNT-NEXT: shrl $6, %eax
+; X86-LZCNT-NEXT: # kill: def $al killed $al killed $eax
; X86-LZCNT-NEXT: retl
;
; X64-BSR-LABEL: lshr_ctlz_undef_cmpne_zero_i64:
; X64-BSR: # %bb.0:
; X64-BSR-NEXT: bsrq %rdi, %rax
-; X64-BSR-NEXT: testl $-64, %eax
-; X64-BSR-NEXT: setne %al
+; X64-BSR-NEXT: shrl $6, %eax
+; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
; X64-BSR-NEXT: retq
;
; X64-LZCNT-LABEL: lshr_ctlz_undef_cmpne_zero_i64:
; X64-LZCNT: # %bb.0:
; X64-LZCNT-NEXT: lzcntq %rdi, %rax
-; X64-LZCNT-NEXT: testb $64, %al
-; X64-LZCNT-NEXT: setne %al
+; X64-LZCNT-NEXT: shrl $6, %eax
+; X64-LZCNT-NEXT: # kill: def $al killed $al killed $rax
; X64-LZCNT-NEXT: retq
%ctlz = call i64 @llvm.ctlz.i64(i64 %in, i1 -1)
%lshr = lshr i64 %ctlz, 6
diff --git a/llvm/test/CodeGen/X86/umul_fix_sat.ll b/llvm/test/CodeGen/X86/umul_fix_sat.ll
index 6b6845147e043..8c7078c726328 100644
--- a/llvm/test/CodeGen/X86/umul_fix_sat.ll
+++ b/llvm/test/CodeGen/X86/umul_fix_sat.ll
@@ -517,15 +517,13 @@ define i64 @func8(i64 %x, i64 %y) nounwind {
; X86-NEXT: adcl $0, %ecx
; X86-NEXT: addl %ebp, %edx
; X86-NEXT: adcl $0, %ecx
+; X86-NEXT: shldl $1, %edx, %ecx
; X86-NEXT: shrdl $31, %edx, %eax
-; X86-NEXT: movl %edx, %esi
-; X86-NEXT: shrl $31, %esi
-; X86-NEXT: xorl %edi, %edi
-; X86-NEXT: negl %esi
-; X86-NEXT: sbbl %edi, %edi
-; X86-NEXT: orl %edi, %eax
-; X86-NEXT: shrdl $31, %ecx, %edx
-; X86-NEXT: orl %edi, %edx
+; X86-NEXT: testl $-2147483648, %edx # imm = 0x80000000
+; X86-NEXT: movl $-1, %edx
+; X86-NEXT: cmovnel %edx, %eax
+; X86-NEXT: cmovnel %edx, %ecx
+; X86-NEXT: movl %ecx, %edx
; X86-NEXT: popl %esi
; X86-NEXT: popl %edi
; X86-NEXT: popl %ebx
diff --git a/llvm/test/CodeGen/X86/xor.ll b/llvm/test/CodeGen/X86/xor.ll
index 2072568b7ba75..8c8b7cc516105 100644
--- a/llvm/test/CodeGen/X86/xor.ll
+++ b/llvm/test/CodeGen/X86/xor.ll
@@ -403,14 +403,19 @@ define i32 @PR17487(i1 %tobool) {
;
; X64-LIN-LABEL: PR17487:
; X64-LIN: # %bb.0:
-; X64-LIN-NEXT: movl %edi, %eax
-; X64-LIN-NEXT: andl $1, %eax
+; X64-LIN-NEXT: movd %edi, %xmm0
+; X64-LIN-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
+; X64-LIN-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-LIN-NEXT: pextrw $4, %xmm0, %eax
; X64-LIN-NEXT: retq
;
; X64-WIN-LABEL: PR17487:
; X64-WIN: # %bb.0:
-; X64-WIN-NEXT: andb $1, %cl
; X64-WIN-NEXT: movzbl %cl, %eax
+; X64-WIN-NEXT: movd %eax, %xmm0
+; X64-WIN-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
+; X64-WIN-NEXT: pand __xmm at 00000000000000010000000000000001(%rip), %xmm0
+; X64-WIN-NEXT: pextrw $4, %xmm0, %eax
; X64-WIN-NEXT: retq
%tmp = insertelement <2 x i1> undef, i1 %tobool, i32 1
%tmp1 = zext <2 x i1> %tmp to <2 x i64>
More information about the llvm-commits
mailing list