summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp35
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h14
2 files changed, 36 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 3c1ab740b23..043cfa1d507 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -182,13 +182,13 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
QualType ExprType) {
llvm::Value *Vec = Builder.CreateLoad(LV.getExtVectorAddr(), "tmp");
- unsigned EncFields = LV.getExtVectorElts();
+ const llvm::Constant *Elts = LV.getExtVectorElts();
// If the result of the expression is a non-vector type, we must be
// extracting a single element. Just codegen as an extractelement.
const VectorType *ExprVT = ExprType->getAsVectorType();
if (!ExprVT) {
- unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(0, EncFields);
+ unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(0, Elts);
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
}
@@ -202,7 +202,7 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
if (NumResultElts == NumSourceElts) {
llvm::SmallVector<llvm::Constant*, 4> Mask;
for (unsigned i = 0; i != NumResultElts; ++i) {
- unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(i, EncFields);
+ unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(i, Elts);
Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
}
@@ -218,7 +218,7 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
// Extract/Insert each element of the result.
for (unsigned i = 0; i != NumResultElts; ++i) {
- unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(i, EncFields);
+ unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(i, Elts);
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
Elt = Builder.CreateExtractElement(Vec, Elt, "tmp");
@@ -312,7 +312,7 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
// value now.
llvm::Value *Vec = Builder.CreateLoad(Dst.getExtVectorAddr(), "tmp");
// FIXME: Volatility.
- unsigned EncFields = Dst.getExtVectorElts();
+ const llvm::Constant *Elts = Dst.getExtVectorElts();
llvm::Value *SrcVal = Src.getScalarVal();
@@ -324,13 +324,13 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
Elt = Builder.CreateExtractElement(SrcVal, Elt, "tmp");
- unsigned Idx = ExtVectorElementExpr::getAccessedFieldNo(i, EncFields);
+ unsigned Idx = ExtVectorElementExpr::getAccessedFieldNo(i, Elts);
llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Idx);
Vec = Builder.CreateInsertElement(Vec, Elt, OutIdx, "tmp");
}
} else {
// If the Src is a scalar (not a vector) it must be updating one element.
- unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(0, EncFields);
+ unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(0, Elts);
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt, "tmp");
}
@@ -460,9 +460,28 @@ LValue CodeGenFunction::
EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
// Emit the base vector as an l-value.
LValue Base = EmitLValue(E->getBase());
+
+ if (Base.isExtVectorElt()) {
+ llvm::Constant *BaseElts = Base.getExtVectorElts();
+ llvm::Constant *ExprElts = E->getEncodedElementAccess();
+
+ llvm::SmallVector<llvm::Constant *, 8> Indices;
+
+ for (unsigned i = 0, e = E->getNumElements(); i != e; ++i) {
+ unsigned Idx = ExtVectorElementExpr::getAccessedFieldNo(i, ExprElts);
+
+ if (isa<llvm::ConstantAggregateZero>(BaseElts))
+ Indices.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0));
+ else
+ Indices.push_back(cast<llvm::ConstantInt>(BaseElts->getOperand(Idx)));
+ }
+ llvm::Constant *NewElts = llvm::ConstantVector::get(&Indices[0], Indices.size());
+ return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), NewElts);
+ }
+
assert(Base.isSimple() && "Can only subscript lvalue vectors here!");
- return LValue::MakeExtVectorElt(Base.getAddress(),
+ return LValue::MakeExtVectorElt(Base.getAddress(),
E->getEncodedElementAccess());
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index a6caa379cc9..f067a0e2250 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -161,8 +161,12 @@ class LValue {
llvm::Value *V;
union {
- llvm::Value *VectorIdx; // Index into a vector subscript: V[i]
- unsigned VectorElts; // Encoded ExtVector element subset: V.xyx
+ // Index into a vector subscript: V[i]
+ llvm::Value *VectorIdx;
+
+ // ExtVector element subset: V.xyx
+ llvm::Constant *VectorElts;
+
struct {
unsigned short StartBit;
unsigned short Size;
@@ -182,7 +186,7 @@ public:
llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
// extended vector elements.
llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
- unsigned getExtVectorElts() const {
+ llvm::Constant *getExtVectorElts() const {
assert(isExtVectorElt());
return VectorElts;
}
@@ -216,11 +220,11 @@ public:
return R;
}
- static LValue MakeExtVectorElt(llvm::Value *Vec, unsigned Elements) {
+ static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts) {
LValue R;
R.LVType = ExtVectorElt;
R.V = Vec;
- R.VectorElts = Elements;
+ R.VectorElts = Elts;
return R;
}
OpenPOWER on IntegriCloud