mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[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
This commit is contained in:
parent
e93449d911
commit
b7f5bb8007
@ -1371,27 +1371,31 @@ bool TargetLowering::isConstTrueVal(const SDNode *N) const {
|
||||
if (!N)
|
||||
return false;
|
||||
|
||||
const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
|
||||
if (!CN) {
|
||||
const BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(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<ConstantSDNode>(N)) {
|
||||
CVal = CN->getAPIntValue();
|
||||
} else if (auto *BV = dyn_cast<BuildVectorSDNode>(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");
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user