summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
diff options
context:
space:
mode:
authorAmara Emerson <aemerson@apple.com>2019-08-02 21:15:36 +0000
committerAmara Emerson <aemerson@apple.com>2019-08-02 21:15:36 +0000
commit73752abeab1a1ce5d44ed3c4c6ac78a4a00be6ed (patch)
tree5fc5126681dd796dd983c7f418bfb8523d7b90f6 /llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
parentc4952da40109ad73cb50225cdd28a55161c64111 (diff)
downloadbcm5719-llvm-73752abeab1a1ce5d44ed3c4c6ac78a4a00be6ed.tar.gz
bcm5719-llvm-73752abeab1a1ce5d44ed3c4c6ac78a4a00be6ed.zip
[AArch64][GlobalISel] Eliminate redundant G_ZEXT when the source is implicitly zext-loaded.
These cases can come up when the extending loads combiner doesn't combine a zext(load) to a zextload op, due to some other operation being in between, which then gets simplified at a later stage. Differential Revision: https://reviews.llvm.org/D65360 llvm-svn: 367723
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp')
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 46a1aee7eb2..a2f51415b75 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -2045,6 +2045,23 @@ bool AArch64InstructionSelector::select(MachineInstr &I,
if (DstTy.isVector())
return false; // Should be handled by imported patterns.
+ // First check if we're extending the result of a load which has a dest type
+ // smaller than 32 bits, then this zext is redundant. GPR32 is the smallest
+ // GPR register on AArch64 and all loads which are smaller automatically
+ // zero-extend the upper bits. E.g.
+ // %v(s8) = G_LOAD %p, :: (load 1)
+ // %v2(s32) = G_ZEXT %v(s8)
+ if (!IsSigned) {
+ auto *LoadMI = getOpcodeDef(TargetOpcode::G_LOAD, SrcReg, MRI);
+ if (LoadMI &&
+ RBI.getRegBank(SrcReg, MRI, TRI)->getID() == AArch64::GPRRegBankID) {
+ const MachineMemOperand *MemOp = *LoadMI->memoperands_begin();
+ unsigned BytesLoaded = MemOp->getSize();
+ if (BytesLoaded < 4 && SrcTy.getSizeInBytes() == BytesLoaded)
+ return selectCopy(I, TII, MRI, TRI, RBI);
+ }
+ }
+
if (DstSize == 64) {
// FIXME: Can we avoid manually doing this?
if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
OpenPOWER on IntegriCloud