diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h index 4155cb260a2a..5d8ae2794ce9 100644 --- a/llvm/include/llvm/ADT/APInt.h +++ b/llvm/include/llvm/ADT/APInt.h @@ -2239,16 +2239,12 @@ Optional GetMostSignificantDifferentBit(const APInt &A, /// Splat/Merge neighboring bits to widen/narrow the bitmask represented /// by \param A to \param NewBitWidth bits. /// -/// MatchAnyBits: (Default) /// e.g. ScaleBitMask(0b0101, 8) -> 0b00110011 /// e.g. ScaleBitMask(0b00011011, 4) -> 0b0111 -/// -/// MatchAllBits: -/// e.g. ScaleBitMask(0b0101, 8) -> 0b00110011 -/// e.g. ScaleBitMask(0b00011011, 4) -> 0b0001 /// A.getBitwidth() or NewBitWidth must be a whole multiples of the other. -APInt ScaleBitMask(const APInt &A, unsigned NewBitWidth, - bool MatchAllBits = false); +/// +/// TODO: Do we need a mode where all bits must be set when merging down? +APInt ScaleBitMask(const APInt &A, unsigned NewBitWidth); } // namespace APIntOps // See friend declaration above. This additional declaration is required in diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index b3b8756ae9ba..bc1011b69c9d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2712,16 +2712,7 @@ bool SelectionDAG::isSplatValue(SDValue V, const APInt &DemandedElts, SubDemandedElts &= ScaledDemandedElts; if (!isSplatValue(Src, SubDemandedElts, SubUndefElts, Depth + 1)) return false; - - // Here we can't do "MatchAnyBits" operation merge for undef bits. - // Because some operation only use part value of the source. - // Take llvm.fshl.* for example: - // t1: v4i32 = Constant:i32<12>, undef:i32, Constant:i32<12>, undef:i32 - // t2: v2i64 = bitcast t1 - // t5: v2i64 = fshl t3, t4, t2 - // We can not convert t2 to {i64 undef, i64 undef} - UndefElts |= APIntOps::ScaleBitMask(SubUndefElts, NumElts, - /*MatchAllBits=*/true); + UndefElts |= APIntOps::ScaleBitMask(SubUndefElts, NumElts); } return true; } diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index f74178b1ba4e..acc68fe0be95 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -2968,8 +2968,7 @@ llvm::APIntOps::GetMostSignificantDifferentBit(const APInt &A, const APInt &B) { return A.getBitWidth() - ((A ^ B).countLeadingZeros() + 1); } -APInt llvm::APIntOps::ScaleBitMask(const APInt &A, unsigned NewBitWidth, - bool MatchAllBits) { +APInt llvm::APIntOps::ScaleBitMask(const APInt &A, unsigned NewBitWidth) { unsigned OldBitWidth = A.getBitWidth(); assert((((OldBitWidth % NewBitWidth) == 0) || ((NewBitWidth % OldBitWidth) == 0)) && @@ -2993,16 +2992,11 @@ APInt llvm::APIntOps::ScaleBitMask(const APInt &A, unsigned NewBitWidth, if (A[i]) NewA.setBits(i * Scale, (i + 1) * Scale); } else { + // Merge bits - if any old bit is set, then set scale equivalent new bit. unsigned Scale = OldBitWidth / NewBitWidth; - for (unsigned i = 0; i != NewBitWidth; ++i) { - if (MatchAllBits) { - if (A.extractBits(Scale, i * Scale).isAllOnes()) - NewA.setBit(i); - } else { - if (!A.extractBits(Scale, i * Scale).isZero()) - NewA.setBit(i); - } - } + for (unsigned i = 0; i != NewBitWidth; ++i) + if (!A.extractBits(Scale, i * Scale).isZero()) + NewA.setBit(i); } return NewA; diff --git a/llvm/test/CodeGen/X86/fshl-splat-undef.ll b/llvm/test/CodeGen/X86/fshl-splat-undef.ll index 365c3e32e0a0..a0afbdc0cd5f 100644 --- a/llvm/test/CodeGen/X86/fshl-splat-undef.ll +++ b/llvm/test/CodeGen/X86/fshl-splat-undef.ll @@ -20,14 +20,8 @@ define void @test_fshl(<8 x i64> %lo, <8 x i64> %hi, <8 x i64>* %arr) { ; CHECK-LABEL: test_fshl: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: movl $63, %eax -; CHECK-NEXT: vmovd %eax, %xmm2 -; CHECK-NEXT: movl $12, %eax -; CHECK-NEXT: vmovd %eax, %xmm3 -; CHECK-NEXT: vpand %xmm2, %xmm3, %xmm2 -; CHECK-NEXT: vpsllq %xmm2, %zmm1, %zmm1 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax -; CHECK-NEXT: vpsrlq $52, %zmm0, %zmm0 +; CHECK-NEXT: vpsrlq $1, %zmm0, %zmm0 ; CHECK-NEXT: vpternlogq $168, {{\.?LCPI[0-9]+_[0-9]+}}, %zmm1, %zmm0 ; CHECK-NEXT: vmovdqa64 %zmm0, (%eax) ; CHECK-NEXT: vzeroupper diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index 0af294c60969..e92754cc2ccd 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -3115,15 +3115,6 @@ TEST(APIntTest, ScaleBitMask) { APInt::getAllOnes(256)); EXPECT_EQ(APIntOps::ScaleBitMask(APInt::getOneBitSet(4096, 32), 256), APInt::getOneBitSet(256, 2)); - - EXPECT_EQ(APIntOps::ScaleBitMask(APInt(2, 0x00), 8, true), APInt(8, 0x00)); - EXPECT_EQ(APIntOps::ScaleBitMask(APInt(2, 0x01), 8, true), APInt(8, 0x0F)); - EXPECT_EQ(APIntOps::ScaleBitMask(APInt(2, 0x02), 8, true), APInt(8, 0xF0)); - EXPECT_EQ(APIntOps::ScaleBitMask(APInt(2, 0x03), 8, true), APInt(8, 0xFF)); - - EXPECT_EQ(APIntOps::ScaleBitMask(APInt(8, 0x00), 4, true), APInt(4, 0x00)); - EXPECT_EQ(APIntOps::ScaleBitMask(APInt(8, 0xFF), 4, true), APInt(4, 0x0F)); - EXPECT_EQ(APIntOps::ScaleBitMask(APInt(8, 0xE4), 4, true), APInt(4, 0x08)); } } // end anonymous namespace