diff options
| author | JF Bastien <jfb@google.com> | 2013-07-17 05:57:42 +0000 |
|---|---|---|
| committer | JF Bastien <jfb@google.com> | 2013-07-17 05:57:42 +0000 |
| commit | 27dcbb24e535d4e96eb9c1083d9888b4f5c9e92d (patch) | |
| tree | 4855645205a89c53469a5c87c37b44b43375a8c9 /clang/lib/CodeGen | |
| parent | cd4c64d2347e2fd92ab2a2a32e3c315cbdb3fc20 (diff) | |
| download | bcm5719-llvm-27dcbb24e535d4e96eb9c1083d9888b4f5c9e92d.tar.gz bcm5719-llvm-27dcbb24e535d4e96eb9c1083d9888b4f5c9e92d.zip | |
Propagate alignment for _Complex
_Complex load/store didn't have their alignment set properly, which was visible when GCC's torture tests use volatile _Complex.
Update some existing tests to check for alignment, and add a new test which also has over-aligned volatile _Complex (since the imaginary part shouldn't be overaligned, only the real part).
llvm-svn: 186490
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGExprComplex.cpp | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 796c55a4bdb..5ba13175d53 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" +#include <algorithm> using namespace clang; using namespace CodeGen; @@ -297,19 +298,26 @@ ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue) { llvm::Value *SrcPtr = lvalue.getAddress(); bool isVolatile = lvalue.isVolatileQualified(); + unsigned AlignR = lvalue.getAlignment().getQuantity(); + ASTContext &C = CGF.getContext(); + QualType ComplexTy = lvalue.getType(); + unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity(); + unsigned AlignI = std::min(AlignR, ComplexAlign); llvm::Value *Real=0, *Imag=0; if (!IgnoreReal || isVolatile) { llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0, SrcPtr->getName() + ".realp"); - Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr->getName() + ".real"); + Real = Builder.CreateAlignedLoad(RealP, AlignR, isVolatile, + SrcPtr->getName() + ".real"); } if (!IgnoreImag || isVolatile) { llvm::Value *ImagP = Builder.CreateStructGEP(SrcPtr, 1, SrcPtr->getName() + ".imagp"); - Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr->getName() + ".imag"); + Imag = Builder.CreateAlignedLoad(ImagP, AlignI, isVolatile, + SrcPtr->getName() + ".imag"); } return ComplexPairTy(Real, Imag); } @@ -325,10 +333,16 @@ void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr = lvalue.getAddress(); llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real"); llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag"); - - // TODO: alignment - Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified()); - Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified()); + unsigned AlignR = lvalue.getAlignment().getQuantity(); + ASTContext &C = CGF.getContext(); + QualType ComplexTy = lvalue.getType(); + unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity(); + unsigned AlignI = std::min(AlignR, ComplexAlign); + + Builder.CreateAlignedStore(Val.first, RealPtr, AlignR, + lvalue.isVolatileQualified()); + Builder.CreateAlignedStore(Val.second, ImagPtr, AlignI, + lvalue.isVolatileQualified()); } |

