diff options
author | JF Bastien <jfb@chromium.org> | 2013-07-22 14:02:59 -0700 |
---|---|---|
committer | JF Bastien <jfb@chromium.org> | 2013-07-22 14:02:59 -0700 |
commit | ccad851d1493d84019f3372c0033908cdd516f58 (patch) | |
tree | 8d73fa6f6e6d38d11b14a83d3a2d0f80c8d0eb6e /lib/CodeGen | |
parent | 0eb1be38d149f22aab802958086a295628a3d76f (diff) |
Cherrypick upstream volatile _Complex alignment patches
Specifically:
r186564 - Fix volatile _Complex alignment test on platforms where 64-bit floating point isn't 64-bit aligned
r186490 - Propagate alignment for _Complex
These should fix GCC torture test failures, as well as the all-important uses of volatile _Complex numbers in C, and their alignment being incorrect.
BUG= PNaCl FYI bots red on torture tests
TEST= ./tools/toolchain_tester/torture_test.py pnacl x86-64 --concurrency=32 >& torture-x86-64.log ; ./tools/toolchain_tester/torture_test.py pnacl x86-32 --concurrency=32 >& torture-x86-32.log ; ./tools/toolchain_tester/torture_test.py pnacl arm --concurrency=32 >& torture-arm.log
R=stichnot@chromium.org
Review URL: https://codereview.chromium.org/19915003
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExprComplex.cpp | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 36f974a313..3a3971479d 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/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; @@ -294,19 +295,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); } @@ -322,10 +330,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()); } |