llvm.org GIT mirror llvm / eb7354c
Merging r311429: ------------------------------------------------------------------------ r311429 | ctopper | 2017-08-21 22:40:17 -0700 (Mon, 21 Aug 2017) | 9 lines [X86] Prevent several calls to ISD::isConstantSplatVector from returning a narrower APInt than the original scalar type ISD::isConstantSplatVector can shrink to the smallest splat width. But we don't check the size of the resulting APInt at all. This can cause us to misinterpret the results. This patch just adds a flag to prevent the APInt from changing width. Fixes PR34271. Differential Revision: https://reviews.llvm.org/D36996 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@311462 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 3 years ago
5 changed file(s) with 48 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
8484
8585 /// If N is a BUILD_VECTOR node whose elements are all the same constant or
8686 /// undefined, return true and return the constant value in \p SplatValue.
87 bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
87 /// This sets \p SplatValue to the smallest possible splat unless AllowShrink
88 /// is set to false.
89 bool isConstantSplatVector(const SDNode *N, APInt &SplatValue,
90 bool AllowShrink = true);
8891
8992 /// Return true if the specified node is a BUILD_VECTOR where all of the
9093 /// elements are ~0 or undef.
115115 // ISD Namespace
116116 //===----------------------------------------------------------------------===//
117117
118 bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
118 bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal,
119 bool AllowShrink) {
119120 auto *BV = dyn_cast(N);
120121 if (!BV)
121122 return false;
123124 APInt SplatUndef;
124125 unsigned SplatBitSize;
125126 bool HasUndefs;
126 EVT EltVT = N->getValueType(0).getVectorElementType();
127 return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs) &&
128 EltVT.getSizeInBits() >= SplatBitSize;
127 unsigned EltSize = N->getValueType(0).getVectorElementType().getSizeInBits();
128 unsigned MinSplatBits = AllowShrink ? 0 : EltSize;
129 return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs,
130 MinSplatBits) &&
131 EltSize >= SplatBitSize;
129132 }
130133
131134 // FIXME: AllOnes and AllZeros duplicate a lot of code. Could these be
2953929539 // In SetLT case, The second operand of the comparison can be either 1 or 0.
2954029540 APInt SplatVal;
2954129541 if ((CC == ISD::SETLT) &&
29542 !((ISD::isConstantSplatVector(SetCC.getOperand(1).getNode(), SplatVal) &&
29543 SplatVal == 1) ||
29542 !((ISD::isConstantSplatVector(SetCC.getOperand(1).getNode(), SplatVal,
29543 /*AllowShrink*/false) &&
29544 SplatVal.isOneValue()) ||
2954429545 (ISD::isBuildVectorAllZeros(SetCC.getOperand(1).getNode()))))
2954529546 return false;
2954629547
3205732058 return SDValue();
3205832059
3205932060 APInt SplatVal;
32060 if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal) ||
32061 if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal,
32062 /*AllowShrink*/false) ||
3206132063 !SplatVal.isMask())
3206232064 return SDValue();
3206332065
3264132643 "Unexpected types for truncate operation");
3264232644
3264332645 APInt C;
32644 if (ISD::isConstantSplatVector(In.getOperand(1).getNode(), C)) {
32646 if (ISD::isConstantSplatVector(In.getOperand(1).getNode(), C,
32647 /*AllowShrink*/false)) {
3264532648 // C should be equal to UINT32_MAX / UINT16_MAX / UINT8_MAX according
3264632649 // the element size of the destination type.
3264732650 return C.isMask(VT.getScalarSizeInBits()) ? In.getOperand(0) :
3534535348
3534635349 SDNode *N1 = N->getOperand(1).getNode();
3534735350 APInt SplatVal;
35348 if (!ISD::isConstantSplatVector(N1, SplatVal) || !SplatVal.isOneValue())
35351 if (!ISD::isConstantSplatVector(N1, SplatVal, /*AllowShrink*/false) ||
35352 !SplatVal.isOneValue())
3534935353 return SDValue();
3535035354
3535135355 SDValue AllOnesVec = getOnesVector(VT, DAG, SDLoc(N));
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=avx512vl,avx512bw | FileCheck %s
2
3 define <16 x i16> @foo(<16 x i32> %i) {
4 ; CHECK-LABEL: foo:
5 ; CHECK: # BB#0:
6 ; CHECK-NEXT: vpminud {{.*}}(%rip){1to16}, %zmm0, %zmm0
7 ; CHECK-NEXT: vpmovdw %zmm0, %ymm0
8 ; CHECK-NEXT: retq
9 %x3 = icmp ult <16 x i32> %i,
10 %x5 = select <16 x i1> %x3, <16 x i32> %i, <16 x i32>
11 %x6 = trunc <16 x i32> %x5 to <16 x i16>
12 ret <16 x i16> %x6
13 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
2
3 ; CHECK: .LCPI0_0:
4 ; CHECK-NEXT: .zero 16,1
5
6 define <4 x i32> @f(<4 x i32> %a) {
7 ; CHECK-LABEL: f:
8 ; CHECK: # BB#0:
9 ; CHECK-NEXT: paddd .LCPI0_0(%rip), %xmm0
10 ; CHECK-NEXT: retq
11 %v = add nuw nsw <4 x i32> %a,
12 ret <4 x i32> %v
13 }