summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorHiroshi Inoue <inouehrs@jp.ibm.com>2018-04-06 05:41:16 +0000
committerHiroshi Inoue <inouehrs@jp.ibm.com>2018-04-06 05:41:16 +0000
commita2eefb6d9a76e456552fd96fad3dae6c0266cbed (patch)
tree2041568918741a73177ed63defeceb4a464423c6 /llvm/lib
parent248148db0032b2f9061449b3dac0a5436ca16a3e (diff)
downloadbcm5719-llvm-a2eefb6d9a76e456552fd96fad3dae6c0266cbed.tar.gz
bcm5719-llvm-a2eefb6d9a76e456552fd96fad3dae6c0266cbed.zip
[PowerPC] allow D-form VSX load/store when accessing FrameIndex without offset
VSX D-form load/store instructions of POWER9 require the offset be a multiple of 16 and a helper`isOffsetMultipleOf` is used to check this. So far, the helper handles FrameIndex + offset case, but not handling FrameIndex without offset case. Due to this, we are missing opportunities to exploit D-form instructions when accessing an object or array allocated on stack. For example, x-form store (stxvx) is used for int a[4] = {0}; instead of d-form store (stxv). For larger arrays, D-form instruction is not used when accessing the first 16-byte. Using D-form instructions reduces register pressure as well as instructions. Differential Revision: https://reviews.llvm.org/D45079 llvm-svn: 329377
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp24
1 files changed, 16 insertions, 8 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index ec822aa53ca..bb9d5244f0e 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -3937,20 +3937,28 @@ bool PPCDAGToDAGISel::isOffsetMultipleOf(SDNode *N, unsigned Val) const {
else if (STN)
AddrOp = STN->getOperand(2);
+ // If the address points a frame object or a frame object with an offset,
+ // we need to check the object alignment.
short Imm = 0;
- if (AddrOp.getOpcode() == ISD::ADD) {
+ if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(
+ AddrOp.getOpcode() == ISD::ADD ? AddrOp.getOperand(0) :
+ AddrOp)) {
// If op0 is a frame index that is under aligned, we can't do it either,
// because it is translated to r31 or r1 + slot + offset. We won't know the
// slot number until the stack frame is finalized.
- if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(AddrOp.getOperand(0))) {
- const MachineFrameInfo &MFI = CurDAG->getMachineFunction().getFrameInfo();
- unsigned SlotAlign = MFI.getObjectAlignment(FI->getIndex());
- if ((SlotAlign % Val) != 0)
- return false;
- }
- return isIntS16Immediate(AddrOp.getOperand(1), Imm) && !(Imm % Val);
+ const MachineFrameInfo &MFI = CurDAG->getMachineFunction().getFrameInfo();
+ unsigned SlotAlign = MFI.getObjectAlignment(FI->getIndex());
+ if ((SlotAlign % Val) != 0)
+ return false;
+
+ // If we have an offset, we need further check on the offset.
+ if (AddrOp.getOpcode() != ISD::ADD)
+ return true;
}
+ if (AddrOp.getOpcode() == ISD::ADD)
+ return isIntS16Immediate(AddrOp.getOperand(1), Imm) && !(Imm % Val);
+
// If the address comes from the outside, the offset will be zero.
return AddrOp.getOpcode() == ISD::CopyFromReg;
}
OpenPOWER on IntegriCloud