diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-03-22 22:36:39 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-03-22 22:36:39 +0000 |
commit | e5a8aeb4ad762b9383f9e9544c619dc386951e18 (patch) | |
tree | 77f3a7d98f82917926e91073bda0edddd500782d | |
parent | 5aac0b6ae95f137b1783f3e6227241fb457b8f8b (diff) |
Make sure we correctly set the alignment for vector loads and stores associated with vector element lvalues. Patch by Kevin Schoedel (with some minor modifications by me).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153285 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 41 | ||||
-rw-r--r-- | lib/CodeGen/CGValue.h | 11 | ||||
-rw-r--r-- | test/CodeGen/ext-vector-member-alignment.c | 27 |
3 files changed, 60 insertions, 19 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 7b820f5732..30e3e7ad2c 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -950,9 +950,10 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV) { } if (LV.isVectorElt()) { - llvm::Value *Vec = Builder.CreateLoad(LV.getVectorAddr(), - LV.isVolatileQualified()); - return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(), + llvm::LoadInst *Load = Builder.CreateLoad(LV.getVectorAddr(), + LV.isVolatileQualified()); + Load->setAlignment(LV.getAlignment().getQuantity()); + return RValue::get(Builder.CreateExtractElement(Load, LV.getVectorIdx(), "vecext")); } @@ -1039,8 +1040,10 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) { // If this is a reference to a subset of the elements of a vector, create an // appropriate shufflevector. RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) { - llvm::Value *Vec = Builder.CreateLoad(LV.getExtVectorAddr(), - LV.isVolatileQualified()); + llvm::LoadInst *Load = Builder.CreateLoad(LV.getExtVectorAddr(), + LV.isVolatileQualified()); + Load->setAlignment(LV.getAlignment().getQuantity()); + llvm::Value *Vec = Load; const llvm::Constant *Elts = LV.getExtVectorElts(); @@ -1075,11 +1078,15 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit if (!Dst.isSimple()) { if (Dst.isVectorElt()) { // Read/modify/write the vector, inserting the new element. - llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddr(), - Dst.isVolatileQualified()); + llvm::LoadInst *Load = Builder.CreateLoad(Dst.getVectorAddr(), + Dst.isVolatileQualified()); + Load->setAlignment(Dst.getAlignment().getQuantity()); + llvm::Value *Vec = Load; Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(), Dst.getVectorIdx(), "vecins"); - Builder.CreateStore(Vec, Dst.getVectorAddr(),Dst.isVolatileQualified()); + llvm::StoreInst *Store = Builder.CreateStore(Vec, Dst.getVectorAddr(), + Dst.isVolatileQualified()); + Store->setAlignment(Dst.getAlignment().getQuantity()); return; } @@ -1263,8 +1270,10 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst) { // This access turns into a read/modify/write of the vector. Load the input // value now. - llvm::Value *Vec = Builder.CreateLoad(Dst.getExtVectorAddr(), - Dst.isVolatileQualified()); + llvm::LoadInst *Load = Builder.CreateLoad(Dst.getExtVectorAddr(), + Dst.isVolatileQualified()); + Load->setAlignment(Dst.getAlignment().getQuantity()); + llvm::Value *Vec = Load; const llvm::Constant *Elts = Dst.getExtVectorElts(); llvm::Value *SrcVal = Src.getScalarVal(); @@ -1320,7 +1329,9 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src, Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt); } - Builder.CreateStore(Vec, Dst.getExtVectorAddr(), Dst.isVolatileQualified()); + llvm::StoreInst *Store = Builder.CreateStore(Vec, Dst.getExtVectorAddr(), + Dst.isVolatileQualified()); + Store->setAlignment(Dst.getAlignment().getQuantity()); } // setObjCGCLValueClass - sets class of he lvalue for the purpose of @@ -1722,7 +1733,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { assert(LHS.isSimple() && "Can only subscript lvalue vectors here!"); Idx = Builder.CreateIntCast(Idx, Int32Ty, IdxSigned, "vidx"); return LValue::MakeVectorElt(LHS.getAddress(), Idx, - E->getBase()->getType()); + E->getBase()->getType(), LHS.getAlignment()); } // Extend or truncate the index type to 32 or 64-bits. @@ -1888,7 +1899,8 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { if (Base.isSimple()) { llvm::Constant *CV = GenerateConstantVector(Builder, Indices); - return LValue::MakeExtVectorElt(Base.getAddress(), CV, type); + return LValue::MakeExtVectorElt(Base.getAddress(), CV, type, + Base.getAlignment()); } assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!"); @@ -1898,7 +1910,8 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { for (unsigned i = 0, e = Indices.size(); i != e; ++i) CElts.push_back(BaseElts->getAggregateElement(Indices[i])); llvm::Constant *CV = llvm::ConstantVector::get(CElts); - return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV, type); + return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV, type, + Base.getAlignment()); } LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index 744a6e02f9..ac704e7dca 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -126,7 +126,8 @@ class LValue { // 'const' is unused here Qualifiers Quals; - /// The alignment to use when accessing this lvalue. + // The alignment to use when accessing this lvalue. (For vector elements, + // this is the alignment of the whole vector.) unsigned short Alignment; // objective-c's ivar @@ -267,22 +268,22 @@ public: } static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx, - QualType type) { + QualType type, CharUnits Alignment) { LValue R; R.LVType = VectorElt; R.V = Vec; R.VectorIdx = Idx; - R.Initialize(type, type.getQualifiers()); + R.Initialize(type, type.getQualifiers(), Alignment); return R; } static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts, - QualType type) { + QualType type, CharUnits Alignment) { LValue R; R.LVType = ExtVectorElt; R.V = Vec; R.VectorElts = Elts; - R.Initialize(type, type.getQualifiers()); + R.Initialize(type, type.getQualifiers(), Alignment); return R; } diff --git a/test/CodeGen/ext-vector-member-alignment.c b/test/CodeGen/ext-vector-member-alignment.c new file mode 100644 index 0000000000..73a6d6cf85 --- /dev/null +++ b/test/CodeGen/ext-vector-member-alignment.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+typedef float float4 __attribute__((ext_vector_type(4)));
+
+struct __attribute__((packed, aligned(4))) struct1 {
+ float4 position;
+};
+int x = __alignof(struct struct1);
+
+float4 f(struct struct1* x) { return x->position; }
+
+void func(struct struct1* p, float *a, float *b, float c) {
+ p->position.x = c;
+ *a = p->position.y;
+ *b = p->position[0];
+ p->position[2] = c;
+ // FIXME: We should be able to come up with a more aggressive alignment
+ // estimate.
+ // CHECK: @func
+ // CHECK: load <4 x float>* {{%.*}}, align 1
+ // CHECK: store <4 x float> {{%.*}}, <4 x float>* {{%.*}}, align 1
+ // CHECK: load <4 x float>* {{%.*}}, align 1
+ // CHECK: load <4 x float>* {{%.*}}, align 1
+ // CHECK: load <4 x float>* {{%.*}}, align 1
+ // CHECK: store <4 x float> {{%.*}}, <4 x float>* {{%.*}}, align 1
+ // CHECK: ret void
+}
|