diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-06-07 00:17:08 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-06-07 00:17:08 +0000 |
commit | f57015d4cc92ad7721ab52be4ba26e94b3a379e9 (patch) | |
tree | cd65333c6865935b8397fd4c4ac5ce5e1a21cd64 /llvm/lib/CodeGen | |
parent | d9c251f46c83dcdbb1a949029a118771c594bb45 (diff) | |
download | bcm5719-llvm-f57015d4cc92ad7721ab52be4ba26e94b3a379e9.tar.gz bcm5719-llvm-f57015d4cc92ad7721ab52be4ba26e94b3a379e9.zip |
[CGP / PowerPC] use direct compares if there's only one load per block in memcmp() expansion
I'd like to enable CGP memcmp expansion for x86, but the output from CGP would regress the
special cases (memcmp(x,y,N) != 0 for N=1,2,4,8,16,32 bytes) that we already handle.
I'm not sure if we'll actually be able to produce the optimal code given the block-at-a-time
limitation in the DAG. We might have to just avoid those special-cases here in CGP. But
regardless of that, I think this is a win for the more general cases.
http://rise4fun.com/Alive/cbQ
Differential Revision: https://reviews.llvm.org/D33963
llvm-svn: 304849
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 2d6d3ada212..12b00eaf6d7 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -1812,7 +1812,7 @@ void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( unsigned NumLoads = std::min(NumLoadsRemaining, NumLoadsPerBlock); Builder.SetInsertPoint(LoadCmpBlocks[Index]); - + Value *Cmp = nullptr; for (unsigned i = 0; i < NumLoads; ++i) { unsigned LoadSize = getLoadSize(RemainingBytes); unsigned GEPIndex = NumBytesProcessed / LoadSize; @@ -1846,9 +1846,16 @@ void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( LoadSrc1 = Builder.CreateZExtOrTrunc(LoadSrc1, MaxLoadType); LoadSrc2 = Builder.CreateZExtOrTrunc(LoadSrc2, MaxLoadType); } - Diff = Builder.CreateXor(LoadSrc1, LoadSrc2); - Diff = Builder.CreateZExtOrTrunc(Diff, MaxLoadType); - XorList.push_back(Diff); + if (NumLoads != 1) { + // If we have multiple loads per block, we need to generate a composite + // comparison using xor+or. + Diff = Builder.CreateXor(LoadSrc1, LoadSrc2); + Diff = Builder.CreateZExtOrTrunc(Diff, MaxLoadType); + XorList.push_back(Diff); + } else { + // If there's only one load per block, we just compare the loaded values. + Cmp = Builder.CreateICmpNE(LoadSrc1, LoadSrc2); + } } auto pairWiseOr = [&](std::vector<Value *> &InList) -> std::vector<Value *> { @@ -1862,16 +1869,17 @@ void MemCmpExpansion::emitLoadCompareBlockMultipleLoads( return OutList; }; - // Pairwise OR the XOR results. - OrList = pairWiseOr(XorList); + if (!Cmp) { + // Pairwise OR the XOR results. + OrList = pairWiseOr(XorList); - // Pairwise OR the OR results until one result left. - while (OrList.size() != 1) { - OrList = pairWiseOr(OrList); + // Pairwise OR the OR results until one result left. + while (OrList.size() != 1) { + OrList = pairWiseOr(OrList); + } + Cmp = Builder.CreateICmpNE(OrList[0], ConstantInt::get(Diff->getType(), 0)); } - Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_NE, OrList[0], - ConstantInt::get(Diff->getType(), 0)); BasicBlock *NextBB = (Index == (LoadCmpBlocks.size() - 1)) ? EndBlock : LoadCmpBlocks[Index + 1]; |