forked from OSchip/llvm-project
ext_vector IRGen. Patch to allow indexing into
ext_vector_type's 'hi/lo' components when used as lvalue. rdar://18031917 pr20697 llvm-svn: 215991
This commit is contained in:
parent
6a128331a6
commit
91b2fa2a9a
|
@ -1361,6 +1361,28 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) {
|
|||
return RValue::get(Vec);
|
||||
}
|
||||
|
||||
/// @brief Generates lvalue for partial ext_vector access.
|
||||
llvm::Value *CodeGenFunction::EmitExtVectorElementLValue(LValue LV) {
|
||||
llvm::Value *VectorAddress = LV.getExtVectorAddr();
|
||||
const VectorType *ExprVT = LV.getType()->getAs<VectorType>();
|
||||
QualType EQT = ExprVT->getElementType();
|
||||
llvm::Type *VectorElementTy = CGM.getTypes().ConvertType(EQT);
|
||||
llvm::Type *VectorElementPtrToTy = VectorElementTy->getPointerTo();
|
||||
|
||||
llvm::Value *CastToPointerElement =
|
||||
Builder.CreateBitCast(VectorAddress,
|
||||
VectorElementPtrToTy, "conv.ptr.element");
|
||||
|
||||
const llvm::Constant *Elts = LV.getExtVectorElts();
|
||||
unsigned ix = getAccessedFieldNo(0, Elts);
|
||||
|
||||
llvm::Value *VectorBasePtrPlusIx =
|
||||
Builder.CreateInBoundsGEP(CastToPointerElement,
|
||||
llvm::ConstantInt::get(SizeTy, ix), "add.ptr");
|
||||
|
||||
return VectorBasePtrPlusIx;
|
||||
}
|
||||
|
||||
/// @brief Load of global gamed gegisters are always calls to intrinsics.
|
||||
RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {
|
||||
assert((LV.getType()->isIntegerType() || LV.getType()->isPointerType()) &&
|
||||
|
@ -2323,7 +2345,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
|
|||
|
||||
// If the base is a vector type, then we are forming a vector element lvalue
|
||||
// with this subscript.
|
||||
if (E->getBase()->getType()->isVectorType()) {
|
||||
if (E->getBase()->getType()->isVectorType() &&
|
||||
!isa<ExtVectorElementExpr>(E->getBase())) {
|
||||
// Emit the vector as an lvalue to get its address.
|
||||
LValue LHS = EmitLValue(E->getBase());
|
||||
assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
|
||||
|
@ -2339,8 +2362,17 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
|
|||
// size is a VLA or Objective-C interface.
|
||||
llvm::Value *Address = nullptr;
|
||||
CharUnits ArrayAlignment;
|
||||
if (const VariableArrayType *vla =
|
||||
getContext().getAsVariableArrayType(E->getType())) {
|
||||
if (isa<ExtVectorElementExpr>(E->getBase())) {
|
||||
LValue LV = EmitLValue(E->getBase());
|
||||
Address = EmitExtVectorElementLValue(LV);
|
||||
Address = Builder.CreateInBoundsGEP(Address, Idx, "arrayidx");
|
||||
const VectorType *ExprVT = LV.getType()->getAs<VectorType>();
|
||||
QualType EQT = ExprVT->getElementType();
|
||||
return MakeAddrLValue(Address, EQT,
|
||||
getContext().getTypeAlignInChars(EQT));
|
||||
}
|
||||
else if (const VariableArrayType *vla =
|
||||
getContext().getAsVariableArrayType(E->getType())) {
|
||||
// The base must be a pointer, which is not an aggregate. Emit
|
||||
// it. It needs to be emitted first in case it's what captures
|
||||
// the VLA bounds.
|
||||
|
|
|
@ -2096,6 +2096,8 @@ public:
|
|||
LValue EmitCastLValue(const CastExpr *E);
|
||||
LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
|
||||
LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e);
|
||||
|
||||
llvm::Value *EmitExtVectorElementLValue(LValue V);
|
||||
|
||||
RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc);
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
typedef __attribute__(( ext_vector_type(4) )) float float4;
|
||||
// CHECK: @test
|
||||
void test()
|
||||
{
|
||||
float4 va;
|
||||
va.hi[0] = 3.0;
|
||||
// CHECK: [[VA:%.*]] = alloca <4 x float>
|
||||
// CHECK: [[CONV:%.*]] = bitcast <4 x float>* [[VA]] to float*
|
||||
// CHECK: [[ADD:%.*]] = getelementptr inbounds float* [[CONV]], i64 2
|
||||
// CHECK: [[ARRIDX:%.*]] = getelementptr inbounds float* [[ADD]], i64 0
|
||||
// CHECK: store float 3.000000e+00, float* [[ARRIDX]]
|
||||
}
|
Loading…
Reference in New Issue