mirror of
https://github.com/RPCSX/llvm.git
synced 2025-04-02 16:21:36 +00:00
[DAG] add fold for masked negated extended bool
The non-obvious motivation for adding this fold (which already happens in InstCombine) is that we want to canonicalize IR towards select instructions and canonicalize DAG nodes towards boolean math. So we need to recreate some folds in the DAG to handle that change in direction. An interesting implementation difference for cases like this is that InstCombine generally works top-down while the DAG goes bottom-up. That means we need to detect different patterns. In this case, the SimplifyDemandedBits fold prevents us from performing a zext to sext fold that would then be recognized as a negation of a sext. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283900 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
809c6df3ea
commit
4cc2f1f09a
@ -3314,10 +3314,23 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
|
||||
if (SDValue Tmp = SimplifyBinOpWithSameOpcodeHands(N))
|
||||
return Tmp;
|
||||
|
||||
// Masking the negated extension of a boolean is just the extended boolean:
|
||||
// and (sub 0, zext(bool X)), 1 --> zext(bool X)
|
||||
//
|
||||
// Note: the SimplifyDemandedBits fold below can make an information-losing
|
||||
// transform, and then we have no way to find this better fold.
|
||||
if (N1C && N1C->isOne() && N0.getOpcode() == ISD::SUB) {
|
||||
ConstantSDNode *SubLHS = isConstOrConstSplat(N0.getOperand(0));
|
||||
SDValue SubRHS = N0.getOperand(1);
|
||||
if (SubLHS && SubLHS->isNullValue() &&
|
||||
SubRHS.getOpcode() == ISD::ZERO_EXTEND &&
|
||||
SubRHS.getOperand(0).getScalarValueSizeInBits() == 1)
|
||||
return SubRHS;
|
||||
}
|
||||
|
||||
// fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1)
|
||||
// fold (and (sra)) -> (and (srl)) when possible.
|
||||
if (!VT.isVector() &&
|
||||
SimplifyDemandedBits(SDValue(N, 0)))
|
||||
if (!VT.isVector() && SimplifyDemandedBits(SDValue(N, 0)))
|
||||
return SDValue(N, 0);
|
||||
|
||||
// fold (zext_inreg (extload x)) -> (zextload x)
|
||||
|
@ -4,7 +4,6 @@
|
||||
define i32 @mask_negated_extended_bool1(i1 %x) {
|
||||
; CHECK-LABEL: mask_negated_extended_bool1:
|
||||
; CHECK: # BB#0:
|
||||
; CHECK-NEXT: negl %edi
|
||||
; CHECK-NEXT: andl $1, %edi
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
@ -19,8 +18,6 @@ define i32 @mask_negated_extended_bool2(i1 zeroext %x) {
|
||||
; CHECK-LABEL: mask_negated_extended_bool2:
|
||||
; CHECK: # BB#0:
|
||||
; CHECK-NEXT: movzbl %dil, %eax
|
||||
; CHECK-NEXT: negl %eax
|
||||
; CHECK-NEXT: andl $1, %eax
|
||||
; CHECK-NEXT: retq
|
||||
;
|
||||
%ext = zext i1 %x to i32
|
||||
@ -32,12 +29,7 @@ define i32 @mask_negated_extended_bool2(i1 zeroext %x) {
|
||||
define <4 x i32> @mask_negated_extended_bool_vec(<4 x i1> %x) {
|
||||
; CHECK-LABEL: mask_negated_extended_bool_vec:
|
||||
; CHECK: # BB#0:
|
||||
; CHECK-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1]
|
||||
; CHECK-NEXT: pand %xmm2, %xmm0
|
||||
; CHECK-NEXT: pxor %xmm1, %xmm1
|
||||
; CHECK-NEXT: psubd %xmm0, %xmm1
|
||||
; CHECK-NEXT: pand %xmm2, %xmm1
|
||||
; CHECK-NEXT: movdqa %xmm1, %xmm0
|
||||
; CHECK-NEXT: andps {{.*}}(%rip), %xmm0
|
||||
; CHECK-NEXT: retq
|
||||
;
|
||||
%ext = zext <4 x i1> %x to <4 x i32>
|
||||
|
Loading…
x
Reference in New Issue
Block a user