summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-07-25 12:14:27 +0000
committerSanjay Patel <spatel@rotateright.com>2019-07-25 12:14:27 +0000
commitbc4a63fd3c29c1a8ce22891bf34ee4dccfef578c (patch)
treedec720d60f4a9d6f8ca4397cb1c11b10cf09b2ce /llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
parent4e1d188be2868aef71f8603f28ca4703723cb97a (diff)
downloadbcm5719-llvm-bc4a63fd3c29c1a8ce22891bf34ee4dccfef578c.tar.gz
bcm5719-llvm-bc4a63fd3c29c1a8ce22891bf34ee4dccfef578c.zip
[InstCombine] try to narrow a truncated load
trunc (load X) --> load (bitcast X to narrow type) We have this transform in DAGCombiner::ReduceLoadWidth(), but the truncated load pattern can interfere with other instcombine transforms, so I'd like to allow the fold sooner. Example: https://bugs.llvm.org/show_bug.cgi?id=16739 ...in that report, we have bitcasts bracketing these ops, so those could get eliminated too. We've generally ruled out widening of loads early in IR ( LoadCombine - http://lists.llvm.org/pipermail/llvm-dev/2016-September/105291.html ), but that reasoning may not apply to narrowing if we can preserve information such as the dereferenceable range. Differential Revision: https://reviews.llvm.org/D64432 llvm-svn: 367011
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 2c9ba203fbf..08a7a068af2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -681,6 +681,42 @@ static Instruction *shrinkInsertElt(CastInst &Trunc,
return nullptr;
}
+static Instruction *narrowLoad(TruncInst &Trunc,
+ InstCombiner::BuilderTy &Builder,
+ const DataLayout &DL) {
+ // Check the layout to ensure we are not creating an unsupported operation.
+ // TODO: Create a GEP to offset the load?
+ if (!DL.isLittleEndian())
+ return nullptr;
+ unsigned NarrowBitWidth = Trunc.getDestTy()->getPrimitiveSizeInBits();
+ if (!DL.isLegalInteger(NarrowBitWidth))
+ return nullptr;
+
+ // Match a truncated load with no other uses.
+ Value *X;
+ if (!match(Trunc.getOperand(0), m_OneUse(m_Load(m_Value(X)))))
+ return nullptr;
+ LoadInst *WideLoad = cast<LoadInst>(Trunc.getOperand(0));
+ if (!WideLoad->isSimple())
+ return nullptr;
+
+ // Don't narrow this load if we would lose information about the
+ // dereferenceable range.
+ bool CanBeNull;
+ uint64_t DerefBits = X->getPointerDereferenceableBytes(DL, CanBeNull) * 8;
+ if (DerefBits < WideLoad->getType()->getPrimitiveSizeInBits())
+ return nullptr;
+
+ // trunc (load X) --> load (bitcast X)
+ PointerType *PtrTy = PointerType::get(Trunc.getDestTy(),
+ WideLoad->getPointerAddressSpace());
+ Value *Bitcast = Builder.CreatePointerCast(X, PtrTy);
+ LoadInst *NarrowLoad = new LoadInst(Trunc.getDestTy(), Bitcast);
+ NarrowLoad->setAlignment(WideLoad->getAlignment());
+ copyMetadataForLoad(*NarrowLoad, *WideLoad);
+ return NarrowLoad;
+}
+
Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
if (Instruction *Result = commonCastTransforms(CI))
return Result;
@@ -840,6 +876,9 @@ Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
if (Instruction *I = foldVecTruncToExtElt(CI, *this))
return I;
+ if (Instruction *NewLoad = narrowLoad(CI, Builder, DL))
+ return NewLoad;
+
return nullptr;
}
OpenPOWER on IntegriCloud