diff options
author | Bill Wendling <isanbard@gmail.com> | 2011-09-30 23:19:55 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2011-09-30 23:19:55 +0000 |
commit | e09b2a0d4964e6a34ea6393e94a9f5a76ba56f1a (patch) | |
tree | 37fd1d85ea872d3db5728a31c6ade397f1d1e6e9 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | 8de34006cf4cd67ef11cac59dd037bb722b18166 (diff) |
When inferring the pointer alignment, if the global doesn't have an initializer
and the alignment is 0 (i.e., it's defined globally in one file and declared in
another file) it could get an alignment which is larger than the ABI allows for
that type, resulting in aligned moves being used for unaligned loads.
For instance, in file A.c:
struct S s;
In file B.c:
struct {
// something long
};
extern S s;
void foo() {
struct S p = s;
// ...
}
this copy is a 'memcpy' which is turned into a series of 'movaps' instructions
on X86. But this is wrong, because 'struct S' has alignment of 4, not 16.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140902 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d617d6710c..6a549e8760 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -6537,6 +6537,8 @@ unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const { Align = TD->getPreferredAlignment(GVar); } } + if (!Align) + Align = TLI.getTargetData()->getABITypeAlignment(GV->getType()); } return MinAlign(Align, GVOffset); } |