From b7f5bb80075c995f855e921c2fc592c2b898dc61 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 26 Apr 2017 14:05:42 +0000 Subject: [PATCH] [TargetLowering] fix isConstTrueVal to account for build vector truncation Build vectors have magical truncation powers, so we have things like this: v4i1 = BUILD_VECTOR Constant:i32<1>, Constant:i32<1>, Constant:i32<1>, Constant:i32<1> v4i16 = BUILD_VECTOR Constant:i32<1>, Constant:i32<1>, Constant:i32<1>, Constant:i32<1> If we don't truncate the splat node returned by getConstantSplatNode(), then we won't find truth when ZeroOrNegativeOneBooleanContent is the rule. Differential Revision: https://reviews.llvm.org/D32505 llvm-svn: 301408 --- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 30 ++++++++++++--------- test/CodeGen/X86/setcc-combine.ll | 28 +++++++++---------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 18b238d4e35..136dec873cb 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1371,27 +1371,31 @@ bool TargetLowering::isConstTrueVal(const SDNode *N) const { if (!N) return false; - const ConstantSDNode *CN = dyn_cast(N); - if (!CN) { - const BuildVectorSDNode *BV = dyn_cast(N); - if (!BV) - return false; - - // Only interested in constant splats, we don't care about undef - // elements in identifying boolean constants and getConstantSplatNode - // returns NULL if all ops are undef; - CN = BV->getConstantSplatNode(); + APInt CVal; + if (auto *CN = dyn_cast(N)) { + CVal = CN->getAPIntValue(); + } else if (auto *BV = dyn_cast(N)) { + auto *CN = BV->getConstantSplatNode(); if (!CN) return false; + + // If this is a truncating build vector, truncate the splat value. + // Otherwise, we may fail to match the expected values below. + unsigned BVEltWidth = BV->getValueType(0).getScalarSizeInBits(); + CVal = CN->getAPIntValue(); + if (BVEltWidth < CVal.getBitWidth()) + CVal = CVal.trunc(BVEltWidth); + } else { + return false; } switch (getBooleanContents(N->getValueType(0))) { case UndefinedBooleanContent: - return CN->getAPIntValue()[0]; + return CVal[0]; case ZeroOrOneBooleanContent: - return CN->isOne(); + return CVal == 1; case ZeroOrNegativeOneBooleanContent: - return CN->isAllOnesValue(); + return CVal.isAllOnesValue(); } llvm_unreachable("Invalid boolean contents"); diff --git a/test/CodeGen/X86/setcc-combine.ll b/test/CodeGen/X86/setcc-combine.ll index a7c5dec4856..38205c66073 100644 --- a/test/CodeGen/X86/setcc-combine.ll +++ b/test/CodeGen/X86/setcc-combine.ll @@ -5,11 +5,10 @@ define i32 @test_eq_1(<4 x i32> %A, <4 x i32> %B) { ; CHECK-LABEL: test_eq_1: ; CHECK: # BB#0: ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 -; CHECK-NEXT: pxor {{.*}}(%rip), %xmm1 -; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3] +; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 +; CHECK-NEXT: pxor %xmm1, %xmm0 +; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3] ; CHECK-NEXT: movd %xmm0, %eax -; CHECK-NEXT: andl $1, %eax -; CHECK-NEXT: negl %eax ; CHECK-NEXT: retq %cmp = icmp slt <4 x i32> %A, %B %sext = sext <4 x i1> %cmp to <4 x i32> @@ -51,11 +50,10 @@ define i32 @test_ge_1(<4 x i32> %A, <4 x i32> %B) { ; CHECK-LABEL: test_ge_1: ; CHECK: # BB#0: ; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 -; CHECK-NEXT: pxor {{.*}}(%rip), %xmm1 -; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3] +; CHECK-NEXT: pcmpeqd %xmm0, %xmm0 +; CHECK-NEXT: pxor %xmm1, %xmm0 +; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3] ; CHECK-NEXT: movd %xmm0, %eax -; CHECK-NEXT: andl $1, %eax -; CHECK-NEXT: negl %eax ; CHECK-NEXT: retq %cmp = icmp slt <4 x i32> %A, %B %sext = sext <4 x i1> %cmp to <4 x i32> @@ -97,11 +95,10 @@ define i32 @test_eq_2(<4 x i32> %A, <4 x i32> %B) { ; CHECK-LABEL: test_eq_2: ; CHECK: # BB#0: ; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 -; CHECK-NEXT: pxor {{.*}}(%rip), %xmm0 -; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3] +; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 +; CHECK-NEXT: pxor %xmm0, %xmm1 +; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3] ; CHECK-NEXT: movd %xmm0, %eax -; CHECK-NEXT: andl $1, %eax -; CHECK-NEXT: negl %eax ; CHECK-NEXT: retq %cmp = icmp slt <4 x i32> %B, %A %sext = sext <4 x i1> %cmp to <4 x i32> @@ -130,11 +127,10 @@ define i32 @test_le_2(<4 x i32> %A, <4 x i32> %B) { ; CHECK-LABEL: test_le_2: ; CHECK: # BB#0: ; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 -; CHECK-NEXT: pxor {{.*}}(%rip), %xmm0 -; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3] +; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 +; CHECK-NEXT: pxor %xmm0, %xmm1 +; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3] ; CHECK-NEXT: movd %xmm0, %eax -; CHECK-NEXT: andl $1, %eax -; CHECK-NEXT: negl %eax ; CHECK-NEXT: retq %cmp = icmp slt <4 x i32> %B, %A %sext = sext <4 x i1> %cmp to <4 x i32>