summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp16
-rw-r--r--llvm/test/CodeGen/X86/mask-negated-bool.ll10
2 files changed, 12 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 7118b4cbf0e..b8dad384f6c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3314,18 +3314,24 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
if (SDValue Tmp = SimplifyBinOpWithSameOpcodeHands(N))
return Tmp;
- // Masking the negated extension of a boolean is just the extended boolean:
+ // Masking the negated extension of a boolean is just the zero-extended
+ // boolean:
// and (sub 0, zext(bool X)), 1 --> zext(bool X)
+ // and (sub 0, sext(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;
+ if (SubLHS && SubLHS->isNullValue()) {
+ if (SubRHS.getOpcode() == ISD::ZERO_EXTEND &&
+ SubRHS.getOperand(0).getScalarValueSizeInBits() == 1)
+ return SubRHS;
+ if (SubRHS.getOpcode() == ISD::SIGN_EXTEND &&
+ SubRHS.getOperand(0).getScalarValueSizeInBits() == 1)
+ return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), VT, SubRHS.getOperand(0));
+ }
}
// fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1)
diff --git a/llvm/test/CodeGen/X86/mask-negated-bool.ll b/llvm/test/CodeGen/X86/mask-negated-bool.ll
index 45c111ca64f..c5c121c5296 100644
--- a/llvm/test/CodeGen/X86/mask-negated-bool.ll
+++ b/llvm/test/CodeGen/X86/mask-negated-bool.ll
@@ -41,7 +41,6 @@ define <4 x i32> @mask_negated_zext_bool_vec(<4 x i1> %x) {
define i32 @mask_negated_sext_bool1(i1 %x) {
; CHECK-LABEL: mask_negated_sext_bool1:
; CHECK: # BB#0:
-; CHECK-NEXT: negl %edi
; CHECK-NEXT: andl $1, %edi
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: retq
@@ -56,8 +55,6 @@ define i32 @mask_negated_sext_bool2(i1 zeroext %x) {
; CHECK-LABEL: mask_negated_sext_bool2:
; CHECK: # BB#0:
; CHECK-NEXT: movzbl %dil, %eax
-; CHECK-NEXT: negl %eax
-; CHECK-NEXT: andl $1, %eax
; CHECK-NEXT: retq
;
%ext = sext i1 %x to i32
@@ -69,12 +66,7 @@ define i32 @mask_negated_sext_bool2(i1 zeroext %x) {
define <4 x i32> @mask_negated_sext_bool_vec(<4 x i1> %x) {
; CHECK-LABEL: mask_negated_sext_bool_vec:
; CHECK: # BB#0:
-; CHECK-NEXT: pslld $31, %xmm0
-; CHECK-NEXT: psrad $31, %xmm0
-; CHECK-NEXT: pxor %xmm1, %xmm1
-; CHECK-NEXT: psubd %xmm0, %xmm1
-; CHECK-NEXT: pand {{.*}}(%rip), %xmm1
-; CHECK-NEXT: movdqa %xmm1, %xmm0
+; CHECK-NEXT: andps {{.*}}(%rip), %xmm0
; CHECK-NEXT: retq
;
%ext = sext <4 x i1> %x to <4 x i32>
OpenPOWER on IntegriCloud