diff options
author | Eli Friedman <efriedma@quicinc.com> | 2020-05-06 12:06:29 -0700 |
---|---|---|
committer | Eli Friedman <efriedma@quicinc.com> | 2020-05-11 17:39:00 -0700 |
commit | c9c930ae67c38b93451aa979de723723aec0067d (patch) | |
tree | 627a5bddc7d4822ea792a6dd567c263544454266 /llvm/lib | |
parent | 117e5609e98b43f925c678b72f816ad3a1c3eee7 (diff) | |
download | llvm-c9c930ae67c38b93451aa979de723723aec0067d.zip llvm-c9c930ae67c38b93451aa979de723723aec0067d.tar.gz llvm-c9c930ae67c38b93451aa979de723723aec0067d.tar.bz2 |
[SelectionDAG] Don't promote the alignment of allocas beyond the stack alignment.
allocas in LLVM IR have a specified alignment. When that alignment is
specified, the alloca has at least that alignment at runtime.
If the specified type of the alloca has a higher preferred alignment,
SelectionDAG currently ignores that specified alignment, and increases
the alignment. It does this even if it would trigger stack realignment.
I don't think this makes sense, so this patch changes that.
I was looking into this for SVE in particular: for SVE, overaligning
vscale'ed types is extra expensive because it requires realigning the
stack multiple times, or using dynamic allocation. (This currently isn't
implemented.)
I updated the expected assembly for a couple tests; in particular, for
arg-copy-elide.ll, the optimization in question does not increase the
alignment the way SelectionDAG normally would. For the rest, I just
increased the specified alignment on the allocas to match what
SelectionDAG was inferring.
Differential Revision: https://reviews.llvm.org/D79532
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 3f302d5..c482125 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -134,8 +134,20 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, for (const Instruction &I : BB) { if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) { Type *Ty = AI->getAllocatedType(); + Align TyPrefAlign = MF->getDataLayout().getPrefTypeAlign(Ty); + // The "specified" alignment is the alignment written on the alloca, + // or the preferred alignment of the type if none is specified. + // + // (Unspecified alignment on allocas will be going away soon.) + Align SpecifiedAlign = AI->getAlign() ? *AI->getAlign() : TyPrefAlign; + + // If the preferred alignment of the type is higher than the specified + // alignment of the alloca, promote the alignment, as long as it doesn't + // require realigning the stack. + // + // FIXME: Do we really want to second-guess the IR in isel? Align Alignment = - max(MF->getDataLayout().getPrefTypeAlign(Ty), AI->getAlign()); + std::max(std::min(TyPrefAlign, StackAlign), SpecifiedAlign); // Static allocas can be folded into the initial stack frame // adjustment. For targets that don't realign the stack, don't |