diff options
author | QingShan Zhang <qshanz@cn.ibm.com> | 2018-07-02 05:46:09 +0000 |
---|---|---|
committer | QingShan Zhang <qshanz@cn.ibm.com> | 2018-07-02 05:46:09 +0000 |
commit | 3b2aa2b4b4b42fdeb2ee2c617dabddeb30c5441f (patch) | |
tree | eeb3e0268bf5a5a86cc002b6af841750164b772e /llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp | |
parent | 5b3db45e8f4d2600c32e18b136a31457e31b7aed (diff) | |
download | bcm5719-llvm-3b2aa2b4b4b42fdeb2ee2c617dabddeb30c5441f.tar.gz bcm5719-llvm-3b2aa2b4b4b42fdeb2ee2c617dabddeb30c5441f.zip |
[PowerPC] Don't make it as pre-inc candidate if displacement isn't 4's multiple for i64 pre-inc load/store
For the below case, pre-inc prep think it's a good candidate to use pre-inc for the bucket, but 64bit integer load/store update (pre-inc) instruction on Power requires the displacement field should be DS-form (4's multiple). Since it can't satisfy the constraint, we have to do some fix ups later. As below, the original load/stores could be well-form, it makes things worse.
unsigned long long result = 0;
unsigned long long foo(char *p, unsigned long long n) {
for (unsigned long long i = 0; i < n; i++) {
unsigned long long x1 = *(unsigned long long *)(p - 50000 + i);
unsigned long long x2 = *(unsigned long long *)(p - 61024 + i);
unsigned long long x3 = *(unsigned long long *)(p - 62048 + i);
unsigned long long x4 = *(unsigned long long *)(p - 64096 + i);
result *= x1 * x2 * x3 * x4;
}
return result;
}
Patch by jedilyn(Kewen Lin).
Differential Revision: https://reviews.llvm.org/D48813
--This line, and those below, will be ignored--
M lib/Target/PowerPC/PPCLoopPreIncPrep.cpp
A test/CodeGen/PowerPC/preincprep-i64-check.ll
llvm-svn: 336074
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp b/llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp index d16397b23ed..2217fa4693c 100644 --- a/llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp +++ b/llvm/lib/Target/PowerPC/PPCLoopPreIncPrep.cpp @@ -294,6 +294,19 @@ bool PPCLoopPreIncPrep::runOnLoop(Loop *L) { if (const SCEVAddRecExpr *LARSCEV = dyn_cast<SCEVAddRecExpr>(LSCEV)) { if (LARSCEV->getLoop() != L) continue; + // See getPreIndexedAddressParts, the displacement for LDU/STDU has to + // be 4's multiple (DS-form). For i64 loads/stores when the displacement + // fits in a 16-bit signed field but isn't a multiple of 4, it will be + // useless and possible to break some original well-form addressing mode + // to make this pre-inc prep for it. + if (PtrValue->getType()->getPointerElementType()->isIntegerTy(64)) { + if (const SCEVConstant *StepConst = + dyn_cast<SCEVConstant>(LARSCEV->getStepRecurrence(*SE))) { + const APInt &ConstInt = StepConst->getValue()->getValue(); + if (ConstInt.isSignedIntN(16) && ConstInt.srem(4) != 0) + continue; + } + } } else { continue; } |