[PATCH] D49075: [NEON] Define fp16 vld and vst intrinsics conditionally
This revision was automatically updated to reflect the committed changes. Closed by commit rL340140: [NEON] Define fp16 vld and vst intrinsics conditionally (authored by kosarev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D49075?vs=157960&id=161400#toc Repository: rC Clang https://reviews.llvm.org/D49075 Files: cfe/trunk/include/clang/Basic/arm_neon.td cfe/trunk/test/CodeGen/arm-neon-vld.c cfe/trunk/test/CodeGen/arm-neon-vst.c cfe/trunk/test/Sema/arm-no-fp16.c Index: cfe/trunk/test/CodeGen/arm-neon-vst.c === --- cfe/trunk/test/CodeGen/arm-neon-vst.c +++ cfe/trunk/test/CodeGen/arm-neon-vst.c @@ -2,8 +2,8 @@ // RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ // RUN: FileCheck -check-prefixes=CHECK,CHECK-A64 %s // RUN: %clang_cc1 -triple armv8-none-linux-gnueabi -target-feature +neon \ -// RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ -// RUN: FileCheck -check-prefixes=CHECK,CHECK-A32 %s +// RUN: -target-feature +fp16 -S -disable-O0-optnone -emit-llvm -o - %s | \ +// RUN: opt -S -mem2reg | FileCheck -check-prefixes=CHECK,CHECK-A32 %s #include Index: cfe/trunk/test/CodeGen/arm-neon-vld.c === --- cfe/trunk/test/CodeGen/arm-neon-vld.c +++ cfe/trunk/test/CodeGen/arm-neon-vld.c @@ -2,8 +2,8 @@ // RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ // RUN: FileCheck -check-prefixes=CHECK,CHECK-A64 %s // RUN: %clang_cc1 -triple armv8-none-linux-gnueabi -target-feature +neon \ -// RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ -// RUN: FileCheck -check-prefixes=CHECK,CHECK-A32 %s +// RUN: -target-feature +fp16 -S -disable-O0-optnone -emit-llvm -o - %s | \ +// RUN: opt -S -mem2reg | FileCheck -check-prefixes=CHECK,CHECK-A32 %s #include Index: cfe/trunk/test/Sema/arm-no-fp16.c === --- cfe/trunk/test/Sema/arm-no-fp16.c +++ cfe/trunk/test/Sema/arm-no-fp16.c @@ -83,3 +83,213 @@ float16x8_t test_vminnmq_f16(float16x8_t a, float16x8_t b) { return vminnmq_f16(a, b); // expected-warning{{implicit declaration of function 'vminnmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} } + +float16x4_t test_vld1_f16(const float16_t *a) { + return vld1_f16(a); // expected-warning{{implicit declaration of function 'vld1_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vld1q_f16(const float16_t *a) { + return vld1q_f16(a); // expected-warning{{implicit declaration of function 'vld1q_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vld1_dup_f16(const float16_t *a) { + return vld1_dup_f16(a); // expected-warning{{implicit declaration of function 'vld1_dup_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vld1q_dup_f16(const float16_t *a) { + return vld1q_dup_f16(a); // expected-warning{{implicit declaration of function 'vld1q_dup_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vld1_lane_f16(const float16_t *a, float16x4_t b) { + return vld1_lane_f16(a, b, 3); // expected-warning{{implicit declaration of function 'vld1_lane_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vld1q_lane_f16(const float16_t *a, float16x8_t b) { + return vld1q_lane_f16(a, b, 7); // expected-warning{{implicit declaration of function 'vld1q_lane_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4x2_t test_vld1_f16_x2(const float16_t *a) { + return vld1_f16_x2(a); // expected-warning{{implicit declaration of function 'vld1_f16_x2'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4x2_t'}} +} + +float16x8x2_t test_vld1q_f16_x2(const float16_t *a) { + return vld1q_f16_x2(a); // expected-warning{{implicit declaration of function 'vld1q_f16_x2'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8x2_t'}} +} + +float16x4x3_t test_vld1_f16_x3(const float16_t *a) { + return vld1_f16_x3(a); // expected-warning{{implicit declaration of function 'vld1_f16_x3'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4x3_t'}} +} + +float16x8x3_t test_vld1q_f16_x3(const float16_t *a) { + return vld1q_f16_x3(a); // expected-warning{{implicit declaration of function 'vld1q_f16_x3'}} expected-error{{returning 'int' from a function with incompatible result type 'fl
[PATCH] D49075: [NEON] Define fp16 vld and vst intrinsics conditionally
This revision was automatically updated to reflect the committed changes. Closed by commit rC340140: [NEON] Define fp16 vld and vst intrinsics conditionally (authored by kosarev, committed by ). Repository: rC Clang https://reviews.llvm.org/D49075 Files: include/clang/Basic/arm_neon.td test/CodeGen/arm-neon-vld.c test/CodeGen/arm-neon-vst.c test/Sema/arm-no-fp16.c Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -337,48 +337,78 @@ // E.3.14 Loads and stores of a single vector def VLD1 : WInst<"vld1", "dc", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; def VLD1_X2 : WInst<"vld1_x2", "2c", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VLD1_X3 : WInst<"vld1_x3", "3c", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VLD1_X4 : WInst<"vld1_x4", "4c", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VLD1_LANE : WInst<"vld1_lane", "dcdi", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; def VLD1_DUP : WInst<"vld1_dup", "dc", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; def VST1 : WInst<"vst1", "vpd", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; def VST1_X2 : WInst<"vst1_x2", "vp2", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VST1_X3 : WInst<"vst1_x3", "vp3", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VST1_X4 : WInst<"vst1_x4", "vp4", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VST1_LANE : WInst<"vst1_lane", "vpdi", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; +let ArchGuard = "(__ARM_FP & 2)" in { +def VLD1_F16 : WInst<"vld1", "dc", "hQh">; +def VLD1_X2_F16 : WInst<"vld1_x2", "2c", "hQh">; +def VLD1_X3_F16 : WInst<"vld1_x3", "3c", "hQh">; +def VLD1_X4_F16 : WInst<"vld1_x4", "4c", "hQh">; +def VLD1_LANE_F16 : WInst<"vld1_lane", "dcdi", "hQh">; +def VLD1_DUP_F16 : WInst<"vld1_dup", "dc", "hQh">; +def VST1_F16 : WInst<"vst1", "vpd", "hQh">; +def VST1_X2_F16 : WInst<"vst1_x2", "vp2", "hQh">; +def VST1_X3_F16 : WInst<"vst1_x3", "vp3", "hQh">; +def VST1_X4_F16 : WInst<"vst1_x4", "vp4", "hQh">; +def VST1_LANE_F16 : WInst<"vst1_lane", "vpdi", "hQh">; +} // E.3.15 Loads and stores of an N-element structure -def VLD2 : WInst<"vld2", "2c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">; -def VLD3 : WInst<"vld3", "3c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">; -def VLD4 : WInst<"vld4", "4c", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">; +def VLD2 : WInst<"vld2", "2c", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">; +def VLD3 : WInst<"vld3", "3c", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">; +def VLD4 : WInst<"vld4", "4c", "QUcQUsQUiQcQsQiQfQPcQPsUcUsUiUlcsilfPcPs">; def VLD2_DUP : WInst<"vld2_dup", "2c", - "UcUsUiUlcsilhfPcPsQcQfQhQiQlQsQPcQPsQUcQUiQUlQUs">; + "UcUsUiUlcsilfPcPsQcQfQiQlQsQPcQPsQUcQUiQUlQUs">; def VLD3_DUP : WInst<"vld3_dup", "3c", - "UcUsUiUlcsilhfPcPsQcQfQhQiQlQsQPcQPsQUcQUiQUlQUs">; + "UcUsUiUlcsilfPcPsQcQfQiQlQsQPcQPsQUcQUiQUlQUs">; def VLD4_DUP : WInst<"vld4_dup", "4c", - "UcUsUiUlcsilhfPcPsQcQfQhQiQlQsQPcQPsQUcQUiQUlQUs">; -def VLD2_LANE : WInst<"vld2_lane", "2c2i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">; -def VLD3_LANE : WInst<"vld3_lane", "3c3i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">; -def VLD4_LANE : WInst<"vld4_lane", "4c4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">; -def VST2 : WInst<"vst2", "vp2", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">; -def VST3 : WInst<"vst3", "vp3", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPs">; -def VST4 : WInst<"vst4", "vp4", "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcs
[PATCH] D38795: [CodeGen] emitOMPArraySectionBase() to generate TBAA info along with LValue base info
kosarev created this revision. kosarev added a project: clang. Prepared on top of https://reviews.llvm.org/D38733. Repository: rL LLVM https://reviews.llvm.org/D38795 Files: CodeGen/CGExpr.cpp Index: CodeGen/CGExpr.cpp === --- CodeGen/CGExpr.cpp +++ CodeGen/CGExpr.cpp @@ -3318,8 +3318,11 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, LValueBaseInfo &BaseInfo, + TBAAAccessInfo &TBAAInfo, QualType BaseTy, QualType ElTy, bool IsLowerBound) { + TBAAInfo = CGF.CGM.getTBAAAccessInfo(ElTy); + LValue BaseLVal; if (auto *ASE = dyn_cast(Base->IgnoreParenImpCasts())) { BaseLVal = CGF.EmitOMPArraySectionExpr(ASE, IsLowerBound); @@ -3454,13 +3457,14 @@ Address EltPtr = Address::invalid(); LValueBaseInfo BaseInfo; + TBAAAccessInfo TBAAInfo; if (auto *VLA = getContext().getAsVariableArrayType(ResultExprTy)) { // 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. Address Base = -emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, BaseTy, -VLA->getElementType(), IsLowerBound); +emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, +BaseTy, VLA->getElementType(), IsLowerBound); // The element count here is the total number of non-VLA elements. llvm::Value *NumElements = getVLASize(VLA).first; @@ -3496,16 +3500,17 @@ ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*SignedIndices=*/false, E->getExprLoc()); BaseInfo = ArrayLV.getBaseInfo(); +TBAAInfo = CGM.getTBAAAccessInfo(ResultExprTy); } else { Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, - BaseTy, ResultExprTy, IsLowerBound); + TBAAInfo, BaseTy, ResultExprTy, + IsLowerBound); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*SignedIndices=*/false, E->getExprLoc()); } - return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo, -CGM.getTBAAAccessInfo(ResultExprTy)); + return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo, TBAAInfo); } LValue CodeGenFunction:: Index: CodeGen/CGExpr.cpp === --- CodeGen/CGExpr.cpp +++ CodeGen/CGExpr.cpp @@ -3318,8 +3318,11 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, LValueBaseInfo &BaseInfo, + TBAAAccessInfo &TBAAInfo, QualType BaseTy, QualType ElTy, bool IsLowerBound) { + TBAAInfo = CGF.CGM.getTBAAAccessInfo(ElTy); + LValue BaseLVal; if (auto *ASE = dyn_cast(Base->IgnoreParenImpCasts())) { BaseLVal = CGF.EmitOMPArraySectionExpr(ASE, IsLowerBound); @@ -3454,13 +3457,14 @@ Address EltPtr = Address::invalid(); LValueBaseInfo BaseInfo; + TBAAAccessInfo TBAAInfo; if (auto *VLA = getContext().getAsVariableArrayType(ResultExprTy)) { // 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. Address Base = -emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, BaseTy, -VLA->getElementType(), IsLowerBound); +emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, +BaseTy, VLA->getElementType(), IsLowerBound); // The element count here is the total number of non-VLA elements. llvm::Value *NumElements = getVLASize(VLA).first; @@ -3496,16 +3500,17 @@ ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*SignedIndices=*/false, E->getExprLoc()); BaseInfo = ArrayLV.getBaseInfo(); +TBAAInfo = CGM.getTBAAAccessInfo(ResultExprTy); } else { Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, - BaseTy, ResultExprTy, IsLowerBound); + TBAAInfo, BaseTy, ResultExprTy, + IsLowerBound); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*SignedIndices=*/false, E->getExprLoc()); } - return MakeAddrLValue(EltPt
[PATCH] D38796: [CodeGen] EmitPointerWithAlignment() to generate TBAA info along with LValue base info
kosarev created this revision. kosarev added a project: clang. Prepared on top of https://reviews.llvm.org/D38795. Repository: rL LLVM https://reviews.llvm.org/D38796 Files: CodeGen/CGExpr.cpp CodeGen/CodeGenFunction.cpp CodeGen/CodeGenFunction.h CodeGen/CodeGenModule.cpp CodeGen/CodeGenModule.h CodeGen/CodeGenTBAA.cpp CodeGen/CodeGenTBAA.h Index: CodeGen/CodeGenTBAA.h === --- CodeGen/CodeGenTBAA.h +++ CodeGen/CodeGenTBAA.h @@ -47,6 +47,12 @@ : TBAAAccessInfo(/* AccessType= */ nullptr) {} + bool operator==(const TBAAAccessInfo &Other) const { +return BaseType == Other.BaseType && + AccessType == Other.AccessType && + Offset == Other.Offset; + } + /// BaseType - The base/leading access type. May be null if this access /// descriptor represents an access that is not considered to be an access /// to an aggregate or union member. @@ -136,6 +142,11 @@ /// getMayAliasAccessInfo - Get TBAA information that represents may-alias /// accesses. TBAAAccessInfo getMayAliasAccessInfo(); + + /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of + /// type casts. + TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo); }; } // end namespace CodeGen Index: CodeGen/CodeGenTBAA.cpp === --- CodeGen/CodeGenTBAA.cpp +++ CodeGen/CodeGenTBAA.cpp @@ -309,3 +309,11 @@ TBAAAccessInfo CodeGenTBAA::getMayAliasAccessInfo() { return TBAAAccessInfo(getChar()); } + +TBAAAccessInfo CodeGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo) { + TBAAAccessInfo MayAliasInfo = getMayAliasAccessInfo(); + if (SourceInfo == MayAliasInfo || TargetInfo == MayAliasInfo) +return MayAliasInfo; + return TargetInfo; +} Index: CodeGen/CodeGenModule.h === --- CodeGen/CodeGenModule.h +++ CodeGen/CodeGenModule.h @@ -677,6 +677,11 @@ /// may-alias accesses. TBAAAccessInfo getTBAAMayAliasAccessInfo(); + /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of + /// type casts. + TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo); + bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); bool isPaddedAtomicType(QualType type); Index: CodeGen/CodeGenModule.cpp === --- CodeGen/CodeGenModule.cpp +++ CodeGen/CodeGenModule.cpp @@ -612,6 +612,13 @@ return TBAA->getMayAliasAccessInfo(); } +TBAAAccessInfo CodeGenModule::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo) { + if (!TBAA) +return TBAAAccessInfo(); + return TBAA->mergeTBAAInfoForCast(SourceInfo, TargetInfo); +} + void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst, TBAAAccessInfo TBAAInfo) { if (llvm::MDNode *Tag = getTBAAAccessTagInfo(TBAAInfo)) Index: CodeGen/CodeGenFunction.h === --- CodeGen/CodeGenFunction.h +++ CodeGen/CodeGenFunction.h @@ -1942,7 +1942,8 @@ TBAAAccessInfo *TBAAInfo = nullptr, bool forPointeeType = false); CharUnits getNaturalPointeeTypeAlignment(QualType T, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, LValueBaseInfo *BaseInfo = nullptr, @@ -3188,7 +3189,8 @@ RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc); Address EmitArrayToPointerDecay(const Expr *Array, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); class ConstantEmission { llvm::PointerIntPair ValueAndIsReference; @@ -3910,7 +3912,8 @@ /// reasonable to just ignore the returned alignment when it isn't from an /// explicit source. Address EmitPointerWithAlignment(const Expr *Addr, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); Index: CodeGen/CodeGenFuncti
[PATCH] D38733: [CodeGen] Generate TBAA info along with LValue base info
This revision was automatically updated to reflect the committed changes. Closed by commit rL315575: [CodeGen] Generate TBAA info along with LValue base info (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38733?vs=118551&id=118771#toc Repository: rL LLVM https://reviews.llvm.org/D38733 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h Index: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp === --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp @@ -980,7 +980,8 @@ SharedLVal = CGF.MakeAddrLValue( CGF.Builder.CreateElementBitCast(SharedLVal.getAddress(), CGF.ConvertTypeForMem(SharedType)), - SharedType, SharedAddresses[N].first.getBaseInfo()); + SharedType, SharedAddresses[N].first.getBaseInfo(), + CGF.CGM.getTBAAAccessInfo(SharedType)); if (isa(ClausesData[N].Ref) || CGF.getContext().getAsArrayType(PrivateVD->getType())) { emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD); @@ -1033,7 +1034,8 @@ return CGF.MakeAddrLValue( CGF.Builder.CreateElementBitCast(BaseLV.getAddress(), CGF.ConvertTypeForMem(ElTy)), - BaseLV.getType(), BaseLV.getBaseInfo()); + BaseLV.getType(), BaseLV.getBaseInfo(), + CGF.CGM.getTBAAAccessInfo(BaseLV.getType())); } static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, @@ -4072,7 +4074,8 @@ Address(SharedRefLValue.getPointer(), C.getDeclAlign(OriginalVD)), SharedRefLValue.getType(), LValueBaseInfo(AlignmentSource::Decl, - SharedRefLValue.getBaseInfo().getMayAlias())); + SharedRefLValue.getBaseInfo().getMayAlias()), +CGF.CGM.getTBAAAccessInfo(SharedRefLValue.getType())); QualType Type = OriginalVD->getType(); if (Type->isArrayType()) { // Initialize firstprivate array. Index: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp === --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp @@ -180,7 +180,8 @@ CodeGenFunction::MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T) { LValueBaseInfo BaseInfo; CharUnits Align = getNaturalTypeAlignment(T, &BaseInfo, /*pointee*/ true); - return MakeAddrLValue(Address(V, Align), T, BaseInfo); + return MakeAddrLValue(Address(V, Align), T, BaseInfo, +CGM.getTBAAAccessInfo(T)); } Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -2159,7 +2159,8 @@ const ReferenceType *RefTy) { LValueBaseInfo BaseInfo; Address Addr = EmitLoadOfReference(RefAddr, RefTy, &BaseInfo); - return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo); + return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo, +CGM.getTBAAAccessInfo(RefTy->getPointeeType())); } Address CodeGenFunction::EmitLoadOfPointer(Address Ptr, @@ -2175,7 +2176,8 @@ const PointerType *PtrTy) { LValueBaseInfo BaseInfo; Address Addr = EmitLoadOfPointer(PtrAddr, PtrTy, &BaseInfo); - return MakeAddrLValue(Addr, PtrTy->getPointeeType(), BaseInfo); + return MakeAddrLValue(Addr, PtrTy->getPointeeType(), BaseInfo, +CGM.getTBAAAccessInfo(PtrTy->getPointeeType())); } static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, @@ -2328,7 +2330,8 @@ bool MayAlias = CapLVal.getBaseInfo().getMayAlias(); return MakeAddrLValue( Address(CapLVal.getPointer(), getContext().getDeclAlign(VD)), -CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl, MayAlias)); +CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl, MayAlias), +CGM.getTBAAAccessInfo(CapLVal.getType())); } assert(isa(CurCodeDecl)); @@ -2440,7 +2443,7 @@ LValueBaseInfo BaseInfo; Address Addr = EmitPointerWithAlignment(E->getSubExpr(), &BaseInfo); -LValue LV = MakeAddrLValue(Addr, T, BaseInfo); +LValue LV = MakeAddrLValue(Addr, T, BaseInfo, CGM.getTBAAAccessInfo(T)); LV.getQuals().setAddressSpace(ExprTy.getAddressSpace()); // We should not generate __weak write barrier on indirect reference @@ -2472,7 +2475,8 @@ (E->getOpcode() == UO_Real ? emitAddrOfRealComponent(LV.getAddress(), LV.getType()) : emitAddrOfImagComponent(LV.getAddress(), LV.getType())); -LValue ElemLV = MakeAddrLValue(Component, T, LV.getBase
[PATCH] D38788: [CodeGen] EmitCXXMemberDataPointerAddress() to generate TBAA info along with LValue base info
This revision was automatically updated to reflect the committed changes. Closed by commit rL315702: [CodeGen] EmitCXXMemberDataPointerAddress() to generate TBAA info along with… (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38788?vs=118560&id=118931#toc Repository: rL LLVM https://reviews.llvm.org/D38788 Files: cfe/trunk/lib/CodeGen/CGClass.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h Index: cfe/trunk/lib/CodeGen/CGClass.cpp === --- cfe/trunk/lib/CodeGen/CGClass.cpp +++ cfe/trunk/lib/CodeGen/CGClass.cpp @@ -129,13 +129,16 @@ CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, - LValueBaseInfo *BaseInfo) { + LValueBaseInfo *BaseInfo, + TBAAAccessInfo *TBAAInfo) { // Ask the ABI to compute the actual address. llvm::Value *ptr = CGM.getCXXABI().EmitMemberDataPointerAddress(*this, E, base, memberPtr, memberPtrType); QualType memberType = memberPtrType->getPointeeType(); + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(memberType); CharUnits memberAlign = getNaturalTypeAlignment(memberType, BaseInfo); memberAlign = CGM.getDynamicOffsetAlignment(base.getAlignment(), Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h === --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -3327,7 +3327,8 @@ Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue); Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -4566,11 +4566,12 @@ = E->getRHS()->getType()->getAs(); LValueBaseInfo BaseInfo; + TBAAAccessInfo TBAAInfo; Address MemberAddr = -EmitCXXMemberDataPointerAddress(E, BaseAddr, OffsetV, MPT, &BaseInfo); +EmitCXXMemberDataPointerAddress(E, BaseAddr, OffsetV, MPT, &BaseInfo, +&TBAAInfo); - return MakeAddrLValue(MemberAddr, MPT->getPointeeType(), BaseInfo, -CGM.getTBAAAccessInfo(MPT->getPointeeType())); + return MakeAddrLValue(MemberAddr, MPT->getPointeeType(), BaseInfo, TBAAInfo); } /// Given the address of a temporary variable, produce an r-value of Index: cfe/trunk/lib/CodeGen/CGClass.cpp === --- cfe/trunk/lib/CodeGen/CGClass.cpp +++ cfe/trunk/lib/CodeGen/CGClass.cpp @@ -129,13 +129,16 @@ CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, - LValueBaseInfo *BaseInfo) { + LValueBaseInfo *BaseInfo, + TBAAAccessInfo *TBAAInfo) { // Ask the ABI to compute the actual address. llvm::Value *ptr = CGM.getCXXABI().EmitMemberDataPointerAddress(*this, E, base, memberPtr, memberPtrType); QualType memberType = memberPtrType->getPointeeType(); + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(memberType); CharUnits memberAlign = getNaturalTypeAlignment(memberType, BaseInfo); memberAlign = CGM.getDynamicOffsetAlignment(base.getAlignment(), Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h === --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -3327,7 +3327,8 @@ Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, - LValueBaseInfo *BaseInfo = nullptr); +
[PATCH] D38791: [CodeGen] EmitLoadOfPointer() to generate TBAA info along with LValue base info
This revision was automatically updated to reflect the committed changes. Closed by commit rL315704: [CodeGen] EmitLoadOfPointer() to generate TBAA info along with LValue base info (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38791?vs=118575&id=118932#toc Repository: rL LLVM https://reviews.llvm.org/D38791 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -2165,7 +2165,11 @@ Address CodeGenFunction::EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, - LValueBaseInfo *BaseInfo) { + LValueBaseInfo *BaseInfo, + TBAAAccessInfo *TBAAInfo) { + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(PtrTy->getPointeeType()); + llvm::Value *Addr = Builder.CreateLoad(Ptr); return Address(Addr, getNaturalTypeAlignment(PtrTy->getPointeeType(), BaseInfo, @@ -2175,9 +2179,9 @@ LValue CodeGenFunction::EmitLoadOfPointerLValue(Address PtrAddr, const PointerType *PtrTy) { LValueBaseInfo BaseInfo; - Address Addr = EmitLoadOfPointer(PtrAddr, PtrTy, &BaseInfo); - return MakeAddrLValue(Addr, PtrTy->getPointeeType(), BaseInfo, -CGM.getTBAAAccessInfo(PtrTy->getPointeeType())); + TBAAAccessInfo TBAAInfo; + Address Addr = EmitLoadOfPointer(PtrAddr, PtrTy, &BaseInfo, &TBAAInfo); + return MakeAddrLValue(Addr, PtrTy->getPointeeType(), BaseInfo, TBAAInfo); } static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h === --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -1948,7 +1948,8 @@ LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, -LValueBaseInfo *BaseInfo = nullptr); +LValueBaseInfo *BaseInfo = nullptr, +TBAAAccessInfo *TBAAInfo = nullptr); LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy); /// CreateTempAlloca - This creates an alloca and inserts it into the entry Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -2165,7 +2165,11 @@ Address CodeGenFunction::EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, - LValueBaseInfo *BaseInfo) { + LValueBaseInfo *BaseInfo, + TBAAAccessInfo *TBAAInfo) { + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(PtrTy->getPointeeType()); + llvm::Value *Addr = Builder.CreateLoad(Ptr); return Address(Addr, getNaturalTypeAlignment(PtrTy->getPointeeType(), BaseInfo, @@ -2175,9 +2179,9 @@ LValue CodeGenFunction::EmitLoadOfPointerLValue(Address PtrAddr, const PointerType *PtrTy) { LValueBaseInfo BaseInfo; - Address Addr = EmitLoadOfPointer(PtrAddr, PtrTy, &BaseInfo); - return MakeAddrLValue(Addr, PtrTy->getPointeeType(), BaseInfo, -CGM.getTBAAAccessInfo(PtrTy->getPointeeType())); + TBAAAccessInfo TBAAInfo; + Address Addr = EmitLoadOfPointer(PtrAddr, PtrTy, &BaseInfo, &TBAAInfo); + return MakeAddrLValue(Addr, PtrTy->getPointeeType(), BaseInfo, TBAAInfo); } static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h === --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -1948,7 +1948,8 @@ LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, -LValueBaseInfo *BaseInfo = nullptr); +LValueBaseInfo *BaseInfo = nullptr, +TBAAAccessInfo *TBAAInfo = nullptr); LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy); /// CreateTempAlloca - This creates an alloca and inserts it into the entry ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38793: [CodeGen] EmitLoadOfReference() to generate TBAA info along with LValue base info
This revision was automatically updated to reflect the committed changes. Closed by commit rL315705: [CodeGen] EmitLoadOfReference() to generate TBAA info along with LValue base… (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38793?vs=118578&id=118933#toc Repository: rL LLVM https://reviews.llvm.org/D38793 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -2149,18 +2149,22 @@ Address CodeGenFunction::EmitLoadOfReference(Address Addr, const ReferenceType *RefTy, - LValueBaseInfo *BaseInfo) { + LValueBaseInfo *BaseInfo, + TBAAAccessInfo *TBAAInfo) { + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(RefTy->getPointeeType()); + llvm::Value *Ptr = Builder.CreateLoad(Addr); return Address(Ptr, getNaturalTypeAlignment(RefTy->getPointeeType(), BaseInfo, /*forPointee*/ true)); } LValue CodeGenFunction::EmitLoadOfReferenceLValue(Address RefAddr, const ReferenceType *RefTy) { LValueBaseInfo BaseInfo; - Address Addr = EmitLoadOfReference(RefAddr, RefTy, &BaseInfo); - return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo, -CGM.getTBAAAccessInfo(RefTy->getPointeeType())); + TBAAAccessInfo TBAAInfo; + Address Addr = EmitLoadOfReference(RefAddr, RefTy, &BaseInfo, &TBAAInfo); + return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo, TBAAInfo); } Address CodeGenFunction::EmitLoadOfPointer(Address Ptr, Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h === --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -1944,7 +1944,8 @@ LValueBaseInfo *BaseInfo = nullptr); Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -2149,18 +2149,22 @@ Address CodeGenFunction::EmitLoadOfReference(Address Addr, const ReferenceType *RefTy, - LValueBaseInfo *BaseInfo) { + LValueBaseInfo *BaseInfo, + TBAAAccessInfo *TBAAInfo) { + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(RefTy->getPointeeType()); + llvm::Value *Ptr = Builder.CreateLoad(Addr); return Address(Ptr, getNaturalTypeAlignment(RefTy->getPointeeType(), BaseInfo, /*forPointee*/ true)); } LValue CodeGenFunction::EmitLoadOfReferenceLValue(Address RefAddr, const ReferenceType *RefTy) { LValueBaseInfo BaseInfo; - Address Addr = EmitLoadOfReference(RefAddr, RefTy, &BaseInfo); - return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo, -CGM.getTBAAAccessInfo(RefTy->getPointeeType())); + TBAAAccessInfo TBAAInfo; + Address Addr = EmitLoadOfReference(RefAddr, RefTy, &BaseInfo, &TBAAInfo); + return MakeAddrLValue(Addr, RefTy->getPointeeType(), BaseInfo, TBAAInfo); } Address CodeGenFunction::EmitLoadOfPointer(Address Ptr, Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h === --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -1944,7 +1944,8 @@ LValueBaseInfo *BaseInfo = nullptr); Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cf
[PATCH] D38794: [CodeGen] getNaturalTypeAlignment() to generate TBAA info along with LValue base info
This revision was automatically updated to reflect the committed changes. Closed by commit rL315708: [CodeGen] getNaturalTypeAlignment() to generate TBAA info along with LValue… (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38794?vs=118581&id=118934#toc Repository: rL LLVM https://reviews.llvm.org/D38794 Files: cfe/trunk/lib/CodeGen/CGClass.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h === --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -1939,6 +1939,7 @@ LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T); CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo = nullptr, +TBAAAccessInfo *TBAAInfo = nullptr, bool forPointeeType = false); CharUnits getNaturalPointeeTypeAlignment(QualType T, LValueBaseInfo *BaseInfo = nullptr); Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -2151,12 +2151,10 @@ const ReferenceType *RefTy, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo) { - if (TBAAInfo) -*TBAAInfo = CGM.getTBAAAccessInfo(RefTy->getPointeeType()); - llvm::Value *Ptr = Builder.CreateLoad(Addr); return Address(Ptr, getNaturalTypeAlignment(RefTy->getPointeeType(), - BaseInfo, /*forPointee*/ true)); + BaseInfo, TBAAInfo, + /* forPointeeType= */ true)); } LValue CodeGenFunction::EmitLoadOfReferenceLValue(Address RefAddr, @@ -2171,12 +2169,9 @@ const PointerType *PtrTy, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo) { - if (TBAAInfo) -*TBAAInfo = CGM.getTBAAAccessInfo(PtrTy->getPointeeType()); - llvm::Value *Addr = Builder.CreateLoad(Ptr); return Address(Addr, getNaturalTypeAlignment(PtrTy->getPointeeType(), - BaseInfo, + BaseInfo, TBAAInfo, /*forPointeeType=*/true)); } @@ -2315,8 +2310,10 @@ // FIXME: Eventually we will want to emit vector element references. // Should we be using the alignment of the constant pointer we emitted? - CharUnits Alignment = getNaturalTypeAlignment(E->getType(), nullptr, -/*pointee*/ true); + CharUnits Alignment = getNaturalTypeAlignment(E->getType(), +/* BaseInfo= */ nullptr, +/* TBAAInfo= */ nullptr, +/* forPointeeType= */ true); return MakeAddrLValue(Address(Val, Alignment), T, AlignmentSource::Decl); } @@ -3729,7 +3726,8 @@ type = refType->getPointeeType(); CharUnits alignment = -getNaturalTypeAlignment(type, &FieldBaseInfo, /*pointee*/ true); +getNaturalTypeAlignment(type, &FieldBaseInfo, /* TBAAInfo= */ nullptr, +/* forPointeeType= */ true); FieldBaseInfo.setMayAlias(false); addr = Address(load, alignment); Index: cfe/trunk/lib/CodeGen/CGClass.cpp === --- cfe/trunk/lib/CodeGen/CGClass.cpp +++ cfe/trunk/lib/CodeGen/CGClass.cpp @@ -137,9 +137,8 @@ memberPtr, memberPtrType); QualType memberType = memberPtrType->getPointeeType(); - if (TBAAInfo) -*TBAAInfo = CGM.getTBAAAccessInfo(memberType); - CharUnits memberAlign = getNaturalTypeAlignment(memberType, BaseInfo); + CharUnits memberAlign = getNaturalTypeAlignment(memberType, BaseInfo, + TBAAInfo); memberAlign = CGM.getDynamicOffsetAlignment(base.getAlignment(), memberPtrType->getClass()->getAsCXXRecordDecl(), Index: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp === --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp @@ -120,12 +120,17 @@ CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T,
[PATCH] D38794: [CodeGen] getNaturalTypeAlignment() to generate TBAA info along with LValue base info
kosarev added a comment. Right. Switching back to returning just AlignmentSource would make its name more adequate, but I suspect we intentionally want full-size lvalue base info here. Repository: rL LLVM https://reviews.llvm.org/D38794 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38795: [CodeGen] emitOMPArraySectionBase() to generate TBAA info along with LValue base info
This revision was automatically updated to reflect the committed changes. Closed by commit rL315715: [CodeGen] emitOMPArraySectionBase() to generate TBAA info along with LValue… (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38795?vs=118585&id=118940#toc Repository: rL LLVM https://reviews.llvm.org/D38795 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -3318,8 +3318,11 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, LValueBaseInfo &BaseInfo, + TBAAAccessInfo &TBAAInfo, QualType BaseTy, QualType ElTy, bool IsLowerBound) { + TBAAInfo = CGF.CGM.getTBAAAccessInfo(ElTy); + LValue BaseLVal; if (auto *ASE = dyn_cast(Base->IgnoreParenImpCasts())) { BaseLVal = CGF.EmitOMPArraySectionExpr(ASE, IsLowerBound); @@ -3449,13 +3452,14 @@ Address EltPtr = Address::invalid(); LValueBaseInfo BaseInfo; + TBAAAccessInfo TBAAInfo; if (auto *VLA = getContext().getAsVariableArrayType(ResultExprTy)) { // 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. Address Base = -emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, BaseTy, -VLA->getElementType(), IsLowerBound); +emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, +BaseTy, VLA->getElementType(), IsLowerBound); // The element count here is the total number of non-VLA elements. llvm::Value *NumElements = getVLASize(VLA).first; @@ -3491,16 +3495,17 @@ ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*SignedIndices=*/false, E->getExprLoc()); BaseInfo = ArrayLV.getBaseInfo(); +TBAAInfo = CGM.getTBAAAccessInfo(ResultExprTy); } else { Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, - BaseTy, ResultExprTy, IsLowerBound); + TBAAInfo, BaseTy, ResultExprTy, + IsLowerBound); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*SignedIndices=*/false, E->getExprLoc()); } - return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo, -CGM.getTBAAAccessInfo(ResultExprTy)); + return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo, TBAAInfo); } LValue CodeGenFunction:: Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -3318,8 +3318,11 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, LValueBaseInfo &BaseInfo, + TBAAAccessInfo &TBAAInfo, QualType BaseTy, QualType ElTy, bool IsLowerBound) { + TBAAInfo = CGF.CGM.getTBAAAccessInfo(ElTy); + LValue BaseLVal; if (auto *ASE = dyn_cast(Base->IgnoreParenImpCasts())) { BaseLVal = CGF.EmitOMPArraySectionExpr(ASE, IsLowerBound); @@ -3449,13 +3452,14 @@ Address EltPtr = Address::invalid(); LValueBaseInfo BaseInfo; + TBAAAccessInfo TBAAInfo; if (auto *VLA = getContext().getAsVariableArrayType(ResultExprTy)) { // 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. Address Base = -emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, BaseTy, -VLA->getElementType(), IsLowerBound); +emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, +BaseTy, VLA->getElementType(), IsLowerBound); // The element count here is the total number of non-VLA elements. llvm::Value *NumElements = getVLASize(VLA).first; @@ -3491,16 +3495,17 @@ ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*SignedIndices=*/false, E->getExprLoc()); BaseInfo = ArrayLV.getBaseInfo(); +TBAAInfo = CGM.getTBAAAccessInfo(ResultExprTy); } else { Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, - BaseTy, ResultExprTy, IsLowerBound); + TBAAInfo, BaseTy, ResultExprTy, + IsLowerBou
[PATCH] D38796: [CodeGen] EmitPointerWithAlignment() to generate TBAA info along with LValue base info
This revision was automatically updated to reflect the committed changes. Closed by commit rL315731: [CodeGen] EmitPointerWithAlignment() to generate TBAA info along with LValue… (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38796?vs=118599&id=118950#toc Repository: rL LLVM https://reviews.llvm.org/D38796 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/lib/CodeGen/CodeGenModule.h cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp cfe/trunk/lib/CodeGen/CodeGenTBAA.h Index: cfe/trunk/lib/CodeGen/CodeGenTBAA.h === --- cfe/trunk/lib/CodeGen/CodeGenTBAA.h +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.h @@ -47,6 +47,12 @@ : TBAAAccessInfo(/* AccessType= */ nullptr) {} + bool operator==(const TBAAAccessInfo &Other) const { +return BaseType == Other.BaseType && + AccessType == Other.AccessType && + Offset == Other.Offset; + } + /// BaseType - The base/leading access type. May be null if this access /// descriptor represents an access that is not considered to be an access /// to an aggregate or union member. @@ -136,6 +142,11 @@ /// getMayAliasAccessInfo - Get TBAA information that represents may-alias /// accesses. TBAAAccessInfo getMayAliasAccessInfo(); + + /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of + /// type casts. + TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo); }; } // end namespace CodeGen Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h === --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -1942,7 +1942,8 @@ TBAAAccessInfo *TBAAInfo = nullptr, bool forPointeeType = false); CharUnits getNaturalPointeeTypeAlignment(QualType T, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, LValueBaseInfo *BaseInfo = nullptr, @@ -3188,7 +3189,8 @@ RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc); Address EmitArrayToPointerDecay(const Expr *Array, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); class ConstantEmission { llvm::PointerIntPair ValueAndIsReference; @@ -3910,7 +3912,8 @@ /// reasonable to just ignore the returned alignment when it isn't from an /// explicit source. Address EmitPointerWithAlignment(const Expr *Addr, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -916,7 +916,8 @@ /// EmitPointerWithAlignment - Given an expression of pointer type, try to /// derive a more accurate bound on the alignment of the pointer. Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, - LValueBaseInfo *BaseInfo) { + LValueBaseInfo *BaseInfo, + TBAAAccessInfo *TBAAInfo) { // We allow this with ObjC object pointers because of fragile ABIs. assert(E->getType()->isPointerType() || E->getType()->isObjCObjectPointerType()); @@ -936,19 +937,28 @@ if (PtrTy->getPointeeType()->isVoidType()) break; -LValueBaseInfo InnerInfo; -Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), &InnerInfo); -if (BaseInfo) *BaseInfo = InnerInfo; +LValueBaseInfo InnerBaseInfo; +TBAAAccessInfo InnerTBAAInfo; +Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), +&InnerBaseInfo, +&InnerTBAAInfo); +if (BaseInfo) *BaseInfo = InnerBaseInfo; +if (TBAAInfo) *TBAAInfo = InnerTBAAInfo; // If this is an explicit bitcast, and the source l-value is // opaque, honor the alignment of the casted-to type
[PATCH] D38796: [CodeGen] EmitPointerWithAlignment() to generate TBAA info along with LValue base info
kosarev added a comment. With this patch applied we fail on bootstrapping stages of release builds (meaning enabled TBAA). The reason is that for some casts we do not generate TBAA info that corresponds to the target type and leave them with TBAA info for the cast's operand expression. This results in invalid TBAA access descriptors. For example, for the following store we generate a TBAA descriptor with ##S## as the base type and ##unsigned## as the access type while the expected descriptor shall have ##V## as the base type and ##unsigned## as the access type. struct V { unsigned n; }; struct S { char bytes[4]; }; void foo(S *p) { ((V*)p->bytes)->n = 0; } Repository: rL LLVM https://reviews.llvm.org/D38796 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38796: [CodeGen] EmitPointerWithAlignment() to generate TBAA info along with LValue base info
kosarev updated this revision to Diff 119089. kosarev edited the summary of this revision. kosarev added a comment. - Fixed handling of explicit casts. - Added a test case. https://reviews.llvm.org/D38796 Files: lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/CodeGenTBAA.cpp lib/CodeGen/CodeGenTBAA.h test/CodeGen/tbaa-cast.cpp Index: test/CodeGen/tbaa-cast.cpp === --- test/CodeGen/tbaa-cast.cpp +++ test/CodeGen/tbaa-cast.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for lvalues constructed +// with use of casts. + +struct V { + unsigned n; +}; + +struct S { + char bytes[4]; +}; + +void foo(S *p) { +// CHECK-LABEL: _Z3fooP1S +// CHECK: store i32 5, {{.*}}, !tbaa [[TAG_V_n:!.*]] + ((V*)p->bytes)->n = 5; +} + +// CHECK-DAG: [[TAG_V_n]] = !{[[TYPE_V:!.*]], [[TYPE_int:!.*]], i64 0} +// CHECK-DAG: [[TYPE_V]] = !{!"_ZTS1V", !{{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} Index: lib/CodeGen/CodeGenTBAA.h === --- lib/CodeGen/CodeGenTBAA.h +++ lib/CodeGen/CodeGenTBAA.h @@ -47,6 +47,12 @@ : TBAAAccessInfo(/* AccessType= */ nullptr) {} + bool operator==(const TBAAAccessInfo &Other) const { +return BaseType == Other.BaseType && + AccessType == Other.AccessType && + Offset == Other.Offset; + } + /// BaseType - The base/leading access type. May be null if this access /// descriptor represents an access that is not considered to be an access /// to an aggregate or union member. @@ -136,6 +142,11 @@ /// getMayAliasAccessInfo - Get TBAA information that represents may-alias /// accesses. TBAAAccessInfo getMayAliasAccessInfo(); + + /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of + /// type casts. + TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo); }; } // end namespace CodeGen Index: lib/CodeGen/CodeGenTBAA.cpp === --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -309,3 +309,11 @@ TBAAAccessInfo CodeGenTBAA::getMayAliasAccessInfo() { return TBAAAccessInfo(getChar()); } + +TBAAAccessInfo CodeGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo) { + TBAAAccessInfo MayAliasInfo = getMayAliasAccessInfo(); + if (SourceInfo == MayAliasInfo || TargetInfo == MayAliasInfo) +return MayAliasInfo; + return TargetInfo; +} Index: lib/CodeGen/CodeGenModule.h === --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -677,6 +677,11 @@ /// may-alias accesses. TBAAAccessInfo getTBAAMayAliasAccessInfo(); + /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of + /// type casts. + TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo); + bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); bool isPaddedAtomicType(QualType type); Index: lib/CodeGen/CodeGenModule.cpp === --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -612,6 +612,13 @@ return TBAA->getMayAliasAccessInfo(); } +TBAAAccessInfo CodeGenModule::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo) { + if (!TBAA) +return TBAAAccessInfo(); + return TBAA->mergeTBAAInfoForCast(SourceInfo, TargetInfo); +} + void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst, TBAAAccessInfo TBAAInfo) { if (llvm::MDNode *Tag = getTBAAAccessTagInfo(TBAAInfo)) Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -1942,7 +1942,8 @@ TBAAAccessInfo *TBAAInfo = nullptr, bool forPointeeType = false); CharUnits getNaturalPointeeTypeAlignment(QualType T, - LValueBaseInfo *BaseInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr, + TBAAAccessInfo *TBAAInfo = nullptr); Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, LValueBaseInfo *BaseInfo = nullptr, @@ -3
[PATCH] D38945: [CodeGen] Pass TBAA info along with lvalue base info everywhere
kosarev created this revision. kosarev added a project: clang. This patch addresses the rest of the cases where we pass lvalue base info, but do not provide corresponding TBAA info. This patch should not bring in any functional changes. This is part of https://reviews.llvm.org/D38126 reworked to be a separate patch to make reviewing easier. Repository: rL LLVM https://reviews.llvm.org/D38945 Files: lib/CodeGen/CGAtomic.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGObjCRuntime.cpp lib/CodeGen/CGValue.h lib/CodeGen/CodeGenFunction.h Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3081,13 +3081,6 @@ llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, LValueBaseInfo BaseInfo, -bool isNontemporal = false) { -return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, BaseInfo, -CGM.getTBAAAccessInfo(Ty), isNontemporal); - } - - llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, -SourceLocation Loc, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, bool isNontemporal = false); @@ -3109,13 +3102,6 @@ } void EmitStoreOfScalar(llvm::Value *Value, Address Addr, - bool Volatile, QualType Ty, LValueBaseInfo BaseInfo, - bool isInit = false, bool isNontemporal = false) { -EmitStoreOfScalar(Value, Addr, Volatile, Ty, BaseInfo, - CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal); - } - - void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, bool isInit = false, bool isNontemporal = false); Index: lib/CodeGen/CGValue.h === --- lib/CodeGen/CGValue.h +++ lib/CodeGen/CGValue.h @@ -230,9 +230,8 @@ Expr *BaseIvarExp; private: - void Initialize(QualType Type, Qualifiers Quals, - CharUnits Alignment, LValueBaseInfo BaseInfo, - TBAAAccessInfo TBAAInfo = TBAAAccessInfo()) { + void Initialize(QualType Type, Qualifiers Quals, CharUnits Alignment, + LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { assert((!Alignment.isZero() || Type->isIncompleteType()) && "initializing l-value with zero alignment!"); this->Type = Type; @@ -381,24 +380,26 @@ } static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx, - QualType type, LValueBaseInfo BaseInfo) { + QualType type, LValueBaseInfo BaseInfo, + TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = VectorElt; R.V = vecAddress.getPointer(); R.VectorIdx = Idx; R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), - BaseInfo); + BaseInfo, TBAAInfo); return R; } static LValue MakeExtVectorElt(Address vecAddress, llvm::Constant *Elts, - QualType type, LValueBaseInfo BaseInfo) { + QualType type, LValueBaseInfo BaseInfo, + TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = ExtVectorElt; R.V = vecAddress.getPointer(); R.VectorElts = Elts; R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(), - BaseInfo); + BaseInfo, TBAAInfo); return R; } @@ -408,24 +409,25 @@ /// bit-field refers to. /// \param Info - The information describing how to perform the bit-field /// access. - static LValue MakeBitfield(Address Addr, - const CGBitFieldInfo &Info, - QualType type, - LValueBaseInfo BaseInfo) { + static LValue MakeBitfield(Address Addr, const CGBitFieldInfo &Info, + QualType type, LValueBaseInfo BaseInfo, + TBAAAccessInfo TBAAInfo) { LValue R; R.LVType = BitField; R.V = Addr.getPointer(); R.BitFieldInfo = &Info; -R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo); +R.Initialize(type, type.getQualifiers(), Addr.getAlignment(), BaseInfo, + TBAAInfo); return R; } static LValue MakeGlobalReg(Address Reg, QualType type) { LValue R; R.LVType = GlobalReg; R.V = Reg.getPointer(); R.Initialize(type, type.getQualifiers(), Reg.getAlignment(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource
[PATCH] D38947: [CodeGen] Refine generation of TBAA info for bit-field lvalues
kosarev created this revision. kosarev added a project: clang. The main change is that now we generate TBAA info before constructing the resulting lvalue instead of constructing lvalue with some default TBAA info and fixing it as necessary afterwards. We also keep the TBAA info close to lvalue base info, which is supposed to simplify their future merging. This patch should not bring in any functional changes. This is part of https://reviews.llvm.org/D38126 reworked to be a separate patch to simplify review. Repository: rL LLVM https://reviews.llvm.org/D38947 Files: lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -3229,7 +3229,7 @@ llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); - LValue EmitLValueForField(LValue Base, const FieldDecl* Field); + LValue EmitLValueForField(LValue BaseExpr, const FieldDecl *Field); LValue EmitLValueForLambdaField(const FieldDecl *Field); /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3662,130 +3662,118 @@ return false; } -LValue CodeGenFunction::EmitLValueForField(LValue base, - const FieldDecl *field) { - LValueBaseInfo BaseInfo = base.getBaseInfo(); - AlignmentSource fieldAlignSource = -getFieldAlignmentSource(BaseInfo.getAlignmentSource()); - LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias()); +LValue CodeGenFunction::EmitLValueForField(LValue BaseExpr, + const FieldDecl *Field) { + LValueBaseInfo BaseInfo = BaseExpr.getBaseInfo(); - QualType type = field->getType(); - const RecordDecl *rec = field->getParent(); - if (rec->isUnion() || rec->hasAttr() || type->isVectorType()) -FieldBaseInfo.setMayAlias(true); - bool mayAlias = FieldBaseInfo.getMayAlias(); - - if (field->isBitField()) { + if (Field->isBitField()) { const CGRecordLayout &RL = - CGM.getTypes().getCGRecordLayout(field->getParent()); -const CGBitFieldInfo &Info = RL.getBitFieldInfo(field); -Address Addr = base.getAddress(); -unsigned Idx = RL.getLLVMFieldNo(field); + CGM.getTypes().getCGRecordLayout(Field->getParent()); +const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field); +Address Addr = BaseExpr.getAddress(); +unsigned Idx = RL.getLLVMFieldNo(Field); if (Idx != 0) // For structs, we GEP to the field that the record layout suggests. Addr = Builder.CreateStructGEP(Addr, Idx, Info.StorageOffset, - field->getName()); + Field->getName()); // Get the access type. llvm::Type *FieldIntTy = llvm::Type::getIntNTy(getLLVMContext(), Info.StorageSize); if (Addr.getElementType() != FieldIntTy) Addr = Builder.CreateElementBitCast(Addr, FieldIntTy); -QualType fieldType = - field->getType().withCVRQualifiers(base.getVRQualifiers()); -return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo); +QualType FieldType = + Field->getType().withCVRQualifiers(BaseExpr.getVRQualifiers()); +// TODO: Support TBAA for bit fields. +LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource(), false); +return LValue::MakeBitfield(Addr, Info, FieldType, FieldBaseInfo); } - Address addr = base.getAddress(); - unsigned cvr = base.getVRQualifiers(); - bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; - if (rec->isUnion()) { -// For unions, there is no pointer adjustment. -assert(!type->isReferenceType() && "union has reference member"); -// TODO: handle path-aware TBAA for union. -TBAAPath = false; + // Fields of may-alias structures are may-alias themselves. + // FIXME: this should get propagated down through anonymous structs + // and unions. + QualType FieldType = Field->getType(); + const RecordDecl *Rec = Field->getParent(); + AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource(); + LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource), false); + TBAAAccessInfo FieldTBAAInfo; + if (BaseInfo.getMayAlias() || Rec->hasAttr() || + FieldType->isVectorType()) { +FieldBaseInfo.setMayAlias(true); +FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + } else if (Rec->isUnion()) { +// TODO: Support TBAA for unions. +FieldBaseInfo.setMayAlias(true); +FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + } else { +// If no base type been assigned for the base access, then try to generate +// one for this base lvalue. +FieldTBAAInfo = BaseExpr.getTBAAInfo(); +if
[PATCH] D38947: [CodeGen] Refine generation of TBAA info for bit-field lvalues
kosarev updated this revision to Diff 119257. kosarev added a comment. - Removed renamings that complicate reviewing. https://reviews.llvm.org/D38947 Files: lib/CodeGen/CGExpr.cpp Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3665,15 +3665,6 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field) { LValueBaseInfo BaseInfo = base.getBaseInfo(); - AlignmentSource fieldAlignSource = -getFieldAlignmentSource(BaseInfo.getAlignmentSource()); - LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias()); - - QualType type = field->getType(); - const RecordDecl *rec = field->getParent(); - if (rec->isUnion() || rec->hasAttr() || type->isVectorType()) -FieldBaseInfo.setMayAlias(true); - bool mayAlias = FieldBaseInfo.getMayAlias(); if (field->isBitField()) { const CGRecordLayout &RL = @@ -3693,19 +3684,54 @@ QualType fieldType = field->getType().withCVRQualifiers(base.getVRQualifiers()); +// TODO: Support TBAA for bit fields. +LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource(), false); return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo); } + // Fields of may-alias structures are may-alias themselves. + // FIXME: this should get propagated down through anonymous structs + // and unions. + QualType FieldType = field->getType(); + const RecordDecl *rec = field->getParent(); + AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource(); + LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource), false); + TBAAAccessInfo FieldTBAAInfo; + if (BaseInfo.getMayAlias() || rec->hasAttr() || + FieldType->isVectorType()) { +FieldBaseInfo.setMayAlias(true); +FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + } else if (rec->isUnion()) { +// TODO: Support TBAA for unions. +FieldBaseInfo.setMayAlias(true); +FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + } else { +// If no base type been assigned for the base access, then try to generate +// one for this base lvalue. +FieldTBAAInfo = base.getTBAAInfo(); +if (!FieldTBAAInfo.BaseType) { +FieldTBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(base.getType()); +assert(!FieldTBAAInfo.Offset && + "Nonzero offset for an access with no base type!"); +} + +// Adjust offset to be relative to the base type. +const ASTRecordLayout &Layout = +getContext().getASTRecordLayout(field->getParent()); +unsigned CharWidth = getContext().getCharWidth(); +if (FieldTBAAInfo.BaseType) + FieldTBAAInfo.Offset += + Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; + +// Update the final access type. +FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType); + } + Address addr = base.getAddress(); unsigned cvr = base.getVRQualifiers(); - bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; if (rec->isUnion()) { // For unions, there is no pointer adjustment. -assert(!type->isReferenceType() && "union has reference member"); -// TODO: handle path-aware TBAA for union. -TBAAPath = false; - -const auto FieldType = field->getType(); +assert(!FieldType->isReferenceType() && "union has reference member"); if (CGM.getCodeGenOpts().StrictVTablePointers && hasAnyVptr(FieldType, getContext())) // Because unions can easily skip invariant.barriers, we need to add @@ -3717,24 +3743,18 @@ addr = emitAddrOfFieldStorage(*this, addr, field); // If this is a reference field, load the reference right now. -if (const ReferenceType *refType = type->getAs()) { +if (const ReferenceType *refType = FieldType->getAs()) { llvm::LoadInst *load = Builder.CreateLoad(addr, "ref"); if (cvr & Qualifiers::Volatile) load->setVolatile(true); - // Loading the reference will disable path-aware TBAA. - TBAAPath = false; - TBAAAccessInfo TBAAInfo = mayAlias ? CGM.getTBAAMayAliasAccessInfo() : - CGM.getTBAAAccessInfo(type); - CGM.DecorateInstructionWithTBAA(load, TBAAInfo); - - mayAlias = false; - type = refType->getPointeeType(); - - CharUnits alignment = -getNaturalTypeAlignment(type, &FieldBaseInfo, /* TBAAInfo= */ nullptr, -/* forPointeeType= */ true); - FieldBaseInfo.setMayAlias(false); - addr = Address(load, alignment); + CGM.DecorateInstructionWithTBAA(load, FieldTBAAInfo); + + FieldType = refType->getPointeeType(); + + CharUnits Align = getNaturalTypeAlignment(FieldType, &FieldBaseInfo, +&FieldTBAAInfo, +/* forPointeeType= */ true); + addr = Address(load, Align); // Qualif
[PATCH] D38947: [CodeGen] Refine generation of TBAA info for bit-field lvalues
kosarev added a comment. Yes, some preparation code moved past the isBitField() block and generation of TBAA info moved before creating the bit-field lvalue. Thanks for catching the BaseExpr renaming. https://reviews.llvm.org/D38947 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38796: [CodeGen] EmitPointerWithAlignment() to generate TBAA info along with LValue base info
This revision was automatically updated to reflect the committed changes. Closed by commit rL315984: [CodeGen] EmitPointerWithAlignment() to generate TBAA info along with LValue… (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38796?vs=119089&id=119272#toc Repository: rL LLVM https://reviews.llvm.org/D38796 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/lib/CodeGen/CodeGenModule.h cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp cfe/trunk/lib/CodeGen/CodeGenTBAA.h cfe/trunk/test/CodeGen/tbaa-cast.cpp Index: cfe/trunk/test/CodeGen/tbaa-cast.cpp === --- cfe/trunk/test/CodeGen/tbaa-cast.cpp +++ cfe/trunk/test/CodeGen/tbaa-cast.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for lvalues constructed +// with use of casts. + +struct V { + unsigned n; +}; + +struct S { + char bytes[4]; +}; + +void foo(S *p) { +// CHECK-LABEL: _Z3fooP1S +// CHECK: store i32 5, {{.*}}, !tbaa [[TAG_V_n:!.*]] + ((V*)p->bytes)->n = 5; +} + +// CHECK-DAG: [[TAG_V_n]] = !{[[TYPE_V:!.*]], [[TYPE_int:!.*]], i64 0} +// CHECK-DAG: [[TYPE_V]] = !{!"_ZTS1V", !{{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -916,7 +916,8 @@ /// EmitPointerWithAlignment - Given an expression of pointer type, try to /// derive a more accurate bound on the alignment of the pointer. Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, - LValueBaseInfo *BaseInfo) { + LValueBaseInfo *BaseInfo, + TBAAAccessInfo *TBAAInfo) { // We allow this with ObjC object pointers because of fragile ABIs. assert(E->getType()->isPointerType() || E->getType()->isObjCObjectPointerType()); @@ -936,20 +937,30 @@ if (PtrTy->getPointeeType()->isVoidType()) break; -LValueBaseInfo InnerInfo; -Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), &InnerInfo); -if (BaseInfo) *BaseInfo = InnerInfo; - -// If this is an explicit bitcast, and the source l-value is -// opaque, honor the alignment of the casted-to type. -if (isa(CE) && -InnerInfo.getAlignmentSource() != AlignmentSource::Decl) { - LValueBaseInfo ExpInfo; +LValueBaseInfo InnerBaseInfo; +TBAAAccessInfo InnerTBAAInfo; +Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), +&InnerBaseInfo, +&InnerTBAAInfo); +if (BaseInfo) *BaseInfo = InnerBaseInfo; +if (TBAAInfo) *TBAAInfo = InnerTBAAInfo; + +if (isa(CE)) { + LValueBaseInfo TargetTypeBaseInfo; + TBAAAccessInfo TargetTypeTBAAInfo; CharUnits Align = getNaturalPointeeTypeAlignment(E->getType(), - &ExpInfo); - if (BaseInfo) -BaseInfo->mergeForCast(ExpInfo); - Addr = Address(Addr.getPointer(), Align); + &TargetTypeBaseInfo, + &TargetTypeTBAAInfo); + if (TBAAInfo) +*TBAAInfo = CGM.mergeTBAAInfoForCast(*TBAAInfo, + TargetTypeTBAAInfo); + // If the source l-value is opaque, honor the alignment of the + // casted-to type. + if (InnerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) { +if (BaseInfo) + BaseInfo->mergeForCast(TargetTypeBaseInfo); +Addr = Address(Addr.getPointer(), Align); + } } if (SanOpts.has(SanitizerKind::CFIUnrelatedCast) && @@ -969,12 +980,13 @@ // Array-to-pointer decay. case CK_ArrayToPointerDecay: - return EmitArrayToPointerDecay(CE->getSubExpr(), BaseInfo); + return EmitArrayToPointerDecay(CE->getSubExpr(), BaseInfo, TBAAInfo); // Derived-to-base conversions. case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { - Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo); + Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo, + TBAAInfo); auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl(); return GetAddressOfBaseClass(Addr, Derived,
[PATCH] D38945: [CodeGen] Pass TBAA info along with lvalue base info everywhere
This revision was automatically updated to reflect the committed changes. Closed by commit rL315986: [CodeGen] Pass TBAA info along with lvalue base info everywhere (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38945?vs=119129&id=119278#toc Repository: rL LLVM https://reviews.llvm.org/D38945 Files: cfe/trunk/lib/CodeGen/CGAtomic.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp cfe/trunk/lib/CodeGen/CGValue.h cfe/trunk/lib/CodeGen/CodeGenFunction.h Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -3213,9 +3213,8 @@ LValue LHS = EmitLValue(E->getBase()); auto *Idx = EmitIdxAfterBase(/*Promote*/false); assert(LHS.isSimple() && "Can only subscript lvalue vectors here!"); -return LValue::MakeVectorElt(LHS.getAddress(), Idx, - E->getBase()->getType(), - LHS.getBaseInfo()); +return LValue::MakeVectorElt(LHS.getAddress(), Idx, E->getBase()->getType(), + LHS.getBaseInfo(), TBAAAccessInfo()); } // All the other cases basically behave like simple offsetting. @@ -3567,7 +3566,7 @@ llvm::Constant *CV = llvm::ConstantDataVector::get(getLLVMContext(), Indices); return LValue::MakeExtVectorElt(Base.getAddress(), CV, type, -Base.getBaseInfo()); +Base.getBaseInfo(), TBAAAccessInfo()); } assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!"); @@ -3578,7 +3577,7 @@ CElts.push_back(BaseElts->getAggregateElement(Indices[i])); llvm::Constant *CV = llvm::ConstantVector::get(CElts); return LValue::MakeExtVectorElt(Base.getExtVectorAddress(), CV, type, - Base.getBaseInfo()); + Base.getBaseInfo(), TBAAAccessInfo()); } LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { @@ -3708,7 +3707,8 @@ QualType fieldType = field->getType().withCVRQualifiers(base.getVRQualifiers()); -return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo); +return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo, +TBAAAccessInfo()); } Address addr = base.getAddress(); Index: cfe/trunk/lib/CodeGen/CGAtomic.cpp === --- cfe/trunk/lib/CodeGen/CGAtomic.cpp +++ cfe/trunk/lib/CodeGen/CGAtomic.cpp @@ -96,9 +96,8 @@ BFI.StorageSize = AtomicSizeInBits; BFI.StorageOffset += OffsetInChars; LVal = LValue::MakeBitfield(Address(Addr, lvalue.getAlignment()), -BFI, lvalue.getType(), -lvalue.getBaseInfo()); -LVal.setTBAAInfo(lvalue.getTBAAInfo()); +BFI, lvalue.getType(), lvalue.getBaseInfo(), +lvalue.getTBAAInfo()); AtomicTy = C.getIntTypeForBitwidth(AtomicSizeInBits, OrigBFI.IsSigned); if (AtomicTy.isNull()) { llvm::APInt Size( @@ -1346,15 +1345,15 @@ if (LVal.isBitField()) return CGF.EmitLoadOfBitfieldLValue( LValue::MakeBitfield(addr, LVal.getBitFieldInfo(), LVal.getType(), - LVal.getBaseInfo()), loc); + LVal.getBaseInfo(), TBAAAccessInfo()), loc); if (LVal.isVectorElt()) return CGF.EmitLoadOfLValue( LValue::MakeVectorElt(addr, LVal.getVectorIdx(), LVal.getType(), - LVal.getBaseInfo()), loc); + LVal.getBaseInfo(), TBAAAccessInfo()), loc); assert(LVal.isExtVectorElt()); return CGF.EmitLoadOfExtVectorElementLValue(LValue::MakeExtVectorElt( addr, LVal.getExtVectorElts(), LVal.getType(), - LVal.getBaseInfo())); + LVal.getBaseInfo(), TBAAAccessInfo())); } RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, @@ -1670,29 +1669,30 @@ UpdateLVal = LValue::MakeBitfield(Ptr, AtomicLVal.getBitFieldInfo(), AtomicLVal.getType(), - AtomicLVal.getBaseInfo()); + AtomicLVal.getBaseInfo(), + AtomicLVal.getTBAAInfo()); DesiredLVal = LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(), - AtomicLVal.getType(), - AtomicLVal.getBaseInfo()); + AtomicLVal.getType(), AtomicLVal.getBaseInfo(), + AtomicLVal.getTBAAInfo()); } else if (AtomicLVal.isVectorElt()) { UpdateLVal = LValue::MakeVectorElt(Ptr, AtomicLVal.getVectorIdx(),
[PATCH] D38947: [CodeGen] Refine generation of TBAA info for bit-field lvalues
This revision was automatically updated to reflect the committed changes. Closed by commit rL315989: [CodeGen] Refine generation of TBAA info for bit-field lvalues (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D38947?vs=119257&id=119288#toc Repository: rL LLVM https://reviews.llvm.org/D38947 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -3679,15 +3679,6 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field) { LValueBaseInfo BaseInfo = base.getBaseInfo(); - AlignmentSource fieldAlignSource = -getFieldAlignmentSource(BaseInfo.getAlignmentSource()); - LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias()); - - QualType type = field->getType(); - const RecordDecl *rec = field->getParent(); - if (rec->isUnion() || rec->hasAttr() || type->isVectorType()) -FieldBaseInfo.setMayAlias(true); - bool mayAlias = FieldBaseInfo.getMayAlias(); if (field->isBitField()) { const CGRecordLayout &RL = @@ -3707,20 +3698,55 @@ QualType fieldType = field->getType().withCVRQualifiers(base.getVRQualifiers()); +// TODO: Support TBAA for bit fields. +LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource(), false); return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo, TBAAAccessInfo()); } + // Fields of may-alias structures are may-alias themselves. + // FIXME: this should get propagated down through anonymous structs + // and unions. + QualType FieldType = field->getType(); + const RecordDecl *rec = field->getParent(); + AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource(); + LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource), false); + TBAAAccessInfo FieldTBAAInfo; + if (BaseInfo.getMayAlias() || rec->hasAttr() || + FieldType->isVectorType()) { +FieldBaseInfo.setMayAlias(true); +FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + } else if (rec->isUnion()) { +// TODO: Support TBAA for unions. +FieldBaseInfo.setMayAlias(true); +FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + } else { +// If no base type been assigned for the base access, then try to generate +// one for this base lvalue. +FieldTBAAInfo = base.getTBAAInfo(); +if (!FieldTBAAInfo.BaseType) { +FieldTBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(base.getType()); +assert(!FieldTBAAInfo.Offset && + "Nonzero offset for an access with no base type!"); +} + +// Adjust offset to be relative to the base type. +const ASTRecordLayout &Layout = +getContext().getASTRecordLayout(field->getParent()); +unsigned CharWidth = getContext().getCharWidth(); +if (FieldTBAAInfo.BaseType) + FieldTBAAInfo.Offset += + Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; + +// Update the final access type. +FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType); + } + Address addr = base.getAddress(); unsigned cvr = base.getVRQualifiers(); - bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; if (rec->isUnion()) { // For unions, there is no pointer adjustment. -assert(!type->isReferenceType() && "union has reference member"); -// TODO: handle path-aware TBAA for union. -TBAAPath = false; - -const auto FieldType = field->getType(); +assert(!FieldType->isReferenceType() && "union has reference member"); if (CGM.getCodeGenOpts().StrictVTablePointers && hasAnyVptr(FieldType, getContext())) // Because unions can easily skip invariant.barriers, we need to add @@ -3732,24 +3758,17 @@ addr = emitAddrOfFieldStorage(*this, addr, field); // If this is a reference field, load the reference right now. -if (const ReferenceType *refType = type->getAs()) { +if (const ReferenceType *refType = FieldType->getAs()) { llvm::LoadInst *load = Builder.CreateLoad(addr, "ref"); if (cvr & Qualifiers::Volatile) load->setVolatile(true); - // Loading the reference will disable path-aware TBAA. - TBAAPath = false; - TBAAAccessInfo TBAAInfo = mayAlias ? CGM.getTBAAMayAliasAccessInfo() : - CGM.getTBAAAccessInfo(type); - CGM.DecorateInstructionWithTBAA(load, TBAAInfo); - - mayAlias = false; - type = refType->getPointeeType(); - - CharUnits alignment = -getNaturalTypeAlignment(type, &FieldBaseInfo, /* TBAAInfo= */ nullptr, -/* forPointeeType= */ true); - FieldBaseInfo.setMayAlias(false); - addr = Address(load, alignment); + CGM.DecorateInstructionWithTBAA(load, FieldTBAAInfo); + + FieldType = refType->getPointeeType(); + Ch
[PATCH] D39008: [CodeGen] Propagate may-alias'ness of lvalues with TBAA info
kosarev created this revision. kosarev added a project: clang. This patch fixes various places in clang to propagate may-alias TBAA access descriptors during construction of lvalues, thus eliminating the need for the LValueBaseInfo::MayAlias flag. This is part of https://reviews.llvm.org/D38126 reworked to be a separate patch to simplify review. Repository: rL LLVM https://reviews.llvm.org/D39008 Files: lib/CodeGen/CGExpr.cpp lib/CodeGen/CGObjCRuntime.cpp lib/CodeGen/CGOpenMPRuntime.cpp lib/CodeGen/CGValue.h lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/CodeGenTBAA.cpp lib/CodeGen/CodeGenTBAA.h Index: lib/CodeGen/CodeGenTBAA.h === --- lib/CodeGen/CodeGenTBAA.h +++ lib/CodeGen/CodeGenTBAA.h @@ -53,6 +53,14 @@ Offset == Other.Offset; } + bool operator!=(const TBAAAccessInfo &Other) const { +return !(*this == Other); + } + + explicit operator bool() const { +return *this != TBAAAccessInfo(); + } + /// BaseType - The base/leading access type. May be null if this access /// descriptor represents an access that is not considered to be an access /// to an aggregate or union member. @@ -143,10 +151,18 @@ /// accesses. TBAAAccessInfo getMayAliasAccessInfo(); + /// isMayAliasAccessInfo - Test for the may-alias TBAA access descriptor. + bool isMayAliasAccessInfo(TBAAAccessInfo Info); + /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of /// type casts. TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, TBAAAccessInfo TargetInfo); + + /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the + /// purpose of conditional operator. + TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB); }; } // end namespace CodeGen @@ -177,9 +193,7 @@ static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, const clang::CodeGen::TBAAAccessInfo &RHS) { -return LHS.BaseType == RHS.BaseType && - LHS.AccessType == RHS.AccessType && - LHS.Offset == RHS.Offset; +return LHS == RHS; } }; Index: lib/CodeGen/CodeGenTBAA.cpp === --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -88,6 +88,25 @@ return false; } +/// Check if the given type is a valid base type to be used in access tags. +static bool isValidBaseType(QualType QTy) { + if (QTy->isReferenceType()) +return false; + if (const RecordType *TTy = QTy->getAs()) { +const RecordDecl *RD = TTy->getDecl()->getDefinition(); +// Incomplete types are not valid base access types. +if (!RD) + return false; +if (RD->hasFlexibleArrayMember()) + return false; +// RD can be struct, union, class, interface or enum. +// For now, we only handle struct and class. +if (RD->isStruct() || RD->isClass()) + return true; + } + return false; +} + llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) { // At -O0 or relaxed aliasing, TBAA is not emitted for regular types. if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) @@ -98,8 +117,16 @@ if (TypeHasMayAlias(QTy)) return getChar(); - const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); + // We need this function to not fall back to returning the "omnipotent char" + // type node for aggregate and union types. Otherwise, any dereference of an + // aggregate will result into the may-alias access descriptor, meaning all + // subsequent accesses to direct and indirect members of that aggregate will + // be considered may-alias too. + // TODO: Combine getTypeInfo() and getBaseTypeInfo() into a single function. + if (isValidBaseType(QTy)) +return getBaseTypeInfo(QTy); + const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); if (llvm::MDNode *N = MetadataCache[Ty]) return N; @@ -232,20 +259,6 @@ return StructMetadataCache[Ty] = nullptr; } -/// Check if the given type is a valid base type to be used in access tags. -static bool isValidBaseType(QualType QTy) { - if (const RecordType *TTy = QTy->getAs()) { -const RecordDecl *RD = TTy->getDecl()->getDefinition(); -if (RD->hasFlexibleArrayMember()) - return false; -// RD can be struct, union, class, interface or enum. -// For now, we only handle struct and class. -if (RD->isStruct() || RD->isClass()) - return true; - } - return false; -} - llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) { if (!isValidBaseType(QTy)) return nullptr; @@ -317,3 +330,26 @@ return MayAliasInfo; return TargetInfo; } + +bool CodeGenTBAA::isMayAliasAccessInfo(TBAAAccessInfo Info) { +
[PATCH] D38126: Make TBAA information to be part of LValueBaseInfo
kosarev updated this revision to Diff 119373. kosarev edited the summary of this revision. kosarev added a comment. Rebased on top of https://reviews.llvm.org/D39008 and ready for review. https://reviews.llvm.org/D38126 Files: CodeGen/CGAtomic.cpp CodeGen/CGClass.cpp CodeGen/CGExpr.cpp CodeGen/CGObjCRuntime.cpp CodeGen/CGOpenMPRuntime.cpp CodeGen/CGValue.h CodeGen/CodeGenFunction.cpp CodeGen/CodeGenFunction.h Index: CodeGen/CodeGenFunction.h === --- CodeGen/CodeGenFunction.h +++ CodeGen/CodeGenFunction.h @@ -1919,45 +1919,39 @@ LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source = AlignmentSource::Type) { -return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), -CGM.getTBAAAccessInfo(T)); +return LValue::MakeAddr(Addr, T, getContext(), +LValueBaseInfo(Source, CGM.getTBAAAccessInfo(T))); } - LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo, -TBAAAccessInfo TBAAInfo) { -return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo); + LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo) { +return LValue::MakeAddr(Addr, T, getContext(), BaseInfo); } LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source = AlignmentSource::Type) { return LValue::MakeAddr(Address(V, Alignment), T, getContext(), -LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); +LValueBaseInfo(Source, CGM.getTBAAAccessInfo(T))); } LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, -LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { -return LValue::MakeAddr(Address(V, Alignment), T, getContext(), -BaseInfo, TBAAInfo); +LValueBaseInfo BaseInfo) { +return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo); } LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T); CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo = nullptr, -TBAAAccessInfo *TBAAInfo = nullptr, bool forPointeeType = false); CharUnits getNaturalPointeeTypeAlignment(QualType T, - LValueBaseInfo *BaseInfo = nullptr, - TBAAAccessInfo *TBAAInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr); Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, - LValueBaseInfo *BaseInfo = nullptr, - TBAAAccessInfo *TBAAInfo = nullptr); + LValueBaseInfo *BaseInfo = nullptr); LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, -LValueBaseInfo *BaseInfo = nullptr, -TBAAAccessInfo *TBAAInfo = nullptr); +LValueBaseInfo *BaseInfo = nullptr); LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy); /// CreateTempAlloca - This creates an alloca and inserts it into the entry @@ -3083,13 +3077,13 @@ SourceLocation Loc, AlignmentSource Source = AlignmentSource::Type, bool isNontemporal = false) { -return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source), -CGM.getTBAAAccessInfo(Ty), isNontemporal); +return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, +LValueBaseInfo(Source, CGM.getTBAAAccessInfo(Ty)), +isNontemporal); } llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, LValueBaseInfo BaseInfo, -TBAAAccessInfo TBAAInfo, bool isNontemporal = false); /// EmitLoadOfScalar - Load a scalar value from an address, taking @@ -3105,13 +3099,13 @@ bool Volatile, QualType Ty, AlignmentSource Source = AlignmentSource::Type, bool isInit = false, bool isNontemporal = false) { -EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source), - CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal); +EmitStoreOfScalar(Value, Addr, Volatile, Ty, + LValueBase
[PATCH] D39083: [CodeGen] Fix generation of TBAA info for array-to-pointer conversions
kosarev created this revision. kosarev added a project: clang. Resolves: Fatal error: Offset not zero at the point of scalar access. http://llvm.org/PR34992 Repository: rL LLVM https://reviews.llvm.org/D39083 Files: lib/CodeGen/CGExpr.cpp test/CodeGen/tbaa-array.cpp Index: test/CodeGen/tbaa-array.cpp === --- test/CodeGen/tbaa-array.cpp +++ test/CodeGen/tbaa-array.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for accesses to array +// elements. + +struct A { int i; }; +struct B { A a[1]; }; + +int foo(B *b) { +// CHECK-LABEL: _Z3fooP1B +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] + return b->a->i; +} + +// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} +// CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3072,8 +3072,6 @@ // Expressions of array type can't be bitfields or vector elements. LValue LV = EmitLValue(E); Address Addr = LV.getAddress(); - if (BaseInfo) *BaseInfo = LV.getBaseInfo(); - if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo(); // If the array type was an incomplete type, we need to make sure // the decay ends up being the right type. @@ -3088,7 +3086,15 @@ Addr = Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(), "arraydecay"); } + // The result of this decay conversion points to an array element within the + // base lvalue. However, since TBAA currently does not support representing + // accesses to elements of member arrays, we conservatively represent accesses + // to the pointee object as if it had no any base lvalue specified. + // TODO: Support TBAA for member arrays. QualType EltType = E->getType()->castAsArrayTypeUnsafe()->getElementType(); + if (BaseInfo) *BaseInfo = LV.getBaseInfo(); + if (TBAAInfo) *TBAAInfo = CGM.getTBAAAccessInfo(EltType); + return Builder.CreateElementBitCast(Addr, ConvertTypeForMem(EltType)); } Index: test/CodeGen/tbaa-array.cpp === --- test/CodeGen/tbaa-array.cpp +++ test/CodeGen/tbaa-array.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for accesses to array +// elements. + +struct A { int i; }; +struct B { A a[1]; }; + +int foo(B *b) { +// CHECK-LABEL: _Z3fooP1B +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] + return b->a->i; +} + +// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} +// CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3072,8 +3072,6 @@ // Expressions of array type can't be bitfields or vector elements. LValue LV = EmitLValue(E); Address Addr = LV.getAddress(); - if (BaseInfo) *BaseInfo = LV.getBaseInfo(); - if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo(); // If the array type was an incomplete type, we need to make sure // the decay ends up being the right type. @@ -3088,7 +3086,15 @@ Addr = Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(), "arraydecay"); } + // The result of this decay conversion points to an array element within the + // base lvalue. However, since TBAA currently does not support representing + // accesses to elements of member arrays, we conservatively represent accesses + // to the pointee object as if it had no any base lvalue specified. + // TODO: Support TBAA for member arrays. QualType EltType = E->getType()->castAsArrayTypeUnsafe()->getElementType(); + if (BaseInfo) *BaseInfo = LV.getBaseInfo(); + if (TBAAInfo) *TBAAInfo = CGM.getTBAAAccessInfo(EltType); + return Builder.CreateElementBitCast(Addr, ConvertTypeForMem(EltType)); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39083: [CodeGen] Fix generation of TBAA info for array-to-pointer conversions
This revision was automatically updated to reflect the committed changes. Closed by commit rL316211: [CodeGen] Fix generation of TBAA info for array-to-pointer conversions (authored by kosarev). Changed prior to commit: https://reviews.llvm.org/D39083?vs=119552&id=119646#toc Repository: rL LLVM https://reviews.llvm.org/D39083 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/test/CodeGen/tbaa-array.cpp Index: cfe/trunk/test/CodeGen/tbaa-array.cpp === --- cfe/trunk/test/CodeGen/tbaa-array.cpp +++ cfe/trunk/test/CodeGen/tbaa-array.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for accesses to array +// elements. + +struct A { int i; }; +struct B { A a[1]; }; + +int foo(B *b) { +// CHECK-LABEL: _Z3fooP1B +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] + return b->a->i; +} + +// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} +// CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -3072,8 +3072,6 @@ // Expressions of array type can't be bitfields or vector elements. LValue LV = EmitLValue(E); Address Addr = LV.getAddress(); - if (BaseInfo) *BaseInfo = LV.getBaseInfo(); - if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo(); // If the array type was an incomplete type, we need to make sure // the decay ends up being the right type. @@ -3088,7 +3086,15 @@ Addr = Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(), "arraydecay"); } + // The result of this decay conversion points to an array element within the + // base lvalue. However, since TBAA currently does not support representing + // accesses to elements of member arrays, we conservatively represent accesses + // to the pointee object as if it had no any base lvalue specified. + // TODO: Support TBAA for member arrays. QualType EltType = E->getType()->castAsArrayTypeUnsafe()->getElementType(); + if (BaseInfo) *BaseInfo = LV.getBaseInfo(); + if (TBAAInfo) *TBAAInfo = CGM.getTBAAAccessInfo(EltType); + return Builder.CreateElementBitCast(Addr, ConvertTypeForMem(EltType)); } Index: cfe/trunk/test/CodeGen/tbaa-array.cpp === --- cfe/trunk/test/CodeGen/tbaa-array.cpp +++ cfe/trunk/test/CodeGen/tbaa-array.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for accesses to array +// elements. + +struct A { int i; }; +struct B { A a[1]; }; + +int foo(B *b) { +// CHECK-LABEL: _Z3fooP1B +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] + return b->a->i; +} + +// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} +// CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -3072,8 +3072,6 @@ // Expressions of array type can't be bitfields or vector elements. LValue LV = EmitLValue(E); Address Addr = LV.getAddress(); - if (BaseInfo) *BaseInfo = LV.getBaseInfo(); - if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo(); // If the array type was an incomplete type, we need to make sure // the decay ends up being the right type. @@ -3088,7 +3086,15 @@ Addr = Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(), "arraydecay"); } + // The result of this decay conversion points to an array element within the + // base lvalue. However, since TBAA currently does not support representing + // accesses to elements of member arrays, we conservatively represent accesses + // to the pointee object as if it had no any base lvalue specified. + // TODO: Support TBAA for member arrays. QualType EltType = E->getType()->castAsArrayTypeUnsafe()->getElementType(); + if (BaseInfo) *BaseInfo = LV.getBaseInfo(); + if (TBAAInfo) *TBAAInfo = CGM.getTBAAAccessInfo(EltType); + return Builder.CreateElementBitCast(Addr, ConvertTypeForMem(EltType)); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39083: [CodeGen] Fix generation of TBAA info for array-to-pointer conversions
kosarev added a comment. Thanks Hal. Repository: rL LLVM https://reviews.llvm.org/D39083 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39138: [CodeGen] Generate TBAA info for 'this' pointers
kosarev created this revision. kosarev added a project: clang. Repository: rL LLVM https://reviews.llvm.org/D39138 Files: lib/CodeGen/CGCXXABI.cpp test/CodeGen/tbaa-this.cpp Index: test/CodeGen/tbaa-this.cpp === --- test/CodeGen/tbaa-this.cpp +++ test/CodeGen/tbaa-this.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for 'this' pointers. + +struct C { + C *self(); +}; + +C *C::self() { +// CHECK-LABEL: _ZN1C4selfEv +// CHECK: load {{.*}}, !tbaa [[TAG_pointer:!.*]] + return this; +} + +C* foo(C *p) { + return p->self(); +} + +// CHECK-DAG: [[TAG_pointer]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0} +// CHECK-DAG: [[TYPE_pointer]] = !{!"any pointer", !{{.*}}, i64 0} Index: lib/CodeGen/CGCXXABI.cpp === --- lib/CodeGen/CGCXXABI.cpp +++ lib/CodeGen/CGCXXABI.cpp @@ -152,9 +152,12 @@ void CGCXXABI::EmitThisParam(CodeGenFunction &CGF) { /// Initialize the 'this' slot. assert(getThisDecl(CGF) && "no 'this' variable for function"); - CGF.CXXABIThisValue -= CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)), - "this"); + ImplicitParamDecl *ThisPtrDecl = getThisDecl(CGF); + auto *Load = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(ThisPtrDecl), + "this"); + QualType ThisPtrType = ThisPtrDecl->getType(); + CGM.DecorateInstructionWithTBAA(Load, CGM.getTBAAAccessInfo(ThisPtrType)); + CGF.CXXABIThisValue = Load; } void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, Index: test/CodeGen/tbaa-this.cpp === --- test/CodeGen/tbaa-this.cpp +++ test/CodeGen/tbaa-this.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for 'this' pointers. + +struct C { + C *self(); +}; + +C *C::self() { +// CHECK-LABEL: _ZN1C4selfEv +// CHECK: load {{.*}}, !tbaa [[TAG_pointer:!.*]] + return this; +} + +C* foo(C *p) { + return p->self(); +} + +// CHECK-DAG: [[TAG_pointer]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0} +// CHECK-DAG: [[TYPE_pointer]] = !{!"any pointer", !{{.*}}, i64 0} Index: lib/CodeGen/CGCXXABI.cpp === --- lib/CodeGen/CGCXXABI.cpp +++ lib/CodeGen/CGCXXABI.cpp @@ -152,9 +152,12 @@ void CGCXXABI::EmitThisParam(CodeGenFunction &CGF) { /// Initialize the 'this' slot. assert(getThisDecl(CGF) && "no 'this' variable for function"); - CGF.CXXABIThisValue -= CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getThisDecl(CGF)), - "this"); + ImplicitParamDecl *ThisPtrDecl = getThisDecl(CGF); + auto *Load = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(ThisPtrDecl), + "this"); + QualType ThisPtrType = ThisPtrDecl->getType(); + CGM.DecorateInstructionWithTBAA(Load, CGM.getTBAAAccessInfo(ThisPtrType)); + CGF.CXXABIThisValue = Load; } void CGCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39177: [CodeGen] Generate TBAA info for reference loads
kosarev created this revision. kosarev added a project: clang. Repository: rL LLVM https://reviews.llvm.org/D39177 Files: lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGOpenMPRuntime.cpp lib/CodeGen/CGStmtOpenMP.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/tbaa-reference.cpp Index: test/CodeGen/tbaa-reference.cpp === --- test/CodeGen/tbaa-reference.cpp +++ test/CodeGen/tbaa-reference.cpp @@ -6,24 +6,32 @@ struct B { S &s; - B(S &s) : s(s) {} - void bar(); + B(S &s); + S &get(); }; -void foo(S &s) { - B b(s); - b.bar(); -} - -// CHECK-LABEL: _Z3fooR1S -// Check initialization of the reference parameter in foo(). -// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer:!.*]] -// +B::B(S &s) : s(s) { // CHECK-LABEL: _ZN1BC2ER1S -// TODO: Check loading of the reference parameter in B::B(S&). -// Check initialization of B::s in B::B(S&). +// Check initialization of the reference parameter. +// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer:!.*]] + +// Check loading of the reference parameter. +// CHECK: load %struct.S*, %struct.S** {{.*}}, !tbaa [[TAG_pointer]] + +// Check initialization of the reference member. // CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer]] -// +} + +S &B::get() { +// CHECK-LABEL: _ZN1B3getEv +// Check that we access the reference as a structure member. +// CHECK: load %struct.S*, %struct.S** {{.*}}, !tbaa [[TAG_B_s:!.*]] + return s; +} + // CHECK-DAG: [[TAG_pointer]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0} +// CHECK-DAG: [[TAG_B_s]] = !{[[TYPE_B:!.*]], [[TYPE_pointer]], i64 0} +// +// CHECK-DAG: [[TYPE_B]] = !{!"_ZTS1B", [[TYPE_pointer]], i64 0} // CHECK-DAG: [[TYPE_pointer]] = !{!"any pointer", [[TYPE_char:!.*]], i64 0} // CHECK-DAG: [[TYPE_char]] = !{!"omnipotent char", {{!.*}}, i64 0} Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -1952,10 +1952,25 @@ LValueBaseInfo *BaseInfo = nullptr, TBAAAccessInfo *TBAAInfo = nullptr); - Address EmitLoadOfReference(Address Ref, const ReferenceType *RefTy, - LValueBaseInfo *BaseInfo = nullptr, - TBAAAccessInfo *TBAAInfo = nullptr); - LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); + Address EmitLoadOfReference(Address ReferenceAddr, + const ReferenceType *ReferenceTy, + LValueBaseInfo ReferenceBaseInfo, + TBAAAccessInfo ReferenceTBAAInfo, + bool IsVolatile = false, + LValueBaseInfo *ReferenceeBaseInfo = nullptr, + TBAAAccessInfo *ReferenceeTBAAInfo = nullptr); + LValue EmitLoadOfReferenceLValue(Address ReferenceAddr, + const ReferenceType *ReferenceTy, + LValueBaseInfo ReferenceBaseInfo, + TBAAAccessInfo ReferenceTBAAInfo); + LValue EmitLoadOfReferenceLValue(Address ReferenceAddr, + const ReferenceType *ReferenceTy, + AlignmentSource Source = + AlignmentSource::Type) { +return EmitLoadOfReferenceLValue( +ReferenceAddr, ReferenceTy, LValueBaseInfo(Source), +CGM.getTBAAAccessInfo(QualType(ReferenceTy, 0))); + } Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, LValueBaseInfo *BaseInfo = nullptr, Index: lib/CodeGen/CGStmtOpenMP.cpp === --- lib/CodeGen/CGStmtOpenMP.cpp +++ lib/CodeGen/CGStmtOpenMP.cpp @@ -412,7 +412,8 @@ if (!VarTy->isReferenceType()) { if (ArgLVal.getType()->isLValueReferenceType()) { ArgAddr = CGF.EmitLoadOfReference( - ArgAddr, ArgLVal.getType()->castAs()); + ArgAddr, ArgLVal.getType()->castAs(), + ArgLVal.getBaseInfo(), ArgLVal.getTBAAInfo()); } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) { assert(ArgLVal.getType()->isPointerType()); ArgAddr = CGF.EmitLoadOfPointer( Index: lib/CodeGen/CGOpenMPRuntime.cpp === --- lib/CodeGen/CGOpenMPRuntime.cpp +++ lib/CodeGen/CGOpenMPRuntime.cpp @@ -1039,7 +1039,9 @@ BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy); else { BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(), - BaseTy->castAs()); +
[PATCH] D39177: [CodeGen] Generate TBAA info for reference loads
kosarev added inline comments. Comment at: test/CodeGen/tbaa-reference.cpp:1 // RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s // Changes for this test look somewhat complicated, so here's a short summary: * We now test loading of reference parameter in B::B() and the constructor itself got an out-of-line definition, so we don't need the foo() function anymore. B::bar() is removed for the same reason. * Added method B::get() to check that we load member references properly. Repository: rL LLVM https://reviews.llvm.org/D39177 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39138: [CodeGen] Generate TBAA info for 'this' pointers
kosarev added a comment. Correct, they are eliminated. However, this change makes things a bit easier as we are pursuing undecorated instructions produced by clang. Once they have their TBAA tags, we don't need to guess if it's something trivial for the optimizer. It shouldn't be a problem to keep this as a local patch, though. So I'm fine with either way. Repository: rL LLVM https://reviews.llvm.org/D39138 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38126: Make TBAA information to be part of LValueBaseInfo
kosarev abandoned this revision. kosarev added a comment. Indeed, if LValueBaseInfo is what we know about the very first value in a sequence, then TBAA info certainly should not be part of it. This also means whatever is specified as a direct base lvalue to the lvalue we are constructing should probably be passed as LValue, as suggested in https://reviews.llvm.org/D39177. Thanks! https://reviews.llvm.org/D38126 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39138: [CodeGen] Generate TBAA info for 'this' pointers
kosarev added a comment. Hmm, according to our research such loads constitute about 18% of all loads under ##-O -Xclang -disable-llvm-passes## on the LLVM code base. I wonder, do you think it would be nice to not generate them at all? I mean, provided that necessary changes do not add too much special-case code. Repository: rL LLVM https://reviews.llvm.org/D39138 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39008: [CodeGen] Propagate may-alias'ness of lvalues with TBAA info
kosarev added a comment. Now that https://reviews.llvm.org/D38796 is comitted and added the tbaa-cast.cpp test case to the mainline, we fail on it with this patch applied. The reason is that we have no special TBAA type node for may-alias accesses, so everything that ever been a potential access to a character type turns into a may-alias access and propagates as such. The test case reads: struct V { unsigned n; }; struct S { char bytes[4]; }; void foo(S *p) { ((V*)p->bytes)->n = 5; } Here, p->bytes decays to a pointer to char, meaning the pointee object is considered may-alias and so it is after the explicit cast. This arises an interesting question: should we introduce a special representation for may-alias accesses to distinct them from character-typed accesses? Or, maybe explicit casts should not derive their may-alias'ness from their source operands? Or, maybe we want to consider all explicit casts of the form ##(T*)E## where ##T*## and ##typeof(E)## point to different types as pointers to may-alias objects? Repository: rL LLVM https://reviews.llvm.org/D39008 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49375: [NEON] Define half-precision vmaxnm intrinsics only when available
kosarev added a comment. Ping. https://reviews.llvm.org/D49375 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49376: [NEON] Define half-precision vrnd intrinsics only when available
kosarev added a comment. Ping. https://reviews.llvm.org/D49376 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49075: [NEON] Define fp16 vld and vst intrinsics conditionally
kosarev added a comment. Ping. https://reviews.llvm.org/D49075 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D48829: [NEON] Fix support for vrndi_f32(), vrndiq_f32() and vrndns_f32() intrinsics
kosarev added a comment. Ping. https://reviews.llvm.org/D48829 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D48829: [NEON] Fix support for vrndi_f32(), vrndiq_f32() and vrndns_f32() intrinsics
This revision was automatically updated to reflect the committed changes. Closed by commit rC337690: [NEON] Fix support for vrndi_f32(), vrndiq_f32() and vrndns_f32() intrinsics (authored by kosarev, committed by ). Repository: rC Clang https://reviews.llvm.org/D48829 Files: include/clang/Basic/arm_neon.td lib/CodeGen/CGBuiltin.cpp test/CodeGen/aarch64-neon-misc.c test/CodeGen/arm-neon-directed-rounding.c test/CodeGen/arm64-vrnd.c Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -988,6 +988,7 @@ def FRINTM_S32 : SInst<"vrndm", "dd", "fQf">; def FRINTX_S32 : SInst<"vrndx", "dd", "fQf">; def FRINTZ_S32 : SInst<"vrnd", "dd", "fQf">; +def FRINTI_S32 : SInst<"vrndi", "dd", "fQf">; } let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__) && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in { @@ -997,7 +998,7 @@ def FRINTM_S64 : SInst<"vrndm", "dd", "dQd">; def FRINTX_S64 : SInst<"vrndx", "dd", "dQd">; def FRINTZ_S64 : SInst<"vrnd", "dd", "dQd">; -def FRINTI_S64 : SInst<"vrndi", "dd", "fdQfQd">; +def FRINTI_S64 : SInst<"vrndi", "dd", "dQd">; } Index: test/CodeGen/arm-neon-directed-rounding.c === --- test/CodeGen/arm-neon-directed-rounding.c +++ test/CodeGen/arm-neon-directed-rounding.c @@ -1,96 +1,128 @@ // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 \ // RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ -// RUN: opt -S -mem2reg | FileCheck %s +// RUN: opt -S -mem2reg | FileCheck -check-prefixes=CHECK,CHECK-A32 %s +// RUN: %clang_cc1 -triple arm64-linux-gnueabihf -target-feature +neon \ +// RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -mem2reg | FileCheck -check-prefixes=CHECK,CHECK-A64 %s #include -// CHECK-LABEL: define <2 x float> @test_vrnda_f32(<2 x float> %a) #0 { -// CHECK: [[VRNDA_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrinta.v2f32(<2 x float> %a) #2 -// CHECK: ret <2 x float> [[VRNDA_V1_I]] +// CHECK-LABEL: define <2 x float> @test_vrnda_f32(<2 x float> %a) +// CHECK-A32: [[VRNDA_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrinta.v2f32(<2 x float> %a) +// CHECK-A64: [[VRNDA_V1_I:%.*]] = call <2 x float> @llvm.round.v2f32(<2 x float> %a) +// CHECK: ret <2 x float> [[VRNDA_V1_I]] float32x2_t test_vrnda_f32(float32x2_t a) { return vrnda_f32(a); } -// CHECK-LABEL: define <4 x float> @test_vrndaq_f32(<4 x float> %a) #0 { -// CHECK: [[VRNDAQ_V1_I:%.*]] = call <4 x float> @llvm.arm.neon.vrinta.v4f32(<4 x float> %a) #2 -// CHECK: ret <4 x float> [[VRNDAQ_V1_I]] +// CHECK-LABEL: define <4 x float> @test_vrndaq_f32(<4 x float> %a) +// CHECK-A32: [[VRNDAQ_V1_I:%.*]] = call <4 x float> @llvm.arm.neon.vrinta.v4f32(<4 x float> %a) +// CHECK-A64: [[VRNDAQ_V1_I:%.*]] = call <4 x float> @llvm.round.v4f32(<4 x float> %a) +// CHECK: ret <4 x float> [[VRNDAQ_V1_I]] float32x4_t test_vrndaq_f32(float32x4_t a) { return vrndaq_f32(a); } -// CHECK-LABEL: define <2 x float> @test_vrndm_f32(<2 x float> %a) #0 { -// CHECK: [[VRNDM_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrintm.v2f32(<2 x float> %a) #2 -// CHECK: ret <2 x float> [[VRNDM_V1_I]] +// CHECK-LABEL: define <2 x float> @test_vrndm_f32(<2 x float> %a) +// CHECK-A32: [[VRNDM_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrintm.v2f32(<2 x float> %a) +// CHECK-A64: [[VRNDM_V1_I:%.*]] = call <2 x float> @llvm.floor.v2f32(<2 x float> %a) +// CHECK: ret <2 x float> [[VRNDM_V1_I]] float32x2_t test_vrndm_f32(float32x2_t a) { return vrndm_f32(a); } -// CHECK-LABEL: define <4 x float> @test_vrndmq_f32(<4 x float> %a) #0 { -// CHECK: [[VRNDMQ_V1_I:%.*]] = call <4 x float> @llvm.arm.neon.vrintm.v4f32(<4 x float> %a) #2 -// CHECK: ret <4 x float> [[VRNDMQ_V1_I]] +// CHECK-LABEL: define <4 x float> @test_vrndmq_f32(<4 x float> %a) +// CHECK-A32: [[VRNDMQ_V1_I:%.*]] = call <4 x float> @llvm.arm.neon.vrintm.v4f32(<4 x float> %a) +// CHECK-A64: [[VRNDMQ_V1_I:%.*]] = call <4 x float> @llvm.floor.v4f32(<4 x float> %a) +// CHECK: ret <4 x float> [[VRNDMQ_V1_I]] float32x4_t test_vrndmq_f32(float32x4_t a) { return vrndmq_f32(a); } -// CHECK-LABEL: define <2 x float> @test_vrndn_f32(<2 x float> %a) #0 { -// CHECK: [[VRNDN_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrintn.v2f32(<2 x float> %a) #2 -// CHECK: ret <2 x float> [[VRNDN_V1_I]] +// CHECK-LABEL: define <2 x float> @test_vrndn_f32(<2 x float> %a) +// CHECK-A32: [[VRNDN_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrintn.v2f32(<2 x float> %a) +// CHECK-A64: [[VRNDN_V1_I:%.*]] = call <2 x float> @llvm.aarch64.neon.frintn.v2f32(<2 x float> %a) +// CHECK: ret <2 x float> [[VRNDN_V1_I]] float32x2_t test_vrndn_f32(float32x2_t a) { return vrndn_f32(a); } -// CHECK-LABEL: define <
[PATCH] D49375: [NEON] Define half-precision vmaxnm intrinsics only when available
kosarev added a comment. Thanks for reviewing! Comment at: include/clang/Basic/arm_neon.td:1466 def VMINH : SInst<"vmin", "ddd", "hQh">; - def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; - def FMINNMH : SInst<"vminnm", "ddd", "hQh">; + let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in { +def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; SjoerdMeijer wrote: > nit: indentation? Do we want some special indentation here? https://reviews.llvm.org/D49375 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49376: [NEON] Define half-precision vrnd intrinsics only when available
kosarev added inline comments. Comment at: include/clang/Basic/arm_neon.td:1419 // Vector rounding - def FRINTZH : SInst<"vrnd", "dd", "hQh">; - def FRINTNH : SInst<"vrndn", "dd", "hQh">; - def FRINTAH : SInst<"vrnda", "dd", "hQh">; - def FRINTPH : SInst<"vrndp", "dd", "hQh">; - def FRINTMH : SInst<"vrndm", "dd", "hQh">; - def FRINTXH : SInst<"vrndx", "dd", "hQh">; + let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in { +def FRINTZH : SInst<"vrnd", "dd", "hQh">; SjoerdMeijer wrote: > nit: is the indentation a bit off here? It's a nested `let ArchGuard`, so I guess we do want the indentation here? https://reviews.llvm.org/D49376 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49376: [NEON] Define half-precision vrnd intrinsics only when available
This revision was automatically updated to reflect the committed changes. Closed by commit rC337699: [NEON] Define half-precision vrnd intrinsics only when available (authored by kosarev, committed by ). Repository: rC Clang https://reviews.llvm.org/D49376 Files: include/clang/Basic/arm_neon.td test/Sema/arm-no-fp16.c Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -1417,12 +1417,14 @@ def VCVTP_U16: SInst<"vcvtp_u16", "ud", "hQh">; // Vector rounding - def FRINTZH : SInst<"vrnd", "dd", "hQh">; - def FRINTNH : SInst<"vrndn", "dd", "hQh">; - def FRINTAH : SInst<"vrnda", "dd", "hQh">; - def FRINTPH : SInst<"vrndp", "dd", "hQh">; - def FRINTMH : SInst<"vrndm", "dd", "hQh">; - def FRINTXH : SInst<"vrndx", "dd", "hQh">; + let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in { +def FRINTZH : SInst<"vrnd", "dd", "hQh">; +def FRINTNH : SInst<"vrndn", "dd", "hQh">; +def FRINTAH : SInst<"vrnda", "dd", "hQh">; +def FRINTPH : SInst<"vrndp", "dd", "hQh">; +def FRINTMH : SInst<"vrndm", "dd", "hQh">; +def FRINTXH : SInst<"vrndx", "dd", "hQh">; + } // Misc. def VABSH: SInst<"vabs", "dd", "hQh">; Index: test/Sema/arm-no-fp16.c === --- test/Sema/arm-no-fp16.c +++ test/Sema/arm-no-fp16.c @@ -9,3 +9,59 @@ float32x4_t test_vcvt_f32_f16(float16x4_t a) { return vcvt_f32_f16(a); // expected-warning{{implicit declaration of function 'vcvt_f32_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float32x4_t'}} } + +float16x4_t test_vrnda_f16(float16x4_t a) { + return vrnda_f16(a); // expected-warning{{implicit declaration of function 'vrnda_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndaq_f16(float16x8_t a) { + return vrndaq_f16(a); // expected-warning{{implicit declaration of function 'vrndaq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrnd_f16(float16x4_t a) { + return vrnd_f16(a); // expected-warning{{implicit declaration of function 'vrnd_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndq_f16(float16x8_t a) { + return vrndq_f16(a); // expected-warning{{implicit declaration of function 'vrndq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndi_f16(float16x4_t a) { + return vrndi_f16(a); // expected-warning{{implicit declaration of function 'vrndi_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndiq_f16(float16x8_t a) { + return vrndiq_f16(a); // expected-warning{{implicit declaration of function 'vrndiq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndm_f16(float16x4_t a) { + return vrndm_f16(a); // expected-warning{{implicit declaration of function 'vrndm_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndmq_f16(float16x8_t a) { + return vrndmq_f16(a); // expected-warning{{implicit declaration of function 'vrndmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndn_f16(float16x4_t a) { + return vrndn_f16(a); // expected-warning{{implicit declaration of function 'vrndn_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndnq_f16(float16x8_t a) { + return vrndnq_f16(a); // expected-warning{{implicit declaration of function 'vrndnq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndp_f16(float16x4_t a) { + return vrndp_f16(a); // expected-warning{{implicit declaration of function 'vrndp_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndpq_f16(float16x8_t a) { + return vrndpq_f16(a); // expected-warning{{implicit declaration of function 'vrndpq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndx_f16(float16x4_t a) { + return vrndx_f16(a); // expected-warning{{implicit declaration of function 'vrndx_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndxq_f16(fl
[PATCH] D49375: [NEON] Define half-precision vmaxnm intrinsics only when available
This revision was automatically updated to reflect the committed changes. Closed by commit rC337704: [NEON] Define half-precision vmaxnm intrinsics only when available (authored by kosarev, committed by ). Changed prior to commit: https://reviews.llvm.org/D49375?vs=155675&id=156802#toc Repository: rC Clang https://reviews.llvm.org/D49375 Files: include/clang/Basic/arm_neon.td test/Sema/arm-no-fp16.c Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -1466,8 +1466,10 @@ // Max/Min def VMAXH : SInst<"vmax", "ddd", "hQh">; def VMINH : SInst<"vmin", "ddd", "hQh">; - def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; - def FMINNMH : SInst<"vminnm", "ddd", "hQh">; + let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in { +def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; +def FMINNMH : SInst<"vminnm", "ddd", "hQh">; + } // Multiplication/Division def VMULH : SOpInst<"vmul", "ddd", "hQh", OP_MUL>; Index: test/Sema/arm-no-fp16.c === --- test/Sema/arm-no-fp16.c +++ test/Sema/arm-no-fp16.c @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple thumbv7-none-eabi %s -target-feature +neon -target-feature -fp16 -fsyntax-only -verify +// RUN: %clang_cc1 -triple thumbv7-none-eabi %s -target-feature +neon \ +// RUN: -fallow-half-arguments-and-returns -target-feature -fp16 \ +// RUN: -fsyntax-only -verify #include @@ -65,3 +67,19 @@ float16x8_t test_vrndxq_f16(float16x8_t a) { return vrndxq_f16(a); // expected-warning{{implicit declaration of function 'vrndxq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} } + +float16x4_t test_vmaxnm_f16(float16x4_t a, float16x4_t b) { + return vmaxnm_f16(a, b); // expected-warning{{implicit declaration of function 'vmaxnm_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vmaxnmq_f16(float16x8_t a, float16x8_t b) { + return vmaxnmq_f16(a, b); // expected-warning{{implicit declaration of function 'vmaxnmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vminnm_f16(float16x4_t a, float16x4_t b) { + return vminnm_f16(a, b); // expected-warning{{implicit declaration of function 'vminnm_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vminnmq_f16(float16x8_t a, float16x8_t b) { + return vminnmq_f16(a, b); // expected-warning{{implicit declaration of function 'vminnmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -1466,8 +1466,10 @@ // Max/Min def VMAXH : SInst<"vmax", "ddd", "hQh">; def VMINH : SInst<"vmin", "ddd", "hQh">; - def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; - def FMINNMH : SInst<"vminnm", "ddd", "hQh">; + let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in { +def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; +def FMINNMH : SInst<"vminnm", "ddd", "hQh">; + } // Multiplication/Division def VMULH : SOpInst<"vmul", "ddd", "hQh", OP_MUL>; Index: test/Sema/arm-no-fp16.c === --- test/Sema/arm-no-fp16.c +++ test/Sema/arm-no-fp16.c @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple thumbv7-none-eabi %s -target-feature +neon -target-feature -fp16 -fsyntax-only -verify +// RUN: %clang_cc1 -triple thumbv7-none-eabi %s -target-feature +neon \ +// RUN: -fallow-half-arguments-and-returns -target-feature -fp16 \ +// RUN: -fsyntax-only -verify #include @@ -65,3 +67,19 @@ float16x8_t test_vrndxq_f16(float16x8_t a) { return vrndxq_f16(a); // expected-warning{{implicit declaration of function 'vrndxq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} } + +float16x4_t test_vmaxnm_f16(float16x4_t a, float16x4_t b) { + return vmaxnm_f16(a, b); // expected-warning{{implicit declaration of function 'vmaxnm_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vmaxnmq_f16(float16x8_t a, float16x8_t b) { + return vmaxnmq_f16(a, b); // expected-warning{{implicit declaration of function 'vmaxnmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float
[PATCH] D49075: [NEON] Define fp16 vld and vst intrinsics conditionally
kosarev updated this revision to Diff 157960. kosarev added a comment. Test that the affected intrinsics are not defined in no-fp16 mode. https://reviews.llvm.org/D49075 Files: include/clang/Basic/arm_neon.td test/CodeGen/arm-neon-vld.c test/CodeGen/arm-neon-vst.c test/Sema/arm-no-fp16.c Index: test/Sema/arm-no-fp16.c === --- test/Sema/arm-no-fp16.c +++ test/Sema/arm-no-fp16.c @@ -83,3 +83,213 @@ float16x8_t test_vminnmq_f16(float16x8_t a, float16x8_t b) { return vminnmq_f16(a, b); // expected-warning{{implicit declaration of function 'vminnmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} } + +float16x4_t test_vld1_f16(const float16_t *a) { + return vld1_f16(a); // expected-warning{{implicit declaration of function 'vld1_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vld1q_f16(const float16_t *a) { + return vld1q_f16(a); // expected-warning{{implicit declaration of function 'vld1q_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vld1_dup_f16(const float16_t *a) { + return vld1_dup_f16(a); // expected-warning{{implicit declaration of function 'vld1_dup_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vld1q_dup_f16(const float16_t *a) { + return vld1q_dup_f16(a); // expected-warning{{implicit declaration of function 'vld1q_dup_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vld1_lane_f16(const float16_t *a, float16x4_t b) { + return vld1_lane_f16(a, b, 3); // expected-warning{{implicit declaration of function 'vld1_lane_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vld1q_lane_f16(const float16_t *a, float16x8_t b) { + return vld1q_lane_f16(a, b, 7); // expected-warning{{implicit declaration of function 'vld1q_lane_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4x2_t test_vld1_f16_x2(const float16_t *a) { + return vld1_f16_x2(a); // expected-warning{{implicit declaration of function 'vld1_f16_x2'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4x2_t'}} +} + +float16x8x2_t test_vld1q_f16_x2(const float16_t *a) { + return vld1q_f16_x2(a); // expected-warning{{implicit declaration of function 'vld1q_f16_x2'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8x2_t'}} +} + +float16x4x3_t test_vld1_f16_x3(const float16_t *a) { + return vld1_f16_x3(a); // expected-warning{{implicit declaration of function 'vld1_f16_x3'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4x3_t'}} +} + +float16x8x3_t test_vld1q_f16_x3(const float16_t *a) { + return vld1q_f16_x3(a); // expected-warning{{implicit declaration of function 'vld1q_f16_x3'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8x3_t'}} +} + +float16x4x4_t test_vld1_f16_x4(const float16_t *a) { + return vld1_f16_x4(a); // expected-warning{{implicit declaration of function 'vld1_f16_x4'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4x4_t'}} +} + +float16x8x4_t test_vld1q_f16_x4(const float16_t *a) { + return vld1q_f16_x4(a); // expected-warning{{implicit declaration of function 'vld1q_f16_x4'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8x4_t'}} +} + +float16x4x2_t test_vld2_f16(const float16_t *a) { + return vld2_f16(a); // expected-warning{{implicit declaration of function 'vld2_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4x2_t'}} +} + +float16x8x2_t test_vld2q_f16(const float16_t *a) { + return vld2q_f16(a); // expected-warning{{implicit declaration of function 'vld2q_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8x2_t'}} +} + +float16x4x2_t test_vld2_lane_f16(const float16_t *a, float16x4x2_t b) { + return vld2_lane_f16(a, b, 3); // expected-warning{{implicit declaration of function 'vld2_lane_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4x2_t'}} +} + +float16x8x2_t test_vld2q_lane_f16(const float16_t *a, float16x8x2_t b) { + return vld2q_lane_f16(a, b, 7); // expected-warning{{implicit declaration of function 'vld2q_lane_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8x2_t'}} +} + +float16x4x2_t test_vld2_dup_f16(const float16_t *src) { + return vld2_dup_f16(src); // expected-warning{{implicit declaration of function 'vld2_dup_f16'}} expecte
[PATCH] D49075: [NEON] Define fp16 vld and vst intrinsics conditionally
kosarev added a comment. Ping. https://reviews.llvm.org/D49075 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42366: [CodeGen] Fix generation of TBAA tags for may-alias accesses
kosarev added a comment. Hal, a friendly ping. Repository: rL LLVM https://reviews.llvm.org/D42366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43181: [CodeGen] Initialize large arrays by copying from a global
kosarev created this revision. kosarev added a reviewer: rjmccall. kosarev added a project: clang. Herald added a subscriber: llvm-commits. Currently, clang compiles explicit initializers for array elements into series of store instructions. For large arrays of built-in types this results in bloated output code and significant amount of time spent on the instruction selection phase. This patch fixes the issue by initializing such arrays with global constants that store the binary image of the initializer. Repository: rL LLVM https://reviews.llvm.org/D43181 Files: lib/CodeGen/CGExprAgg.cpp test/CodeGen/init.c Index: test/CodeGen/init.c === --- test/CodeGen/init.c +++ test/CodeGen/init.c @@ -8,8 +8,9 @@ // CHECK-DAG: %struct.M = type { [2 x %struct.I] } // CHECK-DAG: %struct.I = type { [3 x i32] } -// CHECK: [1 x %struct.M] [%struct.M { [2 x %struct.I] [%struct.I { [3 x i32] [i32 4, i32 4, i32 0] }, %struct.I { [3 x i32] [i32 4, i32 4, i32 5] }] }], -// CHECK: [2 x [3 x i32]] {{[[][[]}}3 x i32] [i32 , i32 , i32 0], [3 x i32] [i32 , i32 , i32 ]], +// CHECK-DAG: [1 x %struct.M] [%struct.M { [2 x %struct.I] [%struct.I { [3 x i32] [i32 4, i32 4, i32 0] }, %struct.I { [3 x i32] [i32 4, i32 4, i32 5] }] }], +// CHECK-DAG: [2 x [3 x i32]] {{[[][[]}}3 x i32] [i32 , i32 , i32 0], [3 x i32] [i32 , i32 , i32 ]], +// CHECK-DAG: [[INIT14:.*]] = private global [16 x i32] [i32 0, i32 0, i32 0, i32 0, i32 0, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 0, i32 0, i32 0, i32 0], align 4 void f1() { // Scalars in braces. @@ -33,8 +34,8 @@ } // Constants -// CHECK: @g3 = constant i32 10 -// CHECK: @f4.g4 = internal constant i32 12 +// CHECK-DAG: @g3 = constant i32 10 +// CHECK-DAG: @f4.g4 = internal constant i32 12 const int g3 = 10; int f4() { static const int g4 = 12; @@ -61,7 +62,7 @@ -// CHECK: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } +// CHECK-DAG: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } // PR8217 struct a7 { int b; @@ -151,3 +152,15 @@ // CHECK: memcpy{{.*}}getelementptr inbounds ([3 x i8], [3 x i8]* @ bar((char[3]) {""}); } + +// Test that we initialize large member arrays by copying from a global and not +// with a series of stores. +struct S14 { int a[16]; }; + +void test14(struct S14 *s14) { +// CHECK-LABEL: @test14 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 {{.*}}, i8* align 4 {{.*}} [[INIT14]] {{.*}}, i32 64, i1 false) +// CHECK-NOT: store +// CHECK: ret void + *s14 = (struct S14) { { [5 ... 11] = 17 } }; +} Index: lib/CodeGen/CGExprAgg.cpp === --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -14,6 +14,7 @@ #include "CodeGenFunction.h" #include "CGObjCRuntime.h" #include "CodeGenModule.h" +#include "ConstantEmitter.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" @@ -85,7 +86,7 @@ void EmitMoveFromReturnSlot(const Expr *E, RValue Src); void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, - QualType elementType, InitListExpr *E); + QualType ArrayQTy, InitListExpr *E); AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) { if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T)) @@ -394,12 +395,15 @@ /// \brief Emit initialization of an array from an initializer list. void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, - QualType elementType, InitListExpr *E) { + QualType ArrayQTy, InitListExpr *E) { uint64_t NumInitElements = E->getNumInits(); uint64_t NumArrayElements = AType->getNumElements(); assert(NumInitElements <= NumArrayElements); + QualType elementType = + CGF.getContext().getAsArrayType(ArrayQTy)->getElementType(); + // DestPtr is an array*. Construct an elementType* by drilling // down a level. llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); @@ -411,6 +415,28 @@ CharUnits elementAlign = DestPtr.getAlignment().alignmentOfArrayElement(elementSize); + // Consider initializing the array by copying from a global. For this to be + // more efficient than per-element initialization, the number of the elements + // with explicit initializers should be large enough. + if (NumInitElements > 8 && elementType->isBuiltinType()) { +CodeGen::CodeGenModule &CGM = CGF.CGM; +ConstantEmitter Emitter(CGM); +LangAS AS = ArrayQTy.getAddressSpace(); +if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) { + auto GV = new llvm::GlobalVariable( + CGM.getModule(), C->getType(), + CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true), + llvm::GlobalValue::PrivateLinkage, C, "constinit", + /* Inser
[PATCH] D43187: [AST] Refine the condition for element-dependent array fillers
kosarev created this revision. kosarev added a reviewer: rsmith. kosarev added a project: clang. Herald added a subscriber: llvm-commits. This patch fixes clang to not consider braced initializers for aggregate elements of arrays to be potentially dependent on the indices of the initialized elements. Resolves bug 18978: initialize a large static array = clang oom? https://bugs.llvm.org/show_bug.cgi?id=18978 Repository: rL LLVM https://reviews.llvm.org/D43187 Files: lib/AST/ExprConstant.cpp test/SemaCXX/large-array-init.cpp Index: test/SemaCXX/large-array-init.cpp === --- test/SemaCXX/large-array-init.cpp +++ test/SemaCXX/large-array-init.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -S -o %t.ll -mllvm -debug-only=exprconstant %s 2>&1 | \ +// RUN: FileCheck %s + +struct S { int i; }; + +static struct S arr[1] = {{ 0 }}; +// CHECK: The number of elements to initialize: 1. + +struct S *foo() { return arr; } Index: lib/AST/ExprConstant.cpp === --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -48,6 +48,8 @@ #include #include +#define DEBUG_TYPE "exprconstant" + using namespace clang; using llvm::APSInt; using llvm::APFloat; @@ -6780,6 +6782,23 @@ return ArrayExprEvaluator(Info, This, Result).Visit(E); } +// Return true iff the given array filler may depend on element on the element +// index. +static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) { + // For now, just whitelist non-class value-initialization and initialization + // lists comprised of them. + if (isa(FillerExpr)) +return false; + if (const InitListExpr *ILE = dyn_cast(FillerExpr)) { +for (unsigned I = 0, E = ILE->getNumInits(); I != E; ++I) { + if (MaybeElementDependentArrayFiller(ILE->getInit(I))) +return true; +} +return false; + } + return true; +} + bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) { const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(E->getType()); if (!CAT) @@ -6809,10 +6828,13 @@ const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : nullptr; // If the initializer might depend on the array index, run it for each - // array element. For now, just whitelist non-class value-initialization. - if (NumEltsToInit != NumElts && !isa(FillerExpr)) + // array element. + if (NumEltsToInit != NumElts && MaybeElementDependentArrayFiller(FillerExpr)) NumEltsToInit = NumElts; + DEBUG(llvm::dbgs() << "The number of elements to initialize: " << +NumEltsToInit << ".\n"); + Result = APValue(APValue::UninitArray(), NumEltsToInit, NumElts); // If the array was previously zero-initialized, preserve the Index: test/SemaCXX/large-array-init.cpp === --- test/SemaCXX/large-array-init.cpp +++ test/SemaCXX/large-array-init.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -S -o %t.ll -mllvm -debug-only=exprconstant %s 2>&1 | \ +// RUN: FileCheck %s + +struct S { int i; }; + +static struct S arr[1] = {{ 0 }}; +// CHECK: The number of elements to initialize: 1. + +struct S *foo() { return arr; } Index: lib/AST/ExprConstant.cpp === --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -48,6 +48,8 @@ #include #include +#define DEBUG_TYPE "exprconstant" + using namespace clang; using llvm::APSInt; using llvm::APFloat; @@ -6780,6 +6782,23 @@ return ArrayExprEvaluator(Info, This, Result).Visit(E); } +// Return true iff the given array filler may depend on element on the element +// index. +static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) { + // For now, just whitelist non-class value-initialization and initialization + // lists comprised of them. + if (isa(FillerExpr)) +return false; + if (const InitListExpr *ILE = dyn_cast(FillerExpr)) { +for (unsigned I = 0, E = ILE->getNumInits(); I != E; ++I) { + if (MaybeElementDependentArrayFiller(ILE->getInit(I))) +return true; +} +return false; + } + return true; +} + bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) { const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(E->getType()); if (!CAT) @@ -6809,10 +6828,13 @@ const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : nullptr; // If the initializer might depend on the array index, run it for each - // array element. For now, just whitelist non-class value-initialization. - if (NumEltsToInit != NumElts && !isa(FillerExpr)) + // array element. + if (NumEltsToInit != NumElts && MaybeElementDependentArrayFiller(FillerExpr)) NumEltsToInit = NumElts; + DEBUG(llvm::dbgs() << "The number of elements to initialize: " << +NumEltsToInit << ".\n"); + Result = APValue(APValue::UninitArray(
[PATCH] D43181: [CodeGen] Initialize large arrays by copying from a global
kosarev added inline comments. Comment at: lib/CodeGen/CGExprAgg.cpp:421 + // with explicit initializers should be large enough. + if (NumInitElements > 8 && elementType->isBuiltinType()) { +CodeGen::CodeGenModule &CGM = CGF.CGM; rjmccall wrote: > Is there a good reason to use an element-count heuristic instead of a > total-size heuristic here? > > Why only builtin types? That seems to pointlessly rule out nested arrays, > complex types, vectors, C structs, and so on. I think the predicate you > probably want here is isTriviallyCopyableType. > Is there a good reason to use an element-count heuristic instead of a > total-size heuristic here? Yes, the code below generates per-element initialization only for explicitly specified initializers. The rest, if any, is initialized with a filler, so it doesn't affect the size of the resulting code much. Repository: rL LLVM https://reviews.llvm.org/D43181 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43187: [AST] Refine the condition for element-dependent array fillers
kosarev added a comment. John, maybe you can review this or suggest some other reviewers? Thanks. Repository: rL LLVM https://reviews.llvm.org/D43187 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43181: [CodeGen] Initialize large arrays by copying from a global
kosarev updated this revision to Diff 134042. kosarev added a comment. Improved as suggested to cover all trivially-copyable types. https://reviews.llvm.org/D43181 Files: lib/CodeGen/CGExprAgg.cpp test/CodeGen/init.c Index: test/CodeGen/init.c === --- test/CodeGen/init.c +++ test/CodeGen/init.c @@ -8,8 +8,9 @@ // CHECK-DAG: %struct.M = type { [2 x %struct.I] } // CHECK-DAG: %struct.I = type { [3 x i32] } -// CHECK: [1 x %struct.M] [%struct.M { [2 x %struct.I] [%struct.I { [3 x i32] [i32 4, i32 4, i32 0] }, %struct.I { [3 x i32] [i32 4, i32 4, i32 5] }] }], -// CHECK: [2 x [3 x i32]] {{[[][[]}}3 x i32] [i32 , i32 , i32 0], [3 x i32] [i32 , i32 , i32 ]], +// CHECK-DAG: [1 x %struct.M] [%struct.M { [2 x %struct.I] [%struct.I { [3 x i32] [i32 4, i32 4, i32 0] }, %struct.I { [3 x i32] [i32 4, i32 4, i32 5] }] }], +// CHECK-DAG: [2 x [3 x i32]] {{[[][[]}}3 x i32] [i32 , i32 , i32 0], [3 x i32] [i32 , i32 , i32 ]], +// CHECK-DAG: [[INIT14:.*]] = private global [16 x i32] [i32 0, i32 0, i32 0, i32 0, i32 0, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 0, i32 0, i32 0, i32 0], align 4 void f1() { // Scalars in braces. @@ -33,8 +34,8 @@ } // Constants -// CHECK: @g3 = constant i32 10 -// CHECK: @f4.g4 = internal constant i32 12 +// CHECK-DAG: @g3 = constant i32 10 +// CHECK-DAG: @f4.g4 = internal constant i32 12 const int g3 = 10; int f4() { static const int g4 = 12; @@ -61,7 +62,7 @@ -// CHECK: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } +// CHECK-DAG: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } // PR8217 struct a7 { int b; @@ -151,3 +152,15 @@ // CHECK: memcpy{{.*}}getelementptr inbounds ([3 x i8], [3 x i8]* @ bar((char[3]) {""}); } + +// Test that we initialize large member arrays by copying from a global and not +// with a series of stores. +struct S14 { int a[16]; }; + +void test14(struct S14 *s14) { +// CHECK-LABEL: @test14 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 {{.*}}, i8* align 4 {{.*}} [[INIT14]] {{.*}}, i32 64, i1 false) +// CHECK-NOT: store +// CHECK: ret void + *s14 = (struct S14) { { [5 ... 11] = 17 } }; +} Index: lib/CodeGen/CGExprAgg.cpp === --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -14,6 +14,7 @@ #include "CodeGenFunction.h" #include "CGObjCRuntime.h" #include "CodeGenModule.h" +#include "ConstantEmitter.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" @@ -85,7 +86,7 @@ void EmitMoveFromReturnSlot(const Expr *E, RValue Src); void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, - QualType elementType, InitListExpr *E); + QualType ArrayQTy, InitListExpr *E); AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) { if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T)) @@ -394,12 +395,15 @@ /// \brief Emit initialization of an array from an initializer list. void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, - QualType elementType, InitListExpr *E) { + QualType ArrayQTy, InitListExpr *E) { uint64_t NumInitElements = E->getNumInits(); uint64_t NumArrayElements = AType->getNumElements(); assert(NumInitElements <= NumArrayElements); + QualType elementType = + CGF.getContext().getAsArrayType(ArrayQTy)->getElementType(); + // DestPtr is an array*. Construct an elementType* by drilling // down a level. llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); @@ -411,6 +415,29 @@ CharUnits elementAlign = DestPtr.getAlignment().alignmentOfArrayElement(elementSize); + // Consider initializing the array by copying from a global. For this to be + // more efficient than per-element initialization, the number of the elements + // with explicit initializers should be large enough. + if (NumInitElements > 8 && + elementType.isTriviallyCopyableType(CGF.getContext())) { +CodeGen::CodeGenModule &CGM = CGF.CGM; +ConstantEmitter Emitter(CGM); +LangAS AS = ArrayQTy.getAddressSpace(); +if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) { + auto GV = new llvm::GlobalVariable( + CGM.getModule(), C->getType(), + CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true), + llvm::GlobalValue::PrivateLinkage, C, "constinit", + /* InsertBefore= */ nullptr, llvm::GlobalVariable::NotThreadLocal, + CGM.getContext().getTargetAddressSpace(AS)); + Emitter.finalize(GV); + CharUnits Align = CGM.getContext().getTypeAlignInChars(ArrayQTy); + GV->setAlignment(Align.getQuantity()); + EmitFinalDestCopy(ArrayQTy, CGF.MakeAddrLValue(GV, ArrayQTy, Align)); + return; +} + } + //
[PATCH] D43187: [AST] Refine the condition for element-dependent array fillers
This revision was automatically updated to reflect the committed changes. Closed by commit rL325120: [AST] Refine the condition for element-dependent array fillers (authored by kosarev, committed by ). Changed prior to commit: https://reviews.llvm.org/D43187?vs=133846&id=134200#toc Repository: rL LLVM https://reviews.llvm.org/D43187 Files: cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/test/SemaCXX/large-array-init.cpp Index: cfe/trunk/test/SemaCXX/large-array-init.cpp === --- cfe/trunk/test/SemaCXX/large-array-init.cpp +++ cfe/trunk/test/SemaCXX/large-array-init.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -S -o %t.ll -mllvm -debug-only=exprconstant %s 2>&1 | \ +// RUN: FileCheck %s + +struct S { int i; }; + +static struct S arr[1] = {{ 0 }}; +// CHECK: The number of elements to initialize: 1. + +struct S *foo() { return arr; } Index: cfe/trunk/lib/AST/ExprConstant.cpp === --- cfe/trunk/lib/AST/ExprConstant.cpp +++ cfe/trunk/lib/AST/ExprConstant.cpp @@ -48,6 +48,8 @@ #include #include +#define DEBUG_TYPE "exprconstant" + using namespace clang; using llvm::APSInt; using llvm::APFloat; @@ -6780,6 +6782,22 @@ return ArrayExprEvaluator(Info, This, Result).Visit(E); } +// Return true iff the given array filler may depend on the element index. +static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) { + // For now, just whitelist non-class value-initialization and initialization + // lists comprised of them. + if (isa(FillerExpr)) +return false; + if (const InitListExpr *ILE = dyn_cast(FillerExpr)) { +for (unsigned I = 0, E = ILE->getNumInits(); I != E; ++I) { + if (MaybeElementDependentArrayFiller(ILE->getInit(I))) +return true; +} +return false; + } + return true; +} + bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) { const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(E->getType()); if (!CAT) @@ -6809,10 +6827,13 @@ const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : nullptr; // If the initializer might depend on the array index, run it for each - // array element. For now, just whitelist non-class value-initialization. - if (NumEltsToInit != NumElts && !isa(FillerExpr)) + // array element. + if (NumEltsToInit != NumElts && MaybeElementDependentArrayFiller(FillerExpr)) NumEltsToInit = NumElts; + DEBUG(llvm::dbgs() << "The number of elements to initialize: " << +NumEltsToInit << ".\n"); + Result = APValue(APValue::UninitArray(), NumEltsToInit, NumElts); // If the array was previously zero-initialized, preserve the Index: cfe/trunk/test/SemaCXX/large-array-init.cpp === --- cfe/trunk/test/SemaCXX/large-array-init.cpp +++ cfe/trunk/test/SemaCXX/large-array-init.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -S -o %t.ll -mllvm -debug-only=exprconstant %s 2>&1 | \ +// RUN: FileCheck %s + +struct S { int i; }; + +static struct S arr[1] = {{ 0 }}; +// CHECK: The number of elements to initialize: 1. + +struct S *foo() { return arr; } Index: cfe/trunk/lib/AST/ExprConstant.cpp === --- cfe/trunk/lib/AST/ExprConstant.cpp +++ cfe/trunk/lib/AST/ExprConstant.cpp @@ -48,6 +48,8 @@ #include #include +#define DEBUG_TYPE "exprconstant" + using namespace clang; using llvm::APSInt; using llvm::APFloat; @@ -6780,6 +6782,22 @@ return ArrayExprEvaluator(Info, This, Result).Visit(E); } +// Return true iff the given array filler may depend on the element index. +static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) { + // For now, just whitelist non-class value-initialization and initialization + // lists comprised of them. + if (isa(FillerExpr)) +return false; + if (const InitListExpr *ILE = dyn_cast(FillerExpr)) { +for (unsigned I = 0, E = ILE->getNumInits(); I != E; ++I) { + if (MaybeElementDependentArrayFiller(ILE->getInit(I))) +return true; +} +return false; + } + return true; +} + bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) { const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(E->getType()); if (!CAT) @@ -6809,10 +6827,13 @@ const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : nullptr; // If the initializer might depend on the array index, run it for each - // array element. For now, just whitelist non-class value-initialization. - if (NumEltsToInit != NumElts && !isa(FillerExpr)) + // array element. + if (NumEltsToInit != NumElts && MaybeElementDependentArrayFiller(FillerExpr)) NumEltsToInit = NumElts; + DEBUG(llvm::dbgs() << "The number of elements to initialize: " << +NumEltsToInit << ".\n"); + Result = APValue(APValue::UninitArray(), NumEltsToInit,
[PATCH] D43181: [CodeGen] Initialize large arrays by copying from a global
kosarev updated this revision to Diff 134590. kosarev added a comment. Updated to consider the total size of the explicit initializers instead of their number. The threshold value is adjusted respectively. https://reviews.llvm.org/D43181 Files: lib/CodeGen/CGExprAgg.cpp test/CodeGen/init.c Index: test/CodeGen/init.c === --- test/CodeGen/init.c +++ test/CodeGen/init.c @@ -8,8 +8,9 @@ // CHECK-DAG: %struct.M = type { [2 x %struct.I] } // CHECK-DAG: %struct.I = type { [3 x i32] } -// CHECK: [1 x %struct.M] [%struct.M { [2 x %struct.I] [%struct.I { [3 x i32] [i32 4, i32 4, i32 0] }, %struct.I { [3 x i32] [i32 4, i32 4, i32 5] }] }], -// CHECK: [2 x [3 x i32]] {{[[][[]}}3 x i32] [i32 , i32 , i32 0], [3 x i32] [i32 , i32 , i32 ]], +// CHECK-DAG: [1 x %struct.M] [%struct.M { [2 x %struct.I] [%struct.I { [3 x i32] [i32 4, i32 4, i32 0] }, %struct.I { [3 x i32] [i32 4, i32 4, i32 5] }] }], +// CHECK-DAG: [2 x [3 x i32]] {{[[][[]}}3 x i32] [i32 , i32 , i32 0], [3 x i32] [i32 , i32 , i32 ]], +// CHECK-DAG: [[INIT14:.*]] = private global [16 x i32] [i32 0, i32 0, i32 0, i32 0, i32 0, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 0, i32 0, i32 0, i32 0], align 4 void f1() { // Scalars in braces. @@ -33,8 +34,8 @@ } // Constants -// CHECK: @g3 = constant i32 10 -// CHECK: @f4.g4 = internal constant i32 12 +// CHECK-DAG: @g3 = constant i32 10 +// CHECK-DAG: @f4.g4 = internal constant i32 12 const int g3 = 10; int f4() { static const int g4 = 12; @@ -61,7 +62,7 @@ -// CHECK: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } +// CHECK-DAG: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } // PR8217 struct a7 { int b; @@ -151,3 +152,15 @@ // CHECK: memcpy{{.*}}getelementptr inbounds ([3 x i8], [3 x i8]* @ bar((char[3]) {""}); } + +// Test that we initialize large member arrays by copying from a global and not +// with a series of stores. +struct S14 { int a[16]; }; + +void test14(struct S14 *s14) { +// CHECK-LABEL: @test14 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 {{.*}}, i8* align 4 {{.*}} [[INIT14]] {{.*}}, i32 64, i1 false) +// CHECK-NOT: store +// CHECK: ret void + *s14 = (struct S14) { { [5 ... 11] = 17 } }; +} Index: lib/CodeGen/CGExprAgg.cpp === --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -14,6 +14,7 @@ #include "CodeGenFunction.h" #include "CGObjCRuntime.h" #include "CodeGenModule.h" +#include "ConstantEmitter.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" @@ -85,7 +86,7 @@ void EmitMoveFromReturnSlot(const Expr *E, RValue Src); void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, - QualType elementType, InitListExpr *E); + QualType ArrayQTy, InitListExpr *E); AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) { if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T)) @@ -394,12 +395,15 @@ /// \brief Emit initialization of an array from an initializer list. void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, - QualType elementType, InitListExpr *E) { + QualType ArrayQTy, InitListExpr *E) { uint64_t NumInitElements = E->getNumInits(); uint64_t NumArrayElements = AType->getNumElements(); assert(NumInitElements <= NumArrayElements); + QualType elementType = + CGF.getContext().getAsArrayType(ArrayQTy)->getElementType(); + // DestPtr is an array*. Construct an elementType* by drilling // down a level. llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); @@ -411,6 +415,29 @@ CharUnits elementAlign = DestPtr.getAlignment().alignmentOfArrayElement(elementSize); + // Consider initializing the array by copying from a global. For this to be + // more efficient than per-element initialization, the number of the elements + // with explicit initializers should be large enough. + if (NumInitElements * elementSize.getQuantity() > 16 && + elementType.isTriviallyCopyableType(CGF.getContext())) { +CodeGen::CodeGenModule &CGM = CGF.CGM; +ConstantEmitter Emitter(CGM); +LangAS AS = ArrayQTy.getAddressSpace(); +if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) { + auto GV = new llvm::GlobalVariable( + CGM.getModule(), C->getType(), + CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true), + llvm::GlobalValue::PrivateLinkage, C, "constinit", + /* InsertBefore= */ nullptr, llvm::GlobalVariable::NotThreadLocal, + CGM.getContext().getTargetAddressSpace(AS)); + Emitter.finalize(GV); + CharUnits Align = CGM.getContext().getTypeAlignInChars(ArrayQTy); + GV->setAlignment(Align.getQuantity()); +
[PATCH] D42366: [CodeGen] Fix generation of TBAA tags for may-alias accesses
kosarev added a comment. John, the patch hangs for about a month now and Hal still seems to be extremely busy. Can we commit this with the constant to be whatever you think is most correct and the fix it as needed and if needed later? At this very moment we don't analyze the size fields of tags anyway, so the point of this patch is mostly to handle may-alias-marked types correctly. Repository: rL LLVM https://reviews.llvm.org/D42366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D43181: [CodeGen] Initialize large arrays by copying from a global
This revision was automatically updated to reflect the committed changes. Closed by commit rL325478: [CodeGen] Initialize large arrays by copying from a global (authored by kosarev, committed by ). Changed prior to commit: https://reviews.llvm.org/D43181?vs=134590&id=134865#toc Repository: rL LLVM https://reviews.llvm.org/D43181 Files: cfe/trunk/lib/CodeGen/CGExprAgg.cpp cfe/trunk/test/CodeGen/init.c Index: cfe/trunk/test/CodeGen/init.c === --- cfe/trunk/test/CodeGen/init.c +++ cfe/trunk/test/CodeGen/init.c @@ -8,8 +8,9 @@ // CHECK-DAG: %struct.M = type { [2 x %struct.I] } // CHECK-DAG: %struct.I = type { [3 x i32] } -// CHECK: [1 x %struct.M] [%struct.M { [2 x %struct.I] [%struct.I { [3 x i32] [i32 4, i32 4, i32 0] }, %struct.I { [3 x i32] [i32 4, i32 4, i32 5] }] }], -// CHECK: [2 x [3 x i32]] {{[[][[]}}3 x i32] [i32 , i32 , i32 0], [3 x i32] [i32 , i32 , i32 ]], +// CHECK-DAG: [1 x %struct.M] [%struct.M { [2 x %struct.I] [%struct.I { [3 x i32] [i32 4, i32 4, i32 0] }, %struct.I { [3 x i32] [i32 4, i32 4, i32 5] }] }], +// CHECK-DAG: [2 x [3 x i32]] {{[[][[]}}3 x i32] [i32 , i32 , i32 0], [3 x i32] [i32 , i32 , i32 ]], +// CHECK-DAG: [[INIT14:.*]] = private global [16 x i32] [i32 0, i32 0, i32 0, i32 0, i32 0, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 0, i32 0, i32 0, i32 0], align 4 void f1() { // Scalars in braces. @@ -33,8 +34,8 @@ } // Constants -// CHECK: @g3 = constant i32 10 -// CHECK: @f4.g4 = internal constant i32 12 +// CHECK-DAG: @g3 = constant i32 10 +// CHECK-DAG: @f4.g4 = internal constant i32 12 const int g3 = 10; int f4() { static const int g4 = 12; @@ -61,7 +62,7 @@ -// CHECK: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } +// CHECK-DAG: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } // PR8217 struct a7 { int b; @@ -151,3 +152,15 @@ // CHECK: memcpy{{.*}}getelementptr inbounds ([3 x i8], [3 x i8]* @ bar((char[3]) {""}); } + +// Test that we initialize large member arrays by copying from a global and not +// with a series of stores. +struct S14 { int a[16]; }; + +void test14(struct S14 *s14) { +// CHECK-LABEL: @test14 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 {{.*}}, i8* align 4 {{.*}} [[INIT14]] {{.*}}, i32 64, i1 false) +// CHECK-NOT: store +// CHECK: ret void + *s14 = (struct S14) { { [5 ... 11] = 17 } }; +} Index: cfe/trunk/lib/CodeGen/CGExprAgg.cpp === --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp @@ -14,6 +14,7 @@ #include "CodeGenFunction.h" #include "CGObjCRuntime.h" #include "CodeGenModule.h" +#include "ConstantEmitter.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" @@ -85,7 +86,7 @@ void EmitMoveFromReturnSlot(const Expr *E, RValue Src); void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, - QualType elementType, InitListExpr *E); + QualType ArrayQTy, InitListExpr *E); AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) { if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T)) @@ -394,12 +395,15 @@ /// \brief Emit initialization of an array from an initializer list. void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, - QualType elementType, InitListExpr *E) { + QualType ArrayQTy, InitListExpr *E) { uint64_t NumInitElements = E->getNumInits(); uint64_t NumArrayElements = AType->getNumElements(); assert(NumInitElements <= NumArrayElements); + QualType elementType = + CGF.getContext().getAsArrayType(ArrayQTy)->getElementType(); + // DestPtr is an array*. Construct an elementType* by drilling // down a level. llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); @@ -411,6 +415,29 @@ CharUnits elementAlign = DestPtr.getAlignment().alignmentOfArrayElement(elementSize); + // Consider initializing the array by copying from a global. For this to be + // more efficient than per-element initialization, the size of the elements + // with explicit initializers should be large enough. + if (NumInitElements * elementSize.getQuantity() > 16 && + elementType.isTriviallyCopyableType(CGF.getContext())) { +CodeGen::CodeGenModule &CGM = CGF.CGM; +ConstantEmitter Emitter(CGM); +LangAS AS = ArrayQTy.getAddressSpace(); +if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) { + auto GV = new llvm::GlobalVariable( + CGM.getModule(), C->getType(), + CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true), + llvm::GlobalValue::PrivateLinkage, C, "constinit", + /* InsertBefore= */ nullptr, llvm::GlobalVariable::NotThreadLocal, + CGM.getContext().getTarge
[PATCH] D42366: [CodeGen] Fix generation of TBAA tags for may-alias accesses
kosarev updated this revision to Diff 134877. kosarev edited the summary of this revision. kosarev added a comment. Do not change the size field of may-alias TBAA descriptors for now. https://reviews.llvm.org/D42366 Files: lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenTBAA.cpp lib/CodeGen/CodeGenTBAA.h test/CodeGen/may-alias.c Index: test/CodeGen/may-alias.c === --- test/CodeGen/may-alias.c +++ test/CodeGen/may-alias.c @@ -1,42 +1,61 @@ -// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -no-struct-path-tbaa -disable-llvm-passes -o - %s | FileCheck %s -// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-passes -o - %s | FileCheck %s -check-prefix=PATH +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 \ +// RUN: -no-struct-path-tbaa -disable-llvm-passes -o - %s | \ +// RUN: FileCheck %s -check-prefixes=CHECK,SCALAR +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 \ +// RUN: -disable-llvm-passes -o - %s | \ +// RUN: FileCheck %s -check-prefixes=CHECK,OLD-PATH +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 \ +// RUN: -new-struct-path-tbaa -disable-llvm-passes -o - %s | \ +// RUN: FileCheck %s -check-prefixes=CHECK,NEW-PATH // Types with the may_alias attribute should be considered equivalent // to char for aliasing. typedef int __attribute__((may_alias)) aliasing_int; -void test0(aliasing_int *ai, int *i) -{ -// CHECK: store i32 0, i32* %{{.*}}, !tbaa [[TAG_CHAR:!.*]] -// PATH: store i32 0, i32* %{{.*}}, !tbaa [[TAG_CHAR:!.*]] +void test0(aliasing_int *ai, int *i) { +// CHECK-LABEL: test0 +// CHECK: store i32 0, {{.*}}, !tbaa [[TAG_alias_int:!.*]] *ai = 0; -// CHECK: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]] -// PATH: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]] + +// CHECK: store i32 1, {{.*}}, !tbaa [[TAG_int:!.*]] *i = 1; } // PR9307 struct Test1 { int x; }; struct Test1MA { int x; } __attribute__((may_alias)); void test1(struct Test1MA *p1, struct Test1 *p2) { - // CHECK: store i32 2, i32* {{%.*}}, !tbaa [[TAG_CHAR]] - // PATH: store i32 2, i32* {{%.*}}, !tbaa [[TAG_CHAR]] +// CHECK-LABEL: test1 +// CHECK: store i32 2, {{.*}}, !tbaa [[TAG_alias_test1_x:!.*]] p1->x = 2; - // CHECK: store i32 3, i32* {{%.*}}, !tbaa [[TAG_INT]] - // PATH: store i32 3, i32* {{%.*}}, !tbaa [[TAG_test1_x:!.*]] + +// CHECK: store i32 3, {{.*}}, !tbaa [[TAG_test1_x:!.*]] p2->x = 3; } -// CHECK: !"any pointer", [[TYPE_CHAR:!.*]], -// CHECK: [[TYPE_CHAR]] = !{!"omnipotent char", [[TAG_CXX_TBAA:!.*]], -// CHECK: [[TAG_CXX_TBAA]] = !{!"Simple C/C++ TBAA"} -// CHECK: [[TAG_CHAR]] = !{[[TYPE_CHAR]], [[TYPE_CHAR]], i64 0} -// CHECK: [[TAG_INT]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0} -// CHECK: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]] - -// PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", !{{.*}} -// PATH: [[TAG_CHAR]] = !{[[TYPE_CHAR]], [[TYPE_CHAR]], i64 0} -// PATH: [[TAG_INT]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0} -// PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]] -// PATH: [[TAG_test1_x]] = !{[[TYPE_test1:!.*]], [[TYPE_INT]], i64 0} -// PATH: [[TYPE_test1]] = !{!"Test1", [[TYPE_INT]], i64 0} + +// SCALAR-DAG: [[ROOT:!.*]] = !{!"Simple C/C++ TBAA"} +// SCALAR-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", [[ROOT]], i64 0} +// SCALAR-DAG: [[TAG_alias_int]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} +// SCALAR-DAG: [[TAG_alias_test1_x]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} +// SCALAR-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0} +// SCALAR-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0} +// SCALAR-DAG: [[TAG_test1_x]] = !{[[TYPE_int]], [[TYPE_int]], i64 0} + +// OLD-PATH-DAG: [[ROOT:!.*]] = !{!"Simple C/C++ TBAA"} +// OLD-PATH-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", [[ROOT]], i64 0} +// OLD-PATH-DAG: [[TAG_alias_int]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} +// OLD-PATH-DAG: [[TAG_alias_test1_x]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} +// OLD-PATH-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0} +// OLD-PATH-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0} +// OLD-PATH-DAG: [[TYPE_test1:!.*]] = !{!"Test1", [[TYPE_int]], i64 0} +// OLD-PATH-DAG: [[TAG_test1_x]] = !{[[TYPE_test1]], [[TYPE_int]], i64 0} + +// NEW-PATH-DAG: [[ROOT:!.*]] = !{!"Simple C/C++ TBAA"} +// NEW-PATH-DAG: [[TYPE_char:!.*]] = !{[[ROOT]], i64 1, !"omnipotent char"} +// NEW-PATH-DAG: [[TAG_alias_int]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0} +// NEW-PATH-DAG: [[TAG_alias_test1_x]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0} +// NEW-PATH-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"} +// NEW-PATH-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0, i64 4} +// NEW-PATH-DAG: [[TYPE_test1:!.*]] = !{[[TYPE_char]], i64 4, !"Test1", [[TYPE_int]], i64 0, i64 4} +// NEW-PATH-DAG: [[TAG_test1_x]] = !{[[TYPE_test1]], [[TYPE_int]], i64 0, i64
[PATCH] D42366: [CodeGen] Fix generation of TBAA tags for may-alias accesses
This revision was automatically updated to reflect the committed changes. Closed by commit rC325575: [CodeGen] Fix generation of TBAA tags for may-alias accesses (authored by kosarev, committed by ). Repository: rC Clang https://reviews.llvm.org/D42366 Files: lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenTBAA.cpp lib/CodeGen/CodeGenTBAA.h test/CodeGen/may-alias.c Index: test/CodeGen/may-alias.c === --- test/CodeGen/may-alias.c +++ test/CodeGen/may-alias.c @@ -1,42 +1,61 @@ -// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -no-struct-path-tbaa -disable-llvm-passes -o - %s | FileCheck %s -// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-passes -o - %s | FileCheck %s -check-prefix=PATH +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 \ +// RUN: -no-struct-path-tbaa -disable-llvm-passes -o - %s | \ +// RUN: FileCheck %s -check-prefixes=CHECK,SCALAR +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 \ +// RUN: -disable-llvm-passes -o - %s | \ +// RUN: FileCheck %s -check-prefixes=CHECK,OLD-PATH +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 \ +// RUN: -new-struct-path-tbaa -disable-llvm-passes -o - %s | \ +// RUN: FileCheck %s -check-prefixes=CHECK,NEW-PATH // Types with the may_alias attribute should be considered equivalent // to char for aliasing. typedef int __attribute__((may_alias)) aliasing_int; -void test0(aliasing_int *ai, int *i) -{ -// CHECK: store i32 0, i32* %{{.*}}, !tbaa [[TAG_CHAR:!.*]] -// PATH: store i32 0, i32* %{{.*}}, !tbaa [[TAG_CHAR:!.*]] +void test0(aliasing_int *ai, int *i) { +// CHECK-LABEL: test0 +// CHECK: store i32 0, {{.*}}, !tbaa [[TAG_alias_int:!.*]] *ai = 0; -// CHECK: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]] -// PATH: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]] + +// CHECK: store i32 1, {{.*}}, !tbaa [[TAG_int:!.*]] *i = 1; } // PR9307 struct Test1 { int x; }; struct Test1MA { int x; } __attribute__((may_alias)); void test1(struct Test1MA *p1, struct Test1 *p2) { - // CHECK: store i32 2, i32* {{%.*}}, !tbaa [[TAG_CHAR]] - // PATH: store i32 2, i32* {{%.*}}, !tbaa [[TAG_CHAR]] +// CHECK-LABEL: test1 +// CHECK: store i32 2, {{.*}}, !tbaa [[TAG_alias_test1_x:!.*]] p1->x = 2; - // CHECK: store i32 3, i32* {{%.*}}, !tbaa [[TAG_INT]] - // PATH: store i32 3, i32* {{%.*}}, !tbaa [[TAG_test1_x:!.*]] + +// CHECK: store i32 3, {{.*}}, !tbaa [[TAG_test1_x:!.*]] p2->x = 3; } -// CHECK: !"any pointer", [[TYPE_CHAR:!.*]], -// CHECK: [[TYPE_CHAR]] = !{!"omnipotent char", [[TAG_CXX_TBAA:!.*]], -// CHECK: [[TAG_CXX_TBAA]] = !{!"Simple C/C++ TBAA"} -// CHECK: [[TAG_CHAR]] = !{[[TYPE_CHAR]], [[TYPE_CHAR]], i64 0} -// CHECK: [[TAG_INT]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0} -// CHECK: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]] - -// PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", !{{.*}} -// PATH: [[TAG_CHAR]] = !{[[TYPE_CHAR]], [[TYPE_CHAR]], i64 0} -// PATH: [[TAG_INT]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0} -// PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]] -// PATH: [[TAG_test1_x]] = !{[[TYPE_test1:!.*]], [[TYPE_INT]], i64 0} -// PATH: [[TYPE_test1]] = !{!"Test1", [[TYPE_INT]], i64 0} + +// SCALAR-DAG: [[ROOT:!.*]] = !{!"Simple C/C++ TBAA"} +// SCALAR-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", [[ROOT]], i64 0} +// SCALAR-DAG: [[TAG_alias_int]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} +// SCALAR-DAG: [[TAG_alias_test1_x]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} +// SCALAR-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0} +// SCALAR-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0} +// SCALAR-DAG: [[TAG_test1_x]] = !{[[TYPE_int]], [[TYPE_int]], i64 0} + +// OLD-PATH-DAG: [[ROOT:!.*]] = !{!"Simple C/C++ TBAA"} +// OLD-PATH-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", [[ROOT]], i64 0} +// OLD-PATH-DAG: [[TAG_alias_int]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} +// OLD-PATH-DAG: [[TAG_alias_test1_x]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} +// OLD-PATH-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0} +// OLD-PATH-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0} +// OLD-PATH-DAG: [[TYPE_test1:!.*]] = !{!"Test1", [[TYPE_int]], i64 0} +// OLD-PATH-DAG: [[TAG_test1_x]] = !{[[TYPE_test1]], [[TYPE_int]], i64 0} + +// NEW-PATH-DAG: [[ROOT:!.*]] = !{!"Simple C/C++ TBAA"} +// NEW-PATH-DAG: [[TYPE_char:!.*]] = !{[[ROOT]], i64 1, !"omnipotent char"} +// NEW-PATH-DAG: [[TAG_alias_int]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0} +// NEW-PATH-DAG: [[TAG_alias_test1_x]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0} +// NEW-PATH-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"} +// NEW-PATH-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0, i64 4} +// NEW-PATH-DAG: [[TYPE_test1:!.*]] = !{[[TYPE_char]], i64 4, !"Test1", [[TYPE_int]], i64 0, i64 4} +// NEW-PATH-DAG: [[TAG_test1_x]] = !{[[
[PATCH] D42366: [CodeGen] Fix generation of TBAA tags for may-alias accesses
kosarev added a comment. I think zero would serve better as the unknown-size value. People who are not aware of TBAA internals would guess that since zero-sized accesses make no sense, they are likely to have some special meaning. Similarly, for code that is supposed to process the size fields of access descriptors zero would be an obvious "illegal size value". In contrast, UINT64_MAX is just a very large number that doesn't hint anything on its special purpose. Either way, we should reflect the convention in the documentation, https://reviews.llvm.org/D40975. Repository: rC Clang https://reviews.llvm.org/D42366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41394: [CodeGen] Support generation of TBAA info in the new format
kosarev created this revision. kosarev added reviewers: rjmccall, hfinkel. kosarev added a project: clang. Now that the MDBuilder helpers generating TBAA type and access descriptors in the new format are in place, we can teach clang to use them when requested. Repository: rL LLVM https://reviews.llvm.org/D41394 Files: lib/CodeGen/CodeGenTBAA.cpp Index: lib/CodeGen/CodeGenTBAA.cpp === --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -59,7 +59,10 @@ llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, uint64_t Size) { - (void)Size; // TODO: Support generation of size-aware type nodes. + if (CodeGenOpts.NewStructPathTBAA) { +llvm::Metadata *Id = MDHelper.createString(Name); +return MDHelper.createTBAATypeNode(Parent, Size, Id); + } return MDHelper.createTBAAScalarTypeNode(Name, Parent); } @@ -300,8 +303,12 @@ OutName = RD->getName(); } -// TODO: Support size-aware type nodes and create one here for the -// given aggregate type. +if (CodeGenOpts.NewStructPathTBAA) { + llvm::MDNode *Parent = getChar(); + uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity(); + llvm::Metadata *Id = MDHelper.createString(OutName); + return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields); +} // Create the struct type node with a vector of pairs (offset, type). SmallVector, 4> OffsetsAndTypes; @@ -348,6 +355,10 @@ Info.BaseType = Info.AccessType; assert(!Info.Offset && "Nonzero offset for an access with no base type!"); } + if (CodeGenOpts.NewStructPathTBAA) { +return N = MDHelper.createTBAAAccessTag(Info.BaseType, Info.AccessType, +Info.Offset, Info.Size); + } return N = MDHelper.createTBAAStructTagNode(Info.BaseType, Info.AccessType, Info.Offset); } Index: lib/CodeGen/CodeGenTBAA.cpp === --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -59,7 +59,10 @@ llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, uint64_t Size) { - (void)Size; // TODO: Support generation of size-aware type nodes. + if (CodeGenOpts.NewStructPathTBAA) { +llvm::Metadata *Id = MDHelper.createString(Name); +return MDHelper.createTBAATypeNode(Parent, Size, Id); + } return MDHelper.createTBAAScalarTypeNode(Name, Parent); } @@ -300,8 +303,12 @@ OutName = RD->getName(); } -// TODO: Support size-aware type nodes and create one here for the -// given aggregate type. +if (CodeGenOpts.NewStructPathTBAA) { + llvm::MDNode *Parent = getChar(); + uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity(); + llvm::Metadata *Id = MDHelper.createString(OutName); + return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields); +} // Create the struct type node with a vector of pairs (offset, type). SmallVector, 4> OffsetsAndTypes; @@ -348,6 +355,10 @@ Info.BaseType = Info.AccessType; assert(!Info.Offset && "Nonzero offset for an access with no base type!"); } + if (CodeGenOpts.NewStructPathTBAA) { +return N = MDHelper.createTBAAAccessTag(Info.BaseType, Info.AccessType, +Info.Offset, Info.Size); + } return N = MDHelper.createTBAAStructTagNode(Info.BaseType, Info.AccessType, Info.Offset); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41399: [CodeGen] Represent array members in new-format TBAA type descriptors
kosarev created this revision. kosarev added reviewers: rjmccall, hfinkel. kosarev added a project: clang. Now that in the new TBAA format we allow access types to be of any object types, including aggregate ones, it becomes critical to specify types of all sub-objects such aggregates comprise as their members. In order to meet this requirement, this patch enables generation of field descriptors for members of array types. This patch requires https://reviews.llvm.org/D41394 to be landed first. Repository: rL LLVM https://reviews.llvm.org/D41399 Files: lib/CodeGen/CodeGenTBAA.cpp test/CodeGen/tbaa-array.cpp Index: test/CodeGen/tbaa-array.cpp === --- test/CodeGen/tbaa-array.cpp +++ test/CodeGen/tbaa-array.cpp @@ -1,18 +1,28 @@ // RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ -// RUN: -emit-llvm -o - | FileCheck %s -// -// Check that we generate correct TBAA information for accesses to array -// elements. +// RUN: -new-struct-path-tbaa -emit-llvm -o - | FileCheck %s struct A { int i; }; struct B { A a[1]; }; +struct C { int i; int x[3]; }; +// Check that we generate correct TBAA information for accesses to array +// elements. int foo(B *b) { // CHECK-LABEL: _Z3fooP1B // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] return b->a->i; } -// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} -// CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} -// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} +// Check that members of array types are represented correctly. +int bar(C *c) { +// CHECK-LABEL: _Z3barP1C +// CHECK: load i32, {{.*}}, !tbaa [[TAG_C_i:!.*]] + return c->i; +} + +// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0, i64 4} +// CHECK-DAG: [[TAG_C_i]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 0, i64 16} +// CHECK-DAG: [[TYPE_A]] = !{[[TYPE_char:!.*]], i64 4, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4} +// CHECK-DAG: [[TYPE_C]] = !{[[TYPE_char]], i64 16, !"_ZTS1C", [[TYPE_int]], i64 0, i64 4, [[TYPE_int]], i64 4, i64 12} +// CHECK-DAG: [[TYPE_int]] = !{[[TYPE_char]], i64 4, !"int"} +// CHECK-DAG: [[TYPE_char]] = !{{{!.*}}, i64 1, !"omnipotent char"} Index: lib/CodeGen/CodeGenTBAA.cpp === --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -161,6 +161,10 @@ if (Ty->isPointerType() || Ty->isReferenceType()) return createScalarTypeNode("any pointer", getChar(), Size); + // Accesses to arrays are accesses to objects of their element types. + if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType()) +return getTypeInfo(cast(Ty)->getElementType()); + // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. if (const EnumType *ETy = dyn_cast(Ty)) { Index: test/CodeGen/tbaa-array.cpp === --- test/CodeGen/tbaa-array.cpp +++ test/CodeGen/tbaa-array.cpp @@ -1,18 +1,28 @@ // RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ -// RUN: -emit-llvm -o - | FileCheck %s -// -// Check that we generate correct TBAA information for accesses to array -// elements. +// RUN: -new-struct-path-tbaa -emit-llvm -o - | FileCheck %s struct A { int i; }; struct B { A a[1]; }; +struct C { int i; int x[3]; }; +// Check that we generate correct TBAA information for accesses to array +// elements. int foo(B *b) { // CHECK-LABEL: _Z3fooP1B // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] return b->a->i; } -// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} -// CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} -// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} +// Check that members of array types are represented correctly. +int bar(C *c) { +// CHECK-LABEL: _Z3barP1C +// CHECK: load i32, {{.*}}, !tbaa [[TAG_C_i:!.*]] + return c->i; +} + +// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0, i64 4} +// CHECK-DAG: [[TAG_C_i]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 0, i64 16} +// CHECK-DAG: [[TYPE_A]] = !{[[TYPE_char:!.*]], i64 4, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4} +// CHECK-DAG: [[TYPE_C]] = !{[[TYPE_char]], i64 16, !"_ZTS1C", [[TYPE_int]], i64 0, i64 4, [[TYPE_int]], i64 4, i64 12} +// CHECK-DAG: [[TYPE_int]] = !{[[TYPE_char]], i64 4, !"int"} +// CHECK-DAG: [[TYPE_char]] = !{{{!.*}}, i64 1, !"omnipotent char"} Index: lib/CodeGen/CodeGenTBAA.cpp === --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -161,6 +161,10 @@ if (Ty->isPointerType() || Ty->isReferenceType()) return createScalarTypeNode("any pointer", getChar(), Size); + // Accesses to arrays are accesses to objects of their element types. + if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType()) +return getTypeInfo(cas
[PATCH] D41394: [CodeGen] Support generation of TBAA info in the new format
kosarev added a comment. There are more tests that we will need to rewrite during migration to the new format than I think we could handle with a single patch. I was going to address them with separate patches. Or, I can rewrite some most basic of them as part of this patch. Repository: rL LLVM https://reviews.llvm.org/D41394 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41394: [CodeGen] Support generation of TBAA info in the new format
kosarev updated this revision to Diff 127722. kosarev added a comment. Added tests. https://reviews.llvm.org/D41394 Files: lib/CodeGen/CodeGenTBAA.cpp test/CodeGen/tbaa.cpp Index: test/CodeGen/tbaa.cpp === --- test/CodeGen/tbaa.cpp +++ test/CodeGen/tbaa.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -new-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NEW-PATH // RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA // Test TBAA metadata generated by front-end. @@ -55,6 +56,9 @@ // PATH-LABEL: define i32 @_Z1g // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]] // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]] +// NEW-PATH-LABEL: define i32 @_Z1g +// NEW-PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]] +// NEW-PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]] *s = 1; A->f32 = 4; return *s; @@ -67,6 +71,9 @@ // PATH-LABEL: define i32 @_Z2g2 // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]] // PATH: store i16 4, i16* %{{.*}}, align 4, !tbaa [[TAG_A_f16:!.*]] +// NEW-PATH-LABEL: define i32 @_Z2g2 +// NEW-PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]] +// NEW-PATH: store i16 4, i16* %{{.*}}, align 4, !tbaa [[TAG_A_f16:!.*]] *s = 1; A->f16 = 4; return *s; @@ -79,6 +86,9 @@ // PATH-LABEL: define i32 @_Z2g3 // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]] +// NEW-PATH-LABEL: define i32 @_Z2g3 +// NEW-PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// NEW-PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]] A->f32 = 1; B->a.f32 = 4; return A->f32; @@ -91,6 +101,9 @@ // PATH-LABEL: define i32 @_Z2g4 // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] // PATH: store i16 4, i16* %{{.*}}, align 4, !tbaa [[TAG_B_a_f16:!.*]] +// NEW-PATH-LABEL: define i32 @_Z2g4 +// NEW-PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// NEW-PATH: store i16 4, i16* %{{.*}}, align 4, !tbaa [[TAG_B_a_f16:!.*]] A->f32 = 1; B->a.f16 = 4; return A->f32; @@ -103,6 +116,9 @@ // PATH-LABEL: define i32 @_Z2g5 // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]] +// NEW-PATH-LABEL: define i32 @_Z2g5 +// NEW-PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// NEW-PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]] A->f32 = 1; B->f32 = 4; return A->f32; @@ -115,6 +131,9 @@ // PATH-LABEL: define i32 @_Z2g6 // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]] +// NEW-PATH-LABEL: define i32 @_Z2g6 +// NEW-PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// NEW-PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]] A->f32 = 1; B->a.f32_2 = 4; return A->f32; @@ -127,6 +146,9 @@ // PATH-LABEL: define i32 @_Z2g7 // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]] +// NEW-PATH-LABEL: define i32 @_Z2g7 +// NEW-PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// NEW-PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]] A->f32 = 1; S->f32 = 4; return A->f32; @@ -139,6 +161,9 @@ // PATH-LABEL: define i32 @_Z2g8 // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] // PATH: store i16 4, i16* %{{.*}}, align 4, !tbaa [[TAG_S_f16:!.*]] +// NEW-PATH-LABEL: define i32 @_Z2g8 +// NEW-PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]] +// NEW-PATH: store i16 4, i16* %{{.*}}, align 4, !tbaa [[TAG_S_f16:!.*]] A->f32 = 1; S->f16 = 4; return A->f32; @@ -151,6 +176,9 @@ // PATH-LABEL: define i32 @_Z2g9 // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]] // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32:!.*]] +// NEW-PATH-LABEL: define i32 @_Z2g9 +// NEW-PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]] +// NEW-PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32:!.*]] S->f32 = 1; S2->f32 = 4; return S->f32; @@ -163,6 +191,9 @@ // PATH-LABEL: define i32 @_Z3g10 // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]] // PATH: store i16
[PATCH] D41452: [CodeGen] Fix access sizes in new-format TBAA tags
kosarev created this revision. kosarev added reviewers: rjmccall, hfinkel. kosarev added a project: clang. The new format requires to specify both the type of the access and its size. This patch fixes setting access sizes for TBAA tags that denote accesses to structure members. This fix affects all future TBAA metadata tests for the new format, so I guess we don't need any special tests for this fix. Repository: rL LLVM https://reviews.llvm.org/D41452 Files: lib/CodeGen/CGExpr.cpp Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3790,8 +3790,10 @@ FieldTBAAInfo.Offset += Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; -// Update the final access type. +// Update the final access type and size. FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType); +FieldTBAAInfo.Size = +getContext().getTypeSizeInChars(FieldType).getQuantity(); } Address addr = base.getAddress(); Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -3790,8 +3790,10 @@ FieldTBAAInfo.Offset += Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; -// Update the final access type. +// Update the final access type and size. FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType); +FieldTBAAInfo.Size = +getContext().getTypeSizeInChars(FieldType).getQuantity(); } Address addr = base.getAddress(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41399: [CodeGen] Represent array members in new-format TBAA type descriptors
kosarev added inline comments. Comment at: test/CodeGen/tbaa-array.cpp:24 +// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0, i64 4} +// CHECK-DAG: [[TAG_C_i]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 0, i64 16} +// CHECK-DAG: [[TYPE_A]] = !{[[TYPE_char:!.*]], i64 4, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4} hfinkel wrote: > Shouldn't this access have a size of 4, and an access for c->x[2] have a size > of 4 and a specific offset and c->x[j] have a size of 12 and an offset of > zero? Why does this list a size of 16? > > In any case, please add tests for: > > int *bar2(C *c) { > return c->x; > } > > int bar3(C *c) { > return c->x[2]; > } > > int bar4(C *c, int j) { > return c->x[j]; > } > Indeed, the access size is wrong as we mistakenly inherit it from the base type. D41452 fixes this. Thanks for catching. Repository: rL LLVM https://reviews.llvm.org/D41399 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41399: [CodeGen] Represent array members in new-format TBAA type descriptors
kosarev added inline comments. Comment at: test/CodeGen/tbaa-array.cpp:24 +// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0, i64 4} +// CHECK-DAG: [[TAG_C_i]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 0, i64 16} +// CHECK-DAG: [[TYPE_A]] = !{[[TYPE_char:!.*]], i64 4, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4} kosarev wrote: > hfinkel wrote: > > Shouldn't this access have a size of 4, and an access for c->x[2] have a > > size of 4 and a specific offset and c->x[j] have a size of 12 and an offset > > of zero? Why does this list a size of 16? > > > > In any case, please add tests for: > > > > int *bar2(C *c) { > > return c->x; > > } > > > > int bar3(C *c) { > > return c->x[2]; > > } > > > > int bar4(C *c, int j) { > > return c->x[j]; > > } > > > Indeed, the access size is wrong as we mistakenly inherit it from the base > type. D41452 fixes this. Thanks for catching. Hal, in bar2() we don't really access memory. What do we want to check with it? Repository: rL LLVM https://reviews.llvm.org/D41399 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41399: [CodeGen] Represent array members in new-format TBAA type descriptors
kosarev updated this revision to Diff 127742. kosarev added a comment. - Fixed the access size. - Added the suggested tests. https://reviews.llvm.org/D41399 Files: lib/CodeGen/CodeGenTBAA.cpp test/CodeGen/tbaa-array.cpp Index: test/CodeGen/tbaa-array.cpp === --- test/CodeGen/tbaa-array.cpp +++ test/CodeGen/tbaa-array.cpp @@ -1,18 +1,52 @@ // RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ // RUN: -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -new-struct-path-tbaa -emit-llvm -o - | \ +// RUN: FileCheck -check-prefix=CHECK-NEW %s // // Check that we generate correct TBAA information for accesses to array // elements. struct A { int i; }; struct B { A a[1]; }; +struct C { int i; int x[3]; }; int foo(B *b) { // CHECK-LABEL: _Z3fooP1B // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] +// CHECK-NEW-LABEL: _Z3fooP1B +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] return b->a->i; } +// Check that members of array types are represented correctly. +int bar(C *c) { +// CHECK-NEW-LABEL: _Z3barP1C +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_C_i:!.*]] + return c->i; +} + +int bar2(C *c) { +// CHECK-NEW-LABEL: _Z4bar2P1C +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]] + return c->x[2]; +} + +int bar3(C *c, int j) { +// CHECK-NEW-LABEL: _Z4bar3P1Ci +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]] + return c->x[j]; +} + // CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} // CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} // CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} + +// CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} +// CHECK-NEW-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"} +// CHECK-NEW-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0, i64 4} +// CHECK-NEW-DAG: [[TYPE_pointer:!.*]] = !{[[TYPE_char]], i64 8, !"any pointer"} +// CHECK-NEW-DAG: [[TYPE_A:!.*]] = !{[[TYPE_char]], i64 4, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4} +// CHECK-NEW-DAG: [[TAG_A_i]] = !{[[TYPE_A]], [[TYPE_int]], i64 0, i64 4} +// CHECK-NEW-DAG: [[TYPE_C:!.*]] = !{[[TYPE_char]], i64 16, !"_ZTS1C", [[TYPE_int]], i64 0, i64 4, [[TYPE_int]], i64 4, i64 12} +// CHECK-NEW-DAG: [[TAG_C_i]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 0, i64 4} Index: lib/CodeGen/CodeGenTBAA.cpp === --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -161,6 +161,10 @@ if (Ty->isPointerType() || Ty->isReferenceType()) return createScalarTypeNode("any pointer", getChar(), Size); + // Accesses to arrays are accesses to objects of their element types. + if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType()) +return getTypeInfo(cast(Ty)->getElementType()); + // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. if (const EnumType *ETy = dyn_cast(Ty)) { Index: test/CodeGen/tbaa-array.cpp === --- test/CodeGen/tbaa-array.cpp +++ test/CodeGen/tbaa-array.cpp @@ -1,18 +1,52 @@ // RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ // RUN: -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -new-struct-path-tbaa -emit-llvm -o - | \ +// RUN: FileCheck -check-prefix=CHECK-NEW %s // // Check that we generate correct TBAA information for accesses to array // elements. struct A { int i; }; struct B { A a[1]; }; +struct C { int i; int x[3]; }; int foo(B *b) { // CHECK-LABEL: _Z3fooP1B // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] +// CHECK-NEW-LABEL: _Z3fooP1B +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] return b->a->i; } +// Check that members of array types are represented correctly. +int bar(C *c) { +// CHECK-NEW-LABEL: _Z3barP1C +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_C_i:!.*]] + return c->i; +} + +int bar2(C *c) { +// CHECK-NEW-LABEL: _Z4bar2P1C +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]] + return c->x[2]; +} + +int bar3(C *c, int j) { +// CHECK-NEW-LABEL: _Z4bar3P1Ci +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]] + return c->x[j]; +} + // CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} // CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} // CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} + +// CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} +// CHECK-NEW-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"} +// CHECK-NEW-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0, i64 4} +// CHECK-NEW-DAG: [[TYPE_pointer:!.*]] = !{[[TYPE_char]], i64 8, !"any pointer"} +// CHECK-NEW-DAG: [[TYPE_A:!.*]] = !{[[TYPE_char]], i64 4, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4} +// CHECK-NEW-DAG
[PATCH] D41452: [CodeGen] Fix access sizes in new-format TBAA tags
This revision was automatically updated to reflect the committed changes. Closed by commit rL321250: [CodeGen] Fix access sizes in new-format TBAA tags (authored by kosarev, committed by ). Changed prior to commit: https://reviews.llvm.org/D41452?vs=127724&id=127834#toc Repository: rL LLVM https://reviews.llvm.org/D41452 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -3801,8 +3801,10 @@ FieldTBAAInfo.Offset += Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; -// Update the final access type. +// Update the final access type and size. FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType); +FieldTBAAInfo.Size = +getContext().getTypeSizeInChars(FieldType).getQuantity(); } Address addr = base.getAddress(); Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -3801,8 +3801,10 @@ FieldTBAAInfo.Offset += Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; -// Update the final access type. +// Update the final access type and size. FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType); +FieldTBAAInfo.Size = +getContext().getTypeSizeInChars(FieldType).getQuantity(); } Address addr = base.getAddress(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41394: [CodeGen] Support generation of TBAA info in the new format
kosarev updated this revision to Diff 127838. kosarev added a comment. Updated as suggested. https://reviews.llvm.org/D41394 Files: lib/CodeGen/CodeGenTBAA.cpp test/CodeGen/tbaa.cpp Index: test/CodeGen/tbaa.cpp === --- test/CodeGen/tbaa.cpp +++ test/CodeGen/tbaa.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=PATH,OLD-PATH +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -new-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=PATH,NEW-PATH // RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA // Test TBAA metadata generated by front-end. @@ -248,29 +249,57 @@ // CHECK: [[TYPE_i16]] = !{!"short", [[TYPE_char]], // CHECK: [[TAG_char]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} -// PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", ! -// PATH: [[TAG_i32]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0} -// PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]] -// PATH: [[TAG_A_f32]] = !{[[TYPE_A:!.*]], [[TYPE_INT]], i64 4} -// PATH: [[TYPE_A]] = !{!"_ZTS7StructA", [[TYPE_SHORT:!.*]], i64 0, [[TYPE_INT]], i64 4, [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12} -// PATH: [[TYPE_SHORT:!.*]] = !{!"short", [[TYPE_CHAR]] -// PATH: [[TAG_A_f16]] = !{[[TYPE_A]], [[TYPE_SHORT]], i64 0} -// PATH: [[TAG_B_a_f32]] = !{[[TYPE_B:!.*]], [[TYPE_INT]], i64 8} -// PATH: [[TYPE_B]] = !{!"_ZTS7StructB", [[TYPE_SHORT]], i64 0, [[TYPE_A]], i64 4, [[TYPE_INT]], i64 20} -// PATH: [[TAG_B_a_f16]] = !{[[TYPE_B]], [[TYPE_SHORT]], i64 4} -// PATH: [[TAG_B_f32]] = !{[[TYPE_B]], [[TYPE_INT]], i64 20} -// PATH: [[TAG_B_a_f32_2]] = !{[[TYPE_B]], [[TYPE_INT]], i64 16} -// PATH: [[TAG_S_f32]] = !{[[TYPE_S:!.*]], [[TYPE_INT]], i64 4} -// PATH: [[TYPE_S]] = !{!"_ZTS7StructS", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4} -// PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0} -// PATH: [[TAG_S2_f32]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 4} -// PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4} -// PATH: [[TAG_S2_f16]] = !{[[TYPE_S2]], [[TYPE_SHORT]], i64 0} -// PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12} -// PATH: [[TYPE_C]] = !{!"_ZTS7StructC", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28} -// PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12} -// PATH: [[TYPE_D]] = !{!"_ZTS7StructD", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28, [[TYPE_CHAR]], i64 32} -// PATH: [[TAG_five_b]] = !{[[TYPE_five:!.*]], [[TYPE_CHAR]], i64 1} -// PATH: [[TYPE_five]] = !{!"_ZTS4five", [[TYPE_CHAR]], i64 0, [[TYPE_INT]], i64 1, [[TYPE_CHAR]], i64 1, [[TYPE_CHAR]], i64 2} -// PATH: [[TAG_six_b]] = !{[[TYPE_six:!.*]], [[TYPE_CHAR]], i64 4} -// PATH: [[TYPE_six]] = !{!"_ZTS3six", [[TYPE_CHAR]], i64 0, [[TYPE_INT]], i64 4, [[TYPE_CHAR]], i64 4, [[TYPE_CHAR]], i64 5} +// OLD-PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", ! +// OLD-PATH: [[TAG_i32]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0} +// OLD-PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]] +// OLD-PATH: [[TAG_A_f32]] = !{[[TYPE_A:!.*]], [[TYPE_INT]], i64 4} +// OLD-PATH: [[TYPE_A]] = !{!"_ZTS7StructA", [[TYPE_SHORT:!.*]], i64 0, [[TYPE_INT]], i64 4, [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12} +// OLD-PATH: [[TYPE_SHORT:!.*]] = !{!"short", [[TYPE_CHAR]] +// OLD-PATH: [[TAG_A_f16]] = !{[[TYPE_A]], [[TYPE_SHORT]], i64 0} +// OLD-PATH: [[TAG_B_a_f32]] = !{[[TYPE_B:!.*]], [[TYPE_INT]], i64 8} +// OLD-PATH: [[TYPE_B]] = !{!"_ZTS7StructB", [[TYPE_SHORT]], i64 0, [[TYPE_A]], i64 4, [[TYPE_INT]], i64 20} +// OLD-PATH: [[TAG_B_a_f16]] = !{[[TYPE_B]], [[TYPE_SHORT]], i64 4} +// OLD-PATH: [[TAG_B_f32]] = !{[[TYPE_B]], [[TYPE_INT]], i64 20} +// OLD-PATH: [[TAG_B_a_f32_2]] = !{[[TYPE_B]], [[TYPE_INT]], i64 16} +// OLD-PATH: [[TAG_S_f32]] = !{[[TYPE_S:!.*]], [[TYPE_INT]], i64 4} +// OLD-PATH: [[TYPE_S]] = !{!"_ZTS7StructS", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4} +// OLD-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0} +// OLD-PATH: [[TAG_S2_f32]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 4} +// OLD-PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4} +// OLD-PATH: [[TAG_S2_f16]] = !{[[TYPE_S2]], [[TYPE_SHORT]], i64 0} +// OLD-PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12} +// OLD-PATH: [[TYPE_C]] = !{!"_ZTS7StructC", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28} +// OLD-PATH: [[TAG_D_b_a_f
[PATCH] D41394: [CodeGen] Support generation of TBAA info in the new format
This revision was automatically updated to reflect the committed changes. Closed by commit rL321351: [CodeGen] Support generation of TBAA info in the new format (authored by kosarev, committed by ). Changed prior to commit: https://reviews.llvm.org/D41394?vs=127838&id=127993#toc Repository: rL LLVM https://reviews.llvm.org/D41394 Files: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp cfe/trunk/test/CodeGen/tbaa.cpp Index: cfe/trunk/test/CodeGen/tbaa.cpp === --- cfe/trunk/test/CodeGen/tbaa.cpp +++ cfe/trunk/test/CodeGen/tbaa.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=PATH,OLD-PATH +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -new-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=PATH,NEW-PATH // RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA // Test TBAA metadata generated by front-end. @@ -248,29 +249,57 @@ // CHECK: [[TYPE_i16]] = !{!"short", [[TYPE_char]], // CHECK: [[TAG_char]] = !{[[TYPE_char]], [[TYPE_char]], i64 0} -// PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", ! -// PATH: [[TAG_i32]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0} -// PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]] -// PATH: [[TAG_A_f32]] = !{[[TYPE_A:!.*]], [[TYPE_INT]], i64 4} -// PATH: [[TYPE_A]] = !{!"_ZTS7StructA", [[TYPE_SHORT:!.*]], i64 0, [[TYPE_INT]], i64 4, [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12} -// PATH: [[TYPE_SHORT:!.*]] = !{!"short", [[TYPE_CHAR]] -// PATH: [[TAG_A_f16]] = !{[[TYPE_A]], [[TYPE_SHORT]], i64 0} -// PATH: [[TAG_B_a_f32]] = !{[[TYPE_B:!.*]], [[TYPE_INT]], i64 8} -// PATH: [[TYPE_B]] = !{!"_ZTS7StructB", [[TYPE_SHORT]], i64 0, [[TYPE_A]], i64 4, [[TYPE_INT]], i64 20} -// PATH: [[TAG_B_a_f16]] = !{[[TYPE_B]], [[TYPE_SHORT]], i64 4} -// PATH: [[TAG_B_f32]] = !{[[TYPE_B]], [[TYPE_INT]], i64 20} -// PATH: [[TAG_B_a_f32_2]] = !{[[TYPE_B]], [[TYPE_INT]], i64 16} -// PATH: [[TAG_S_f32]] = !{[[TYPE_S:!.*]], [[TYPE_INT]], i64 4} -// PATH: [[TYPE_S]] = !{!"_ZTS7StructS", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4} -// PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0} -// PATH: [[TAG_S2_f32]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 4} -// PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4} -// PATH: [[TAG_S2_f16]] = !{[[TYPE_S2]], [[TYPE_SHORT]], i64 0} -// PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12} -// PATH: [[TYPE_C]] = !{!"_ZTS7StructC", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28} -// PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12} -// PATH: [[TYPE_D]] = !{!"_ZTS7StructD", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28, [[TYPE_CHAR]], i64 32} -// PATH: [[TAG_five_b]] = !{[[TYPE_five:!.*]], [[TYPE_CHAR]], i64 1} -// PATH: [[TYPE_five]] = !{!"_ZTS4five", [[TYPE_CHAR]], i64 0, [[TYPE_INT]], i64 1, [[TYPE_CHAR]], i64 1, [[TYPE_CHAR]], i64 2} -// PATH: [[TAG_six_b]] = !{[[TYPE_six:!.*]], [[TYPE_CHAR]], i64 4} -// PATH: [[TYPE_six]] = !{!"_ZTS3six", [[TYPE_CHAR]], i64 0, [[TYPE_INT]], i64 4, [[TYPE_CHAR]], i64 4, [[TYPE_CHAR]], i64 5} +// OLD-PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", ! +// OLD-PATH: [[TAG_i32]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0} +// OLD-PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]] +// OLD-PATH: [[TAG_A_f32]] = !{[[TYPE_A:!.*]], [[TYPE_INT]], i64 4} +// OLD-PATH: [[TYPE_A]] = !{!"_ZTS7StructA", [[TYPE_SHORT:!.*]], i64 0, [[TYPE_INT]], i64 4, [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12} +// OLD-PATH: [[TYPE_SHORT:!.*]] = !{!"short", [[TYPE_CHAR]] +// OLD-PATH: [[TAG_A_f16]] = !{[[TYPE_A]], [[TYPE_SHORT]], i64 0} +// OLD-PATH: [[TAG_B_a_f32]] = !{[[TYPE_B:!.*]], [[TYPE_INT]], i64 8} +// OLD-PATH: [[TYPE_B]] = !{!"_ZTS7StructB", [[TYPE_SHORT]], i64 0, [[TYPE_A]], i64 4, [[TYPE_INT]], i64 20} +// OLD-PATH: [[TAG_B_a_f16]] = !{[[TYPE_B]], [[TYPE_SHORT]], i64 4} +// OLD-PATH: [[TAG_B_f32]] = !{[[TYPE_B]], [[TYPE_INT]], i64 20} +// OLD-PATH: [[TAG_B_a_f32_2]] = !{[[TYPE_B]], [[TYPE_INT]], i64 16} +// OLD-PATH: [[TAG_S_f32]] = !{[[TYPE_S:!.*]], [[TYPE_INT]], i64 4} +// OLD-PATH: [[TYPE_S]] = !{!"_ZTS7StructS", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4} +// OLD-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0} +// OLD-PATH: [[TAG_S2_f32]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 4} +// OLD-PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4} +// OLD-PATH: [[TA
[PATCH] D41399: [CodeGen] Represent array members in new-format TBAA type descriptors
This revision was automatically updated to reflect the committed changes. Closed by commit rL321352: [CodeGen] Represent array members in new-format TBAA type descriptors (authored by kosarev, committed by ). Changed prior to commit: https://reviews.llvm.org/D41399?vs=127742&id=127994#toc Repository: rL LLVM https://reviews.llvm.org/D41399 Files: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp cfe/trunk/test/CodeGen/tbaa-array.cpp Index: cfe/trunk/test/CodeGen/tbaa-array.cpp === --- cfe/trunk/test/CodeGen/tbaa-array.cpp +++ cfe/trunk/test/CodeGen/tbaa-array.cpp @@ -1,18 +1,52 @@ // RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ // RUN: -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -new-struct-path-tbaa -emit-llvm -o - | \ +// RUN: FileCheck -check-prefix=CHECK-NEW %s // // Check that we generate correct TBAA information for accesses to array // elements. struct A { int i; }; struct B { A a[1]; }; +struct C { int i; int x[3]; }; int foo(B *b) { // CHECK-LABEL: _Z3fooP1B // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] +// CHECK-NEW-LABEL: _Z3fooP1B +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] return b->a->i; } +// Check that members of array types are represented correctly. +int bar(C *c) { +// CHECK-NEW-LABEL: _Z3barP1C +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_C_i:!.*]] + return c->i; +} + +int bar2(C *c) { +// CHECK-NEW-LABEL: _Z4bar2P1C +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]] + return c->x[2]; +} + +int bar3(C *c, int j) { +// CHECK-NEW-LABEL: _Z4bar3P1Ci +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]] + return c->x[j]; +} + // CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} // CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} // CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} + +// CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} +// CHECK-NEW-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"} +// CHECK-NEW-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0, i64 4} +// CHECK-NEW-DAG: [[TYPE_pointer:!.*]] = !{[[TYPE_char]], i64 8, !"any pointer"} +// CHECK-NEW-DAG: [[TYPE_A:!.*]] = !{[[TYPE_char]], i64 4, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4} +// CHECK-NEW-DAG: [[TAG_A_i]] = !{[[TYPE_A]], [[TYPE_int]], i64 0, i64 4} +// CHECK-NEW-DAG: [[TYPE_C:!.*]] = !{[[TYPE_char]], i64 16, !"_ZTS1C", [[TYPE_int]], i64 0, i64 4, [[TYPE_int]], i64 4, i64 12} +// CHECK-NEW-DAG: [[TAG_C_i]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 0, i64 4} Index: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp === --- cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp @@ -161,6 +161,10 @@ if (Ty->isPointerType() || Ty->isReferenceType()) return createScalarTypeNode("any pointer", getChar(), Size); + // Accesses to arrays are accesses to objects of their element types. + if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType()) +return getTypeInfo(cast(Ty)->getElementType()); + // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. if (const EnumType *ETy = dyn_cast(Ty)) { Index: cfe/trunk/test/CodeGen/tbaa-array.cpp === --- cfe/trunk/test/CodeGen/tbaa-array.cpp +++ cfe/trunk/test/CodeGen/tbaa-array.cpp @@ -1,18 +1,52 @@ // RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ // RUN: -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \ +// RUN: -new-struct-path-tbaa -emit-llvm -o - | \ +// RUN: FileCheck -check-prefix=CHECK-NEW %s // // Check that we generate correct TBAA information for accesses to array // elements. struct A { int i; }; struct B { A a[1]; }; +struct C { int i; int x[3]; }; int foo(B *b) { // CHECK-LABEL: _Z3fooP1B // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] +// CHECK-NEW-LABEL: _Z3fooP1B +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]] return b->a->i; } +// Check that members of array types are represented correctly. +int bar(C *c) { +// CHECK-NEW-LABEL: _Z3barP1C +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_C_i:!.*]] + return c->i; +} + +int bar2(C *c) { +// CHECK-NEW-LABEL: _Z4bar2P1C +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]] + return c->x[2]; +} + +int bar3(C *c, int j) { +// CHECK-NEW-LABEL: _Z4bar3P1Ci +// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]] + return c->x[j]; +} + // CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0} // CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0} // CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0} + +// CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} +// CHECK-NEW-DAG: [[TYPE_int:!.*]] = !{[[TYP
[PATCH] D41539: [CodeGen] Decorate aggregate accesses with TBAA tags
kosarev created this revision. kosarev added reviewers: rjmccall, hfinkel. kosarev added a project: clang. Repository: rL LLVM https://reviews.llvm.org/D41539 Files: lib/CodeGen/CGExprAgg.cpp test/CodeGen/tbaa-struct-new.cpp Index: test/CodeGen/tbaa-struct-new.cpp === --- test/CodeGen/tbaa-struct-new.cpp +++ test/CodeGen/tbaa-struct-new.cpp @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -new-struct-path-tbaa \ +// RUN: -emit-llvm -o - -O1 %s | FileCheck %s +// +// Check that we generate TBAA metadata for struct copies correctly. + +struct A { + short s; + int i; + char c; + int j; +}; + +void copy(A *a1, A *a2) { +// CHECK-LABEL: _Z4copyP1AS0_ +// CHECK: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_A:![0-9]*]] + *a1 = *a2; +} + +struct B { + char c; + A a; + int i; +}; + +void copy2(B *b1, B *b2) { +// CHECK-LABEL: _Z5copy2P1BS0_ +// CHECK: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_B:![0-9]*]] + *b1 = *b2; +} + +struct S { + _Complex char cc; + _Complex int ci; +}; + +union U { + _Complex int ci; + S s; +}; + +void copy3(U *u1, U *u2) { +// CHECK-LABEL: _Z5copy3P1US0_ +// CHECK: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_U:![0-9]*]] + *u1 = *u2; +} + +// Make sure that zero-length bitfield works. +struct C { + char a; + int : 0; // Shall not be ignored; see r185018. + char b; + char c; +} __attribute__((ms_struct)); + +void copy4(C *c1, C *c2) { +// CHECK-LABEL: _Z5copy4P1CS0_ +// CHECK: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_C:![0-9]*]] + *c1 = *c2; +} + +struct D { + char a; + int : 0; + char b; + char c; +}; + +void copy5(D *d1, D *d2) { +// CHECK-LABEL: _Z5copy5P1DS0_ +// CHECK: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_D:![0-9]*]] + *d1 = *d2; +} + +// CHECK-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} +// CHECK-DAG: [[TYPE_short:!.*]] = !{[[TYPE_char]], i64 2, !"short"} +// CHECK-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"} +// CHECK-DAG: [[TYPE_A:!.*]] = !{[[TYPE_char]], i64 16, !"_ZTS1A", [[TYPE_short]], i64 0, i64 2, [[TYPE_int]], i64 4, i64 4, [[TYPE_char]], i64 8, i64 1, [[TYPE_int]], i64 12, i64 4} +// CHECK-DAG: [[TAG_A]] = !{[[TYPE_A]], [[TYPE_A]], i64 0, i64 16} +// CHECK-DAG: [[TYPE_B:!.*]] = !{[[TYPE_char]], i64 24, !"_ZTS1B", [[TYPE_char]], i64 0, i64 1, [[TYPE_A]], i64 4, i64 16, [[TYPE_int]], i64 20, i64 4} +// CHECK-DAG: [[TAG_B]] = !{[[TYPE_B]], [[TYPE_B]], i64 0, i64 24} +// CHECK-DAG: [[TAG_U]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 12} +// CHECK-DAG: [[TYPE_C:!.*]] = !{[[TYPE_char]], i64 3, !"_ZTS1C", [[TYPE_char]], i64 0, i64 1, [[TYPE_int]], i64 1, i64 4, [[TYPE_char]], i64 1, i64 1, [[TYPE_char]], i64 2, i64 1} +// CHECK-DAG: [[TAG_C]] = !{[[TYPE_C]], [[TYPE_C]], i64 0, i64 3} +// CHECK-DAG: [[TYPE_D:!.*]] = !{[[TYPE_char]], i64 6, !"_ZTS1D", [[TYPE_char]], i64 0, i64 1, [[TYPE_int]], i64 4, i64 4, [[TYPE_char]], i64 4, i64 1, [[TYPE_char]], i64 5, i64 1} +// CHECK-DAG: [[TAG_D]] = !{[[TYPE_D]], [[TYPE_D]], i64 0, i64 6} Index: lib/CodeGen/CGExprAgg.cpp === --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -1657,4 +1657,7 @@ // the optimizer wishes to expand it in to scalar memory operations. if (llvm::MDNode *TBAAStructTag = CGM.getTBAAStructInfo(Ty)) Inst->setMetadata(llvm::LLVMContext::MD_tbaa_struct, TBAAStructTag); + + if (CGM.getCodeGenOpts().NewStructPathTBAA) +CGM.DecorateInstructionWithTBAA(Inst, CGM.getTBAAAccessInfo(Ty)); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41539: [CodeGen] Decorate aggregate accesses with TBAA tags
kosarev updated this revision to Diff 128017. kosarev added a comment. Reworked to not add another test file. https://reviews.llvm.org/D41539 Files: lib/CodeGen/CGExprAgg.cpp test/CodeGen/tbaa-struct.cpp Index: test/CodeGen/tbaa-struct.cpp === --- test/CodeGen/tbaa-struct.cpp +++ test/CodeGen/tbaa-struct.cpp @@ -1,75 +1,105 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - -O1 %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - -O1 %s | \ +// RUN: FileCheck -check-prefixes=CHECK,CHECK-OLD %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -new-struct-path-tbaa \ +// RUN: -emit-llvm -o - -O1 %s | \ +// RUN: FileCheck -check-prefixes=CHECK,CHECK-NEW %s // -// Check that we generate !tbaa.struct metadata for struct copies. +// Check that we generate TBAA metadata for struct copies correctly. + struct A { short s; int i; char c; int j; }; -void copy(struct A *a, struct A *b) { - *a = *b; +void copy(A *a1, A *a2) { +// CHECK-LABEL: _Z4copyP1AS0_ +// CHECK-OLD: call void @llvm.memcpy{{.*}}, !tbaa.struct [[TS:!.*]] +// CHECK-NEW: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_A:![0-9]*]] + *a1 = *a2; } -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 16, i32 4, i1 false), !tbaa.struct [[TS:!.*]] - struct B { - char c1; - struct A a; - int ii; + char c; + A a; + int i; }; -void copy2(struct B *a, struct B *b) { - *a = *b; +void copy2(B *b1, B *b2) { +// CHECK-LABEL: _Z5copy2P1BS0_ +// CHECK-OLD: call void @llvm.memcpy{{.*}}, !tbaa.struct [[TS2:!.*]] +// CHECK-NEW: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_B:![0-9]*]] + *b1 = *b2; } -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 24, i32 4, i1 false), !tbaa.struct [[TS2:!.*]] +struct S { + _Complex char cc; + _Complex int ci; +}; -typedef _Complex int T2; -typedef _Complex char T5; -typedef _Complex int T7; -typedef struct T4 { T5 field0; T7 field1; } T4; -typedef union T1 { T2 field0; T4 field1; } T1; +union U { + _Complex int ci; + S s; +}; -void copy3 (T1 *a, T1 *b) { - *a = *b; +void copy3(U *u1, U *u2) { +// CHECK-LABEL: _Z5copy3P1US0_ +// CHECK-OLD: call void @llvm.memcpy{{.*}}, !tbaa.struct [[TS3:!.*]] +// CHECK-NEW: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_U:![0-9]*]] + *u1 = *u2; } -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 12, i32 4, i1 false), !tbaa.struct [[TS3:!.*]] - // Make sure that zero-length bitfield works. -#define ATTR __attribute__ ((ms_struct)) -struct five { +struct C { char a; - int :0;/* ignored; prior field is not a bitfield. */ + int : 0; // Shall not be ignored; see r185018. char b; char c; -} ATTR; -void copy4(struct five *a, struct five *b) { - *a = *b; +} __attribute__((ms_struct)); + +void copy4(C *c1, C *c2) { +// CHECK-LABEL: _Z5copy4P1CS0_ +// CHECK-OLD: call void @llvm.memcpy{{.*}}, !tbaa.struct [[TS4:!.*]] +// CHECK-NEW: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_C:![0-9]*]] + *c1 = *c2; } -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 3, i32 1, i1 false), !tbaa.struct [[TS4:!.*]] -struct six { +struct D { char a; - int :0; + int : 0; char b; char c; }; -void copy5(struct six *a, struct six *b) { - *a = *b; + +void copy5(D *d1, D *d2) { +// CHECK-LABEL: _Z5copy5P1DS0_ +// CHECK-OLD: call void @llvm.memcpy{{.*}}, !tbaa.struct [[TS5:!.*]] +// CHECK-NEW: call void @llvm.memcpy{{.*}}, !tbaa [[TAG_D:![0-9]*]] + *d1 = *d2; } -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 6, i32 1, i1 false), !tbaa.struct [[TS5:!.*]] -// CHECK: [[TS]] = !{i64 0, i64 2, !{{.*}}, i64 4, i64 4, !{{.*}}, i64 8, i64 1, !{{.*}}, i64 12, i64 4, !{{.*}}} -// CHECK: [[CHAR:!.*]] = !{!"omnipotent char", !{{.*}}} -// CHECK: [[TAG_INT:!.*]] = !{[[INT:!.*]], [[INT]], i64 0} -// CHECK: [[INT]] = !{!"int", [[CHAR]] -// CHECK: [[TAG_CHAR:!.*]] = !{[[CHAR]], [[CHAR]], i64 0} +// CHECK-OLD: [[TS]] = !{i64 0, i64 2, !{{.*}}, i64 4, i64 4, !{{.*}}, i64 8, i64 1, !{{.*}}, i64 12, i64 4, !{{.*}}} +// CHECK-OLD: [[CHAR:!.*]] = !{!"omnipotent char", !{{.*}}} +// CHECK-OLD: [[TAG_INT:!.*]] = !{[[INT:!.*]], [[INT]], i64 0} +// CHECK-OLD: [[INT]] = !{!"int", [[CHAR]] +// CHECK-OLD: [[TAG_CHAR:!.*]] = !{[[CHAR]], [[CHAR]], i64 0} // (offset, size) = (0,1) char; (4,2) short; (8,4) int; (12,1) char; (16,4) int; (20,4) int -// CHECK: [[TS2]] = !{i64 0, i64 1, !{{.*}}, i64 4, i64 2, !{{.*}}, i64 8, i64 4, !{{.*}}, i64 12, i64 1, !{{.*}}, i64 16, i64 4, {{.*}}, i64 20, i64 4, {{.*}}} +// CHECK-OLD: [[TS2]] = !{i64 0, i64 1, !{{.*}}, i64 4, i64 2, !{{.*}}, i64 8, i64 4, !{{.*}}, i64 12, i64 1, !{{.*}}, i64 16, i64 4, {{.*}}, i64 20, i64 4, {{.*}}} // (offset, size) = (0,8) char; (0,2) char; (4,8) char -// CHECK: [[TS3]] = !{i64 0, i64 8, !{{.*}}, i64 0, i64 2, !{{.*}}, i64 4, i64 8, !{{.*}}} -// CHECK: [[TS4]] = !
[PATCH] D41547: [CodeGen] Fix TBAA info for accesses to members of base classes
kosarev created this revision. kosarev added reviewers: rjmccall, hfinkel. kosarev added a project: clang. Resolves: Bug 35724 - regression (r315984): fatal error: error in backend: Broken function found (Did not see access type in access path!) https://bugs.llvm.org/show_bug.cgi?id=35724 Repository: rL LLVM https://reviews.llvm.org/D41547 Files: lib/CodeGen/CGExpr.cpp test/CodeGen/tbaa-base.cpp Index: test/CodeGen/tbaa-base.cpp === --- test/CodeGen/tbaa-base.cpp +++ test/CodeGen/tbaa-base.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -emit-llvm -o - | FileCheck %s +// +// Test generating of TBAA metadata for accesses to members of base classes. + +struct A { + int x, y, z; +}; + +struct B : A { + int i; +}; + +struct C { + int i; + B b; + int j; +}; + +int f1(B *b) { +// CHECK-LABEL: _Z2f1P1B +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y:!.*]] + return b->y; +} + +int f2(C *c) { +// CHECK-LABEL: _Z2f2P1C +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return (&(c->b))->y; +} + +struct D : virtual A +{}; + +struct E { + D d; +}; + +int f3(D *d) { +// CHECK-LABEL: _Z2f3P1D +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return d->y; +} + +int f4(E *e) { +// CHECK-LABEL: _Z2f4P1E +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return (&(e->d))->y; +} + +// CHECK-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", {{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0} +// CHECK-DAG: [[TYPE_A:!.*]] = !{!"_ZTS1A", [[TYPE_int]], i64 0, [[TYPE_int]], i64 4, [[TYPE_int]], i64 8} +// CHECK-DAG: [[TAG_A_y]] = !{[[TYPE_A]], [[TYPE_int]], i64 4} Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1034,8 +1034,12 @@ // Derived-to-base conversions. case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { - Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo, - TBAAInfo); + // TODO: Support accesses to members of base classes in TBAA. For now, we + // conservatively pretend that the complete object is of the base class + // type. + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(E->getType()); + Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo); auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl(); return GetAddressOfBaseClass(Addr, Derived, CE->path_begin(), CE->path_end(), Index: test/CodeGen/tbaa-base.cpp === --- test/CodeGen/tbaa-base.cpp +++ test/CodeGen/tbaa-base.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -emit-llvm -o - | FileCheck %s +// +// Test generating of TBAA metadata for accesses to members of base classes. + +struct A { + int x, y, z; +}; + +struct B : A { + int i; +}; + +struct C { + int i; + B b; + int j; +}; + +int f1(B *b) { +// CHECK-LABEL: _Z2f1P1B +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y:!.*]] + return b->y; +} + +int f2(C *c) { +// CHECK-LABEL: _Z2f2P1C +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return (&(c->b))->y; +} + +struct D : virtual A +{}; + +struct E { + D d; +}; + +int f3(D *d) { +// CHECK-LABEL: _Z2f3P1D +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return d->y; +} + +int f4(E *e) { +// CHECK-LABEL: _Z2f4P1E +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return (&(e->d))->y; +} + +// CHECK-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", {{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0} +// CHECK-DAG: [[TYPE_A:!.*]] = !{!"_ZTS1A", [[TYPE_int]], i64 0, [[TYPE_int]], i64 4, [[TYPE_int]], i64 8} +// CHECK-DAG: [[TAG_A_y]] = !{[[TYPE_A]], [[TYPE_int]], i64 4} Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1034,8 +1034,12 @@ // Derived-to-base conversions. case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { - Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo, - TBAAInfo); + // TODO: Support accesses to members of base classes in TBAA. For now, we + // conservatively pretend that the complete object is of the base class + // type. + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(E->getType()); + Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo); auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl(); return GetAddressOfBaseClass(Addr, Derived, CE->path_begin(), CE->path_end(), ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bi
[PATCH] D41562: [CodeGen] Generate TBAA info on passing arguments and returning values
kosarev created this revision. kosarev added reviewers: rjmccall, hfinkel. kosarev added a project: clang. We only do this for the new format as the old format does not allow to represent accesses to aggregates. This patch significantly improves TBAA coverage on -O1 builds. Repository: rL LLVM https://reviews.llvm.org/D41562 Files: lib/CodeGen/CGCall.cpp test/CodeGen/tbaa-call.cpp Index: test/CodeGen/tbaa-call.cpp === --- test/CodeGen/tbaa-call.cpp +++ test/CodeGen/tbaa-call.cpp @@ -0,0 +1,110 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes \ +// RUN: -new-struct-path-tbaa %s -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for instructions that pass +// function arguments and returning values. + +struct A { int : 0; }; +struct B { double d; }; +struct C { A a; B b; }; +struct D { int i; }; +struct E { double d; int i; }; +struct F { float _Complex c; int x; }; +struct G { E e; }; + +B get_B(); +C get_C(); +D get_D(); +E get_E(); +F get_F(); + +void set_E(E); + +C f1() { +// CHECK-LABEL: _Z2f1v +// CHECK: load double, {{.*}}, !tbaa [[TAG_C:!.*]] + return C(); +} + +D f2() { +// CHECK-LABEL: _Z2f2v +// CHECK: load i32, {{.*}}, !tbaa [[TAG_D:!.*]] + return D(); +} + +E f3() { +// CHECK-LABEL: _Z2f3v +// CHECK: load { double, i32 }, {{.*}}, !tbaa [[TAG_E:!.*]] + return E(); +} + +E f4() { +// CHECK-LABEL: _Z2f4v +// CHECK: call { double, i32 } @_Z5get_Ev() +// CHECK-DAG: store double {{.*}}, !tbaa [[TAG_E]] +// CHECK-DAG: store i32 {{.*}}, !tbaa [[TAG_E]] +// CHECK: load { double, i32 }, {{.*}}, !tbaa [[TAG_E]] + return get_E(); +} + +B f5() { +// CHECK-LABEL: _Z2f5v +// CHECK: call double @_Z5get_Bv() +// CHECK: store double {{.*}}, !tbaa [[TAG_B:!.*]] +// CHECK: load double, {{.*}}, !tbaa [[TAG_B]] + return get_B(); +} + +C f6() { +// CHECK-LABEL: _Z2f6v +// CHECK: call double @_Z5get_Cv() +// CHECK: store double {{.*}}, !tbaa [[TAG_C]] +// CHECK: load double, {{.*}}, !tbaa [[TAG_C]] + return get_C(); +} + +D f7() { +// CHECK-LABEL: _Z2f7v +// CHECK: call i32 @_Z5get_Dv() +// CHECK: store i32 {{.*}}, !tbaa [[TAG_D]] +// CHECK: load i32, {{.*}}, !tbaa [[TAG_D]] + return get_D(); +} + +F f8() { +// CHECK-LABEL: _Z2f8v +// CHECK: call { <2 x float>, i32 } @_Z5get_Fv() +// CHECK: store { <2 x float>, i32 } {{.*}}, !tbaa [[TAG_F:!.*]] +// CHECK: load { <2 x float>, i32 }, {{.*}}, !tbaa [[TAG_F]] + return get_F(); +} + +G f9(G g) { +// CHECK-LABEL: _Z2f91G +// CHECK-DAG: store double {{.*}}, !tbaa [[TAG_G:!.*]] +// CHECK-DAG: store i32 {{.*}}, !tbaa [[TAG_G]] +// CHECK: load { double, i32 }, {{.*}}, !tbaa [[TAG_G]] + return g; +} + +void f10() { +// CHECK-LABEL: _Z3f10v +// CHECK-DAG: load double, {{.*}}, !tbaa [[TAG_E]] +// CHECK-DAG: load i32, {{.*}}, !tbaa [[TAG_E]] +// CHECK: call void @_Z5set_E1E + E e; + set_E(e); +} + +// CHECK-DAG: [[TYPE_B:!.*]] = !{{{.*}}, !"_ZTS1B", {{.*}}} +// CHECK-DAG: [[TAG_B]] = !{[[TYPE_B]], [[TYPE_B]], {{.*}}} +// CHECK-DAG: [[TYPE_C:!.*]] = !{{{.*}}, !"_ZTS1C", {{.*}}} +// CHECK-DAG: [[TAG_C]] = !{[[TYPE_C]], [[TYPE_C]], {{.*}}} +// CHECK-DAG: [[TYPE_D:!.*]] = !{{{.*}}, !"_ZTS1D", {{.*}}} +// CHECK-DAG: [[TAG_D]] = !{[[TYPE_D]], [[TYPE_D]], {{.*}}} +// CHECK-DAG: [[TYPE_E:!.*]] = !{{{.*}}, !"_ZTS1E", {{.*}}} +// CHECK-DAG: [[TAG_E]] = !{[[TYPE_E]], [[TYPE_E]], {{.*}}} +// CHECK-DAG: [[TYPE_F:!.*]] = !{{{.*}}, !"_ZTS1F", {{.*}}} +// CHECK-DAG: [[TAG_F]] = !{[[TYPE_F]], [[TYPE_F]], {{.*}}} +// CHECK-DAG: [[TYPE_G:!.*]] = !{{{.*}}, !"_ZTS1G", {{.*}}} +// CHECK-DAG: [[TAG_G]] = !{[[TYPE_G]], [[TYPE_G]], {{.*}}} Index: lib/CodeGen/CGCall.cpp === --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1195,12 +1195,16 @@ /// destination type; in this situation the values of bits which not /// present in the src are undefined. static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty, + TBAAAccessInfo TBAAInfo, CodeGenFunction &CGF) { llvm::Type *SrcTy = Src.getElementType(); // If SrcTy and Ty are the same, just do a load. - if (SrcTy == Ty) -return CGF.Builder.CreateLoad(Src); + if (SrcTy == Ty) { +auto *Load = CGF.Builder.CreateLoad(Src); +CGF.CGM.DecorateInstructionWithTBAA(Load, TBAAInfo); +return Load; + } uint64_t DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(Ty); @@ -1215,7 +1219,8 @@ // extension or truncation to the desired type. if ((isa(Ty) || isa(Ty)) && (isa(SrcTy) || isa(SrcTy))) { -llvm::Value *Load = CGF.Builder.CreateLoad(Src); +auto *Load = CGF.Builder.CreateLoad(Src); +CGF.CGM.DecorateInstructionWithTBAA(Load, TBAAInfo); return CoerceIntOrPtrToIntOrPtr(Load, Ty, CGF); } @@ -1229,7 +1234,9 @@ // to that information. Src = CGF.Builder.CreateBitCast(Src,
[PATCH] D41539: [CodeGen] Decorate aggregate accesses with TBAA tags
kosarev added a comment. Sure, but since it is not a trivial change we could first replace 'tbaa.struct' with 'tbaa' and then decide how to attach multiple TBAA tags to an instruction. I didn't think enough about it, but one way to do that is to have different kinds of TBAA tags for read and write accesses, in which case we could re-purpose the 'tbaa.struct' tag slot. https://reviews.llvm.org/D41539 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41547: [CodeGen] Fix TBAA info for accesses to members of base classes
This revision was automatically updated to reflect the committed changes. Closed by commit rC321999: [CodeGen] Fix TBAA info for accesses to members of base classes (authored by kosarev, committed by ). Repository: rC Clang https://reviews.llvm.org/D41547 Files: lib/CodeGen/CGExpr.cpp test/CodeGen/tbaa-base.cpp Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1034,8 +1034,12 @@ // Derived-to-base conversions. case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { - Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo, - TBAAInfo); + // TODO: Support accesses to members of base classes in TBAA. For now, we + // conservatively pretend that the complete object is of the base class + // type. + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(E->getType()); + Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo); auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl(); return GetAddressOfBaseClass(Addr, Derived, CE->path_begin(), CE->path_end(), Index: test/CodeGen/tbaa-base.cpp === --- test/CodeGen/tbaa-base.cpp +++ test/CodeGen/tbaa-base.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -emit-llvm -o - | FileCheck %s +// +// Test generating of TBAA metadata for accesses to members of base classes. + +struct A { + int x, y, z; +}; + +struct B : A { + int i; +}; + +struct C { + int i; + B b; + int j; +}; + +int f1(B *b) { +// CHECK-LABEL: _Z2f1P1B +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y:!.*]] + return b->y; +} + +int f2(C *c) { +// CHECK-LABEL: _Z2f2P1C +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return (&(c->b))->y; +} + +struct D : virtual A +{}; + +struct E { + D d; +}; + +int f3(D *d) { +// CHECK-LABEL: _Z2f3P1D +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return d->y; +} + +int f4(E *e) { +// CHECK-LABEL: _Z2f4P1E +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return (&(e->d))->y; +} + +// CHECK-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", {{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0} +// CHECK-DAG: [[TYPE_A:!.*]] = !{!"_ZTS1A", [[TYPE_int]], i64 0, [[TYPE_int]], i64 4, [[TYPE_int]], i64 8} +// CHECK-DAG: [[TAG_A_y]] = !{[[TYPE_A]], [[TYPE_int]], i64 4} Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1034,8 +1034,12 @@ // Derived-to-base conversions. case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { - Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo, - TBAAInfo); + // TODO: Support accesses to members of base classes in TBAA. For now, we + // conservatively pretend that the complete object is of the base class + // type. + if (TBAAInfo) +*TBAAInfo = CGM.getTBAAAccessInfo(E->getType()); + Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo); auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl(); return GetAddressOfBaseClass(Addr, Derived, CE->path_begin(), CE->path_end(), Index: test/CodeGen/tbaa-base.cpp === --- test/CodeGen/tbaa-base.cpp +++ test/CodeGen/tbaa-base.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -emit-llvm -o - | FileCheck %s +// +// Test generating of TBAA metadata for accesses to members of base classes. + +struct A { + int x, y, z; +}; + +struct B : A { + int i; +}; + +struct C { + int i; + B b; + int j; +}; + +int f1(B *b) { +// CHECK-LABEL: _Z2f1P1B +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y:!.*]] + return b->y; +} + +int f2(C *c) { +// CHECK-LABEL: _Z2f2P1C +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return (&(c->b))->y; +} + +struct D : virtual A +{}; + +struct E { + D d; +}; + +int f3(D *d) { +// CHECK-LABEL: _Z2f3P1D +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return d->y; +} + +int f4(E *e) { +// CHECK-LABEL: _Z2f4P1E +// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] + return (&(e->d))->y; +} + +// CHECK-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", {{.*}}, i64 0} +// CHECK-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0} +// CHECK-DAG: [[TYPE_A:!.*]] = !{!"_ZTS1A", [[TYPE_int]], i64 0, [[TYPE_int]], i64 4, [[TYPE_int]], i64 8} +// CHECK-DAG: [[TAG_A_y]] = !{[[TYPE_A]], [[TYPE_int]], i64 4} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41539: [CodeGen] Decorate aggregate accesses with TBAA tags
kosarev added a comment. OK, I'm reading your response so that this patch may significantly increase the number of cases where we propagate TBAA tags from memory-transfer intrinsic calls, which means potentially more cases where ignoring may_alias would lead to problems. If so, then I tend to agree. Will prepare another version. Thanks. https://reviews.llvm.org/D41539 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47121: [NEON] Support VLD1xN intrinsics in AArch32 mode (Clang part)
kosarev added a comment. Ping. https://reviews.llvm.org/D47121 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47121: [NEON] Support VLD1xN intrinsics in AArch32 mode (Clang part)
kosarev added a comment. Thanks for reviewing. Comment at: lib/CodeGen/CGBuiltin.cpp:7865 } // FIXME: Sharing loads & stores with 32-bit is complicated by the absence // of an Align parameter here. SjoerdMeijer wrote: > How about this FIXME? Is it still relevant? And does it need to be moved up? > Or perhaps better: move the code back here to minimise the diff? Yes, it's still true for the vst builtins handled below. None of the vld/vst patches removes this comment, but it should go away with whatever is the one to be committed last. Umm, it seems leaving the vld code here wouldn't make the diff smaller? Comment at: test/CodeGen/arm-neon-vld.c:4 +// RUN: FileCheck -check-prefixes=CHECK,CHECK-A64 %s +// RUN: %clang_cc1 -triple armv8-none-linux-gnueabi -target-feature +neon \ +// RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ SjoerdMeijer wrote: > Should this be armv7? There are more ARMv8 vld intrinsics that we currently support only in A64 so I was going to add tests for them here. I'm not sure if we want to test availability of NEON intrinsics for various architectures with codegen tests like this one or have some separate tests in sema. https://reviews.llvm.org/D47121 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47121: [NEON] Support VLD1xN intrinsics in AArch32 mode (Clang part)
This revision was automatically updated to reflect the committed changes. Closed by commit rL333819: [NEON] Support VLD1xN intrinsics in AArch32 mode (Clang part) (authored by kosarev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D47121?vs=147718&id=149612#toc Repository: rL LLVM https://reviews.llvm.org/D47121 Files: llvm/trunk/include/llvm/IR/IntrinsicsARM.td llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMInstrNEON.td llvm/trunk/test/CodeGen/ARM/arm-vld1.ll Index: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp === --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -1761,9 +1761,7 @@ case MVT::v4f32: case MVT::v4i32: OpcodeIndex = 2; break; case MVT::v2f64: - case MVT::v2i64: OpcodeIndex = 3; -assert(NumVecs == 1 && "v2i64 type only supported for VLD1"); -break; + case MVT::v2i64: OpcodeIndex = 3; break; } EVT ResTy; @@ -3441,6 +3439,51 @@ return; } +case Intrinsic::arm_neon_vld1x2: { + static const uint16_t DOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16, + ARM::VLD1q32, ARM::VLD1q64 }; + static const uint16_t QOpcodes[] = { ARM::VLD1d8QPseudo, + ARM::VLD1d16QPseudo, + ARM::VLD1d32QPseudo, + ARM::VLD1d64QPseudo }; + SelectVLD(N, false, 2, DOpcodes, QOpcodes, nullptr); + return; +} + +case Intrinsic::arm_neon_vld1x3: { + static const uint16_t DOpcodes[] = { ARM::VLD1d8TPseudo, + ARM::VLD1d16TPseudo, + ARM::VLD1d32TPseudo, + ARM::VLD1d64TPseudo }; + static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowTPseudo_UPD, +ARM::VLD1q16LowTPseudo_UPD, +ARM::VLD1q32LowTPseudo_UPD, +ARM::VLD1q64LowTPseudo_UPD }; + static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighTPseudo, +ARM::VLD1q16HighTPseudo, +ARM::VLD1q32HighTPseudo, +ARM::VLD1q64HighTPseudo }; + SelectVLD(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); + return; +} + +case Intrinsic::arm_neon_vld1x4: { + static const uint16_t DOpcodes[] = { ARM::VLD1d8QPseudo, + ARM::VLD1d16QPseudo, + ARM::VLD1d32QPseudo, + ARM::VLD1d64QPseudo }; + static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowQPseudo_UPD, +ARM::VLD1q16LowQPseudo_UPD, +ARM::VLD1q32LowQPseudo_UPD, +ARM::VLD1q64LowQPseudo_UPD }; + static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighQPseudo, +ARM::VLD1q16HighQPseudo, +ARM::VLD1q32HighQPseudo, +ARM::VLD1q64HighQPseudo }; + SelectVLD(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); + return; +} + case Intrinsic::arm_neon_vld2: { static const uint16_t DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16, ARM::VLD2d32, ARM::VLD1q64 }; Index: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp === --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp @@ -12763,6 +12763,9 @@ case ISD::INTRINSIC_W_CHAIN: switch (cast(N->getOperand(1))->getZExtValue()) { case Intrinsic::arm_neon_vld1: +case Intrinsic::arm_neon_vld1x2: +case Intrinsic::arm_neon_vld1x3: +case Intrinsic::arm_neon_vld1x4: case Intrinsic::arm_neon_vld2: case Intrinsic::arm_neon_vld3: case Intrinsic::arm_neon_vld4: @@ -14074,6 +14077,21 @@ Info.flags = MachineMemOperand::MOLoad; return true; } + case Intrinsic::arm_neon_vld1x2: + case Intrinsic::arm_neon_vld1x3: + case Intrinsic::arm_neon_vld1x4: { +Info.opc = ISD::INTRINSIC_W_CHAIN; +// Conservatively set memVT to the entire set of vectors loaded. +auto &DL = I.getCalledFunction()->getParent()->getDataLayout(); +uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64; +Info.memVT = EVT::getVectorVT(I.getType()->g
[PATCH] D47446: [NEON] Support VST1xN intrinsics in AArch32 mode (Clang part)
kosarev added a comment. Ping. https://reviews.llvm.org/D47446 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45515: [NEON] Support vrndns_f32 intrinsic
This revision was automatically updated to reflect the committed changes. Closed by commit rC330012: [NEON] Support vrndns_f32 intrinsic (authored by kosarev, committed by ). Repository: rC Clang https://reviews.llvm.org/D45515 Files: include/clang/Basic/arm_neon.td lib/CodeGen/CGBuiltin.cpp test/CodeGen/arm-neon-directed-rounding.c Index: test/CodeGen/arm-neon-directed-rounding.c === --- test/CodeGen/arm-neon-directed-rounding.c +++ test/CodeGen/arm-neon-directed-rounding.c @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 \ +// RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -mem2reg | FileCheck %s #include @@ -85,3 +87,10 @@ float32x4_t test_vrndq_f32(float32x4_t a) { return vrndq_f32(a); } + +// CHECK-LABEL: define float @test_vrndns_f32(float %a) #0 { +// CHECK: [[VRNDN_I:%.*]] = call float @llvm.arm.neon.vrintn.f32(float %a) #2 +// CHECK: ret float [[VRNDN_I]] +float32_t test_vrndns_f32(float32_t a) { + return vrndns_f32(a); +} Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -5590,6 +5590,12 @@ case NEON::BI__builtin_neon_vgetq_lane_f32: return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane"); + case NEON::BI__builtin_neon_vrndns_f32: { +Value *Arg = EmitScalarExpr(E->getArg(0)); +llvm::Type *Tys[] = {Arg->getType()}; +Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vrintn, Tys); +return Builder.CreateCall(F, {Arg}, "vrndn"); } + case NEON::BI__builtin_neon_vset_lane_i8: case NEON::BI__builtin_neon_vset_lane_i16: case NEON::BI__builtin_neon_vset_lane_i32: Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -1116,6 +1116,12 @@ } +// Scalar Floating-point Round to Integral +let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in { +def SCALAR_FRINTN_S32 : SInst<"vrndn", "ss", "Sf">; +} + + // Scalar Reduce Pairwise Addition (Scalar and Floating Point) def SCALAR_ADDP : SInst<"vpadd", "sd", "SfSHlSHdSHUl">; Index: test/CodeGen/arm-neon-directed-rounding.c === --- test/CodeGen/arm-neon-directed-rounding.c +++ test/CodeGen/arm-neon-directed-rounding.c @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 \ +// RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -mem2reg | FileCheck %s #include @@ -85,3 +87,10 @@ float32x4_t test_vrndq_f32(float32x4_t a) { return vrndq_f32(a); } + +// CHECK-LABEL: define float @test_vrndns_f32(float %a) #0 { +// CHECK: [[VRNDN_I:%.*]] = call float @llvm.arm.neon.vrintn.f32(float %a) #2 +// CHECK: ret float [[VRNDN_I]] +float32_t test_vrndns_f32(float32_t a) { + return vrndns_f32(a); +} Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -5590,6 +5590,12 @@ case NEON::BI__builtin_neon_vgetq_lane_f32: return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane"); + case NEON::BI__builtin_neon_vrndns_f32: { +Value *Arg = EmitScalarExpr(E->getArg(0)); +llvm::Type *Tys[] = {Arg->getType()}; +Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vrintn, Tys); +return Builder.CreateCall(F, {Arg}, "vrndn"); } + case NEON::BI__builtin_neon_vset_lane_i8: case NEON::BI__builtin_neon_vset_lane_i16: case NEON::BI__builtin_neon_vset_lane_i32: Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -1116,6 +1116,12 @@ } +// Scalar Floating-point Round to Integral +let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in { +def SCALAR_FRINTN_S32 : SInst<"vrndn", "ss", "Sf">; +} + + // Scalar Reduce Pairwise Addition (Scalar and Floating Point) def SCALAR_ADDP : SInst<"vpadd", "sd", "SfSHlSHdSHUl">;
[PATCH] D45668: [NEON] Define vget_high_f16() and vget_low_f16() intrinsics in AArch64 mode only
kosarev created this revision. kosarev added reviewers: t.p.northover, rengolin, SjoerdMeijer. kosarev added a project: clang. Herald added subscribers: kristof.beyls, javed.absar. These are AArch64-specific intrinsics. The patch removes AArch32-mode test cases and maintains AArch64 ones in tools/clang/test/CodeGen/aarch64-neon-vget-hilo.c. https://reviews.llvm.org/D45668 Files: include/clang/Basic/arm_neon.td test/CodeGen/arm_neon_intrinsics.c Index: test/CodeGen/arm_neon_intrinsics.c === --- test/CodeGen/arm_neon_intrinsics.c +++ test/CodeGen/arm_neon_intrinsics.c @@ -3254,13 +3254,6 @@ return vget_high_s64(a); } -// CHECK-LABEL: @test_vget_high_f16( -// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> %a, <8 x half> %a, <4 x i32> -// CHECK: ret <4 x half> [[SHUFFLE_I]] -float16x4_t test_vget_high_f16(float16x8_t a) { - return vget_high_f16(a); -} - // CHECK-LABEL: @test_vget_high_f32( // CHECK: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> %a, <4 x float> %a, <2 x i32> // CHECK: ret <2 x float> [[SHUFFLE_I]] @@ -3560,13 +3553,6 @@ return vget_low_s64(a); } -// CHECK-LABEL: @test_vget_low_f16( -// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> %a, <8 x half> %a, <4 x i32> -// CHECK: ret <4 x half> [[SHUFFLE_I]] -float16x4_t test_vget_low_f16(float16x8_t a) { - return vget_low_f16(a); -} - // CHECK-LABEL: @test_vget_low_f32( // CHECK: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> %a, <4 x float> %a, <2 x i32> // CHECK: ret <2 x float> [[SHUFFLE_I]] Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -398,8 +398,14 @@ // E.3.21 Splitting vectors let InstName = "vmov" in { -def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>; -def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; +def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilfUcUsUiUlPcPs", OP_HI>; +def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilfUcUsUiUlPcPs", OP_LO>; +} +let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)" in { + let InstName = "vmov" in { + def VGET_HIGH_F16 : NoTestOpInst<"vget_high", "dk", "h", OP_HI>; + def VGET_LOW_F16 : NoTestOpInst<"vget_low", "dk", "h", OP_LO>; + } } Index: test/CodeGen/arm_neon_intrinsics.c === --- test/CodeGen/arm_neon_intrinsics.c +++ test/CodeGen/arm_neon_intrinsics.c @@ -3254,13 +3254,6 @@ return vget_high_s64(a); } -// CHECK-LABEL: @test_vget_high_f16( -// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> %a, <8 x half> %a, <4 x i32> -// CHECK: ret <4 x half> [[SHUFFLE_I]] -float16x4_t test_vget_high_f16(float16x8_t a) { - return vget_high_f16(a); -} - // CHECK-LABEL: @test_vget_high_f32( // CHECK: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> %a, <4 x float> %a, <2 x i32> // CHECK: ret <2 x float> [[SHUFFLE_I]] @@ -3560,13 +3553,6 @@ return vget_low_s64(a); } -// CHECK-LABEL: @test_vget_low_f16( -// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> %a, <8 x half> %a, <4 x i32> -// CHECK: ret <4 x half> [[SHUFFLE_I]] -float16x4_t test_vget_low_f16(float16x8_t a) { - return vget_low_f16(a); -} - // CHECK-LABEL: @test_vget_low_f32( // CHECK: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> %a, <4 x float> %a, <2 x i32> // CHECK: ret <2 x float> [[SHUFFLE_I]] Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -398,8 +398,14 @@ // E.3.21 Splitting vectors let InstName = "vmov" in { -def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>; -def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; +def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilfUcUsUiUlPcPs", OP_HI>; +def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilfUcUsUiUlPcPs", OP_LO>; +} +let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)" in { + let InstName = "vmov" in { + def VGET_HIGH_F16 : NoTestOpInst<"vget_high", "dk", "h", OP_HI>; + def VGET_LOW_F16 : NoTestOpInst<"vget_low", "dk", "h", OP_LO>; + } } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45669: [NEON] Fix the architecture condition for the crypto intrinsics
kosarev created this revision. kosarev added reviewers: t.p.northover, rengolin, SjoerdMeijer. kosarev added a project: clang. Herald added subscribers: kristof.beyls, javed.absar. This is rather a cosmetic change as on ARMv7 targets we do not define __ARM_FEATURE_CRYPTO, even if it was explicitly requested with -target-feature. The crypto intrinsics test cases are in tools/clang/test/CodeGen/neon-crypto.c . No changes are necessary for them. https://reviews.llvm.org/D45669 Files: include/clang/Basic/arm_neon.td Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -913,7 +913,7 @@ // Crypto -let ArchGuard = "__ARM_FEATURE_CRYPTO" in { +let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO)" in { def AESE : SInst<"vaese", "ddd", "QUc">; def AESD : SInst<"vaesd", "ddd", "QUc">; def AESMC : SInst<"vaesmc", "dd", "QUc">; Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -913,7 +913,7 @@ // Crypto -let ArchGuard = "__ARM_FEATURE_CRYPTO" in { +let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO)" in { def AESE : SInst<"vaese", "ddd", "QUc">; def AESD : SInst<"vaesd", "ddd", "QUc">; def AESMC : SInst<"vaesmc", "dd", "QUc">; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45670: [NEON} Define vfma_n_f32() and vfmaq_n_f32() intrinsics in AArch32 mode
kosarev created this revision. kosarev added reviewers: t.p.northover, rengolin, SjoerdMeijer. kosarev added a project: clang. Herald added subscribers: kristof.beyls, javed.absar. Currently we only support them in AArch64 mode. The AArch64 test cases are in tools/clang/test/CodeGen/aarch64-neon-2velem.c. https://reviews.llvm.org/D45670 Files: include/clang/Basic/arm_neon.td test/CodeGen/arm-neon-fma.c Index: test/CodeGen/arm-neon-fma.c === --- test/CodeGen/arm-neon-fma.c +++ test/CodeGen/arm-neon-fma.c @@ -20,3 +20,29 @@ float32x4_t test_fmaq_order(float32x4_t accum, float32x4_t lhs, float32x4_t rhs) { return vfmaq_f32(accum, lhs, rhs); } + +// CHECK-LABEL: define <2 x float> @test_vfma_n_f32(<2 x float> %a, <2 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[TMP0:%.*]] = bitcast <2 x float> %a to <8 x i8> +// CHECK: [[TMP1:%.*]] = bitcast <2 x float> %b to <8 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <2 x float> [[VECINIT1_I]] to <8 x i8> +// CHECK: [[TMP3:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> %b, <2 x float> [[VECINIT1_I]], <2 x float> %a) +// CHECK: ret <2 x float> [[TMP3]] +float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) { + return vfma_n_f32(a, b, n); +} + +// CHECK-LABEL: define <4 x float> @test_vfmaq_n_f32(<4 x float> %a, <4 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %n, i32 2 +// CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %n, i32 3 +// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %a to <16 x i8> +// CHECK: [[TMP1:%.*]] = bitcast <4 x float> %b to <16 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <4 x float> [[VECINIT3_I]] to <16 x i8> +// CHECK: [[TMP3:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %b, <4 x float> [[VECINIT3_I]], <4 x float> %a) +// CHECK: ret <4 x float> [[TMP3]] +float32x4_t test_vfmaq_n_f32(float32x4_t a, float32x4_t b, float32_t n) { + return vfmaq_n_f32(a, b, n); +} Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -531,6 +531,7 @@ let ArchGuard = "defined(__ARM_FEATURE_FMA)" in { def VFMA : SInst<"vfma", "", "fQf">; def VFMS : SOpInst<"vfms", "", "fQf", OP_FMLS>; + def FMLA_N_F32 : SOpInst<"vfma_n", "ddds", "fQf", OP_FMLA_N>; } @@ -621,7 +622,7 @@ // MUL, MLA, MLS, FMA, FMS definitions with scalar argument def VMUL_N_A64 : IOpInst<"vmul_n", "dds", "Qd", OP_MUL_N>; -def FMLA_N : SOpInst<"vfma_n", "ddds", "fdQfQd", OP_FMLA_N>; +def FMLA_N : SOpInst<"vfma_n", "ddds", "dQd", OP_FMLA_N>; def FMLS_N : SOpInst<"vfms_n", "ddds", "fdQfQd", OP_FMLS_N>; def MLA_N : SOpInst<"vmla_n", "ddds", "Qd", OP_MLA_N>; Index: test/CodeGen/arm-neon-fma.c === --- test/CodeGen/arm-neon-fma.c +++ test/CodeGen/arm-neon-fma.c @@ -20,3 +20,29 @@ float32x4_t test_fmaq_order(float32x4_t accum, float32x4_t lhs, float32x4_t rhs) { return vfmaq_f32(accum, lhs, rhs); } + +// CHECK-LABEL: define <2 x float> @test_vfma_n_f32(<2 x float> %a, <2 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[TMP0:%.*]] = bitcast <2 x float> %a to <8 x i8> +// CHECK: [[TMP1:%.*]] = bitcast <2 x float> %b to <8 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <2 x float> [[VECINIT1_I]] to <8 x i8> +// CHECK: [[TMP3:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> %b, <2 x float> [[VECINIT1_I]], <2 x float> %a) +// CHECK: ret <2 x float> [[TMP3]] +float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) { + return vfma_n_f32(a, b, n); +} + +// CHECK-LABEL: define <4 x float> @test_vfmaq_n_f32(<4 x float> %a, <4 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %n, i32 2 +// CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %n, i32 3 +// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %a to <16 x i8> +// CHECK: [[TMP1:%.*]] = bitcast <4 x float> %b to <16 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <4 x float> [[VECINI
[PATCH] D45669: [NEON] Fix the architecture condition for the crypto intrinsics
This revision was automatically updated to reflect the committed changes. Closed by commit rC330187: [NEON] Fix the architecture condition for the crypto intrinsics (authored by kosarev, committed by ). Repository: rL LLVM https://reviews.llvm.org/D45669 Files: include/clang/Basic/arm_neon.td Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -913,7 +913,7 @@ // Crypto -let ArchGuard = "__ARM_FEATURE_CRYPTO" in { +let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO)" in { def AESE : SInst<"vaese", "ddd", "QUc">; def AESD : SInst<"vaesd", "ddd", "QUc">; def AESMC : SInst<"vaesmc", "dd", "QUc">; Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -913,7 +913,7 @@ // Crypto -let ArchGuard = "__ARM_FEATURE_CRYPTO" in { +let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO)" in { def AESE : SInst<"vaese", "ddd", "QUc">; def AESD : SInst<"vaesd", "ddd", "QUc">; def AESMC : SInst<"vaesmc", "dd", "QUc">; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45669: [NEON] Fix the architecture condition for the crypto intrinsics
This revision was automatically updated to reflect the committed changes. Closed by commit rL330187: [NEON] Fix the architecture condition for the crypto intrinsics (authored by kosarev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D45669?vs=142559&id=142766#toc Repository: rL LLVM https://reviews.llvm.org/D45669 Files: cfe/trunk/include/clang/Basic/arm_neon.td Index: cfe/trunk/include/clang/Basic/arm_neon.td === --- cfe/trunk/include/clang/Basic/arm_neon.td +++ cfe/trunk/include/clang/Basic/arm_neon.td @@ -913,7 +913,7 @@ // Crypto -let ArchGuard = "__ARM_FEATURE_CRYPTO" in { +let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO)" in { def AESE : SInst<"vaese", "ddd", "QUc">; def AESD : SInst<"vaesd", "ddd", "QUc">; def AESMC : SInst<"vaesmc", "dd", "QUc">; Index: cfe/trunk/include/clang/Basic/arm_neon.td === --- cfe/trunk/include/clang/Basic/arm_neon.td +++ cfe/trunk/include/clang/Basic/arm_neon.td @@ -913,7 +913,7 @@ // Crypto -let ArchGuard = "__ARM_FEATURE_CRYPTO" in { +let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_CRYPTO)" in { def AESE : SInst<"vaese", "ddd", "QUc">; def AESD : SInst<"vaesd", "ddd", "QUc">; def AESMC : SInst<"vaesmc", "dd", "QUc">; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45668: [NEON] Define vget_high_f16() and vget_low_f16() intrinsics in AArch64 mode only
kosarev added a comment. The NEON Intrinsics Reference (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0073a/index.html) reads like they are AArch64-only. https://reviews.llvm.org/D45668 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45670: [NEON} Define vfma_n_f32() and vfmaq_n_f32() intrinsics in AArch32 mode
kosarev updated this revision to Diff 142784. kosarev added a comment. Removed checks for unused bitcasts. Thanks for catching! https://reviews.llvm.org/D45670 Files: include/clang/Basic/arm_neon.td test/CodeGen/arm-neon-fma.c Index: test/CodeGen/arm-neon-fma.c === --- test/CodeGen/arm-neon-fma.c +++ test/CodeGen/arm-neon-fma.c @@ -20,3 +20,27 @@ float32x4_t test_fmaq_order(float32x4_t accum, float32x4_t lhs, float32x4_t rhs) { return vfmaq_f32(accum, lhs, rhs); } + +// CHECK-LABEL: define <2 x float> @test_vfma_n_f32(<2 x float> %a, <2 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[TMP1:%.*]] = bitcast <2 x float> %b to <8 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <2 x float> [[VECINIT1_I]] to <8 x i8> +// CHECK: [[TMP3:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> %b, <2 x float> [[VECINIT1_I]], <2 x float> %a) +// CHECK: ret <2 x float> [[TMP3]] +float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) { + return vfma_n_f32(a, b, n); +} + +// CHECK-LABEL: define <4 x float> @test_vfmaq_n_f32(<4 x float> %a, <4 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %n, i32 2 +// CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %n, i32 3 +// CHECK: [[TMP1:%.*]] = bitcast <4 x float> %b to <16 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <4 x float> [[VECINIT3_I]] to <16 x i8> +// CHECK: [[TMP3:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %b, <4 x float> [[VECINIT3_I]], <4 x float> %a) +// CHECK: ret <4 x float> [[TMP3]] +float32x4_t test_vfmaq_n_f32(float32x4_t a, float32x4_t b, float32_t n) { + return vfmaq_n_f32(a, b, n); +} Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -531,6 +531,7 @@ let ArchGuard = "defined(__ARM_FEATURE_FMA)" in { def VFMA : SInst<"vfma", "", "fQf">; def VFMS : SOpInst<"vfms", "", "fQf", OP_FMLS>; + def FMLA_N_F32 : SOpInst<"vfma_n", "ddds", "fQf", OP_FMLA_N>; } @@ -621,7 +622,7 @@ // MUL, MLA, MLS, FMA, FMS definitions with scalar argument def VMUL_N_A64 : IOpInst<"vmul_n", "dds", "Qd", OP_MUL_N>; -def FMLA_N : SOpInst<"vfma_n", "ddds", "fdQfQd", OP_FMLA_N>; +def FMLA_N : SOpInst<"vfma_n", "ddds", "dQd", OP_FMLA_N>; def FMLS_N : SOpInst<"vfms_n", "ddds", "fdQfQd", OP_FMLS_N>; def MLA_N : SOpInst<"vmla_n", "ddds", "Qd", OP_MLA_N>; Index: test/CodeGen/arm-neon-fma.c === --- test/CodeGen/arm-neon-fma.c +++ test/CodeGen/arm-neon-fma.c @@ -20,3 +20,27 @@ float32x4_t test_fmaq_order(float32x4_t accum, float32x4_t lhs, float32x4_t rhs) { return vfmaq_f32(accum, lhs, rhs); } + +// CHECK-LABEL: define <2 x float> @test_vfma_n_f32(<2 x float> %a, <2 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[TMP1:%.*]] = bitcast <2 x float> %b to <8 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <2 x float> [[VECINIT1_I]] to <8 x i8> +// CHECK: [[TMP3:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> %b, <2 x float> [[VECINIT1_I]], <2 x float> %a) +// CHECK: ret <2 x float> [[TMP3]] +float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) { + return vfma_n_f32(a, b, n); +} + +// CHECK-LABEL: define <4 x float> @test_vfmaq_n_f32(<4 x float> %a, <4 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %n, i32 2 +// CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %n, i32 3 +// CHECK: [[TMP1:%.*]] = bitcast <4 x float> %b to <16 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <4 x float> [[VECINIT3_I]] to <16 x i8> +// CHECK: [[TMP3:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %b, <4 x float> [[VECINIT3_I]], <4 x float> %a) +// CHECK: ret <4 x float> [[TMP3]] +float32x4_t test_vfmaq_n_f32(float32x4_t a, float32x4_t b, float32_t n) { + return vfmaq_n_f32(a, b, n); +} Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td ++
[PATCH] D45668: [NEON] Define vget_high_f16() and vget_low_f16() intrinsics in AArch64 mode only
This revision was automatically updated to reflect the committed changes. Closed by commit rL330195: [NEON] Define vget_high_f16() and vget_low_f16() intrinsics in AArch64 mode only (authored by kosarev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D45668?vs=142558&id=142789#toc Repository: rL LLVM https://reviews.llvm.org/D45668 Files: cfe/trunk/include/clang/Basic/arm_neon.td cfe/trunk/test/CodeGen/arm_neon_intrinsics.c Index: cfe/trunk/include/clang/Basic/arm_neon.td === --- cfe/trunk/include/clang/Basic/arm_neon.td +++ cfe/trunk/include/clang/Basic/arm_neon.td @@ -398,8 +398,14 @@ // E.3.21 Splitting vectors let InstName = "vmov" in { -def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>; -def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; +def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilfUcUsUiUlPcPs", OP_HI>; +def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilfUcUsUiUlPcPs", OP_LO>; +} +let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)" in { + let InstName = "vmov" in { + def VGET_HIGH_F16 : NoTestOpInst<"vget_high", "dk", "h", OP_HI>; + def VGET_LOW_F16 : NoTestOpInst<"vget_low", "dk", "h", OP_LO>; + } } Index: cfe/trunk/test/CodeGen/arm_neon_intrinsics.c === --- cfe/trunk/test/CodeGen/arm_neon_intrinsics.c +++ cfe/trunk/test/CodeGen/arm_neon_intrinsics.c @@ -3254,13 +3254,6 @@ return vget_high_s64(a); } -// CHECK-LABEL: @test_vget_high_f16( -// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> %a, <8 x half> %a, <4 x i32> -// CHECK: ret <4 x half> [[SHUFFLE_I]] -float16x4_t test_vget_high_f16(float16x8_t a) { - return vget_high_f16(a); -} - // CHECK-LABEL: @test_vget_high_f32( // CHECK: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> %a, <4 x float> %a, <2 x i32> // CHECK: ret <2 x float> [[SHUFFLE_I]] @@ -3560,13 +3553,6 @@ return vget_low_s64(a); } -// CHECK-LABEL: @test_vget_low_f16( -// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> %a, <8 x half> %a, <4 x i32> -// CHECK: ret <4 x half> [[SHUFFLE_I]] -float16x4_t test_vget_low_f16(float16x8_t a) { - return vget_low_f16(a); -} - // CHECK-LABEL: @test_vget_low_f32( // CHECK: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> %a, <4 x float> %a, <2 x i32> // CHECK: ret <2 x float> [[SHUFFLE_I]] Index: cfe/trunk/include/clang/Basic/arm_neon.td === --- cfe/trunk/include/clang/Basic/arm_neon.td +++ cfe/trunk/include/clang/Basic/arm_neon.td @@ -398,8 +398,14 @@ // E.3.21 Splitting vectors let InstName = "vmov" in { -def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>; -def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; +def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilfUcUsUiUlPcPs", OP_HI>; +def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilfUcUsUiUlPcPs", OP_LO>; +} +let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)" in { + let InstName = "vmov" in { + def VGET_HIGH_F16 : NoTestOpInst<"vget_high", "dk", "h", OP_HI>; + def VGET_LOW_F16 : NoTestOpInst<"vget_low", "dk", "h", OP_LO>; + } } Index: cfe/trunk/test/CodeGen/arm_neon_intrinsics.c === --- cfe/trunk/test/CodeGen/arm_neon_intrinsics.c +++ cfe/trunk/test/CodeGen/arm_neon_intrinsics.c @@ -3254,13 +3254,6 @@ return vget_high_s64(a); } -// CHECK-LABEL: @test_vget_high_f16( -// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> %a, <8 x half> %a, <4 x i32> -// CHECK: ret <4 x half> [[SHUFFLE_I]] -float16x4_t test_vget_high_f16(float16x8_t a) { - return vget_high_f16(a); -} - // CHECK-LABEL: @test_vget_high_f32( // CHECK: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> %a, <4 x float> %a, <2 x i32> // CHECK: ret <2 x float> [[SHUFFLE_I]] @@ -3560,13 +3553,6 @@ return vget_low_s64(a); } -// CHECK-LABEL: @test_vget_low_f16( -// CHECK: [[SHUFFLE_I:%.*]] = shufflevector <8 x half> %a, <8 x half> %a, <4 x i32> -// CHECK: ret <4 x half> [[SHUFFLE_I]] -float16x4_t test_vget_low_f16(float16x8_t a) { - return vget_low_f16(a); -} - // CHECK-LABEL: @test_vget_low_f32( // CHECK: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> %a, <4 x float> %a, <2 x i32> // CHECK: ret <2 x float> [[SHUFFLE_I]] ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listin
[PATCH] D45668: [NEON] Define vget_high_f16() and vget_low_f16() intrinsics in AArch64 mode only
kosarev added a comment. Sure, will do. Should we treat these intrinsics as ARMv8 or ARMv7/v8? Also, would you mind if I commit a comment under this differential revision explaining the situation? Repository: rL LLVM https://reviews.llvm.org/D45668 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45670: [NEON] Define vfma_n_f32() and vfmaq_n_f32() intrinsics in AArch32 mode
This revision was automatically updated to reflect the committed changes. Closed by commit rL330336: [NEON] Define vfma_n_f32() and vfmaq_n_f32() intrinsics in AArch32 mode (authored by kosarev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D45670?vs=142784&id=143099#toc Repository: rL LLVM https://reviews.llvm.org/D45670 Files: cfe/trunk/include/clang/Basic/arm_neon.td cfe/trunk/test/CodeGen/arm-neon-fma.c Index: cfe/trunk/include/clang/Basic/arm_neon.td === --- cfe/trunk/include/clang/Basic/arm_neon.td +++ cfe/trunk/include/clang/Basic/arm_neon.td @@ -531,6 +531,7 @@ let ArchGuard = "defined(__ARM_FEATURE_FMA)" in { def VFMA : SInst<"vfma", "", "fQf">; def VFMS : SOpInst<"vfms", "", "fQf", OP_FMLS>; + def FMLA_N_F32 : SOpInst<"vfma_n", "ddds", "fQf", OP_FMLA_N>; } @@ -621,7 +622,7 @@ // MUL, MLA, MLS, FMA, FMS definitions with scalar argument def VMUL_N_A64 : IOpInst<"vmul_n", "dds", "Qd", OP_MUL_N>; -def FMLA_N : SOpInst<"vfma_n", "ddds", "fdQfQd", OP_FMLA_N>; +def FMLA_N : SOpInst<"vfma_n", "ddds", "dQd", OP_FMLA_N>; def FMLS_N : SOpInst<"vfms_n", "ddds", "fdQfQd", OP_FMLS_N>; def MLA_N : SOpInst<"vmla_n", "ddds", "Qd", OP_MLA_N>; Index: cfe/trunk/test/CodeGen/arm-neon-fma.c === --- cfe/trunk/test/CodeGen/arm-neon-fma.c +++ cfe/trunk/test/CodeGen/arm-neon-fma.c @@ -20,3 +20,27 @@ float32x4_t test_fmaq_order(float32x4_t accum, float32x4_t lhs, float32x4_t rhs) { return vfmaq_f32(accum, lhs, rhs); } + +// CHECK-LABEL: define <2 x float> @test_vfma_n_f32(<2 x float> %a, <2 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[TMP1:%.*]] = bitcast <2 x float> %b to <8 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <2 x float> [[VECINIT1_I]] to <8 x i8> +// CHECK: [[TMP3:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> %b, <2 x float> [[VECINIT1_I]], <2 x float> %a) +// CHECK: ret <2 x float> [[TMP3]] +float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) { + return vfma_n_f32(a, b, n); +} + +// CHECK-LABEL: define <4 x float> @test_vfmaq_n_f32(<4 x float> %a, <4 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <4 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <4 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[VECINIT2_I:%.*]] = insertelement <4 x float> [[VECINIT1_I]], float %n, i32 2 +// CHECK: [[VECINIT3_I:%.*]] = insertelement <4 x float> [[VECINIT2_I]], float %n, i32 3 +// CHECK: [[TMP1:%.*]] = bitcast <4 x float> %b to <16 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <4 x float> [[VECINIT3_I]] to <16 x i8> +// CHECK: [[TMP3:%.*]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %b, <4 x float> [[VECINIT3_I]], <4 x float> %a) +// CHECK: ret <4 x float> [[TMP3]] +float32x4_t test_vfmaq_n_f32(float32x4_t a, float32x4_t b, float32_t n) { + return vfmaq_n_f32(a, b, n); +} Index: cfe/trunk/include/clang/Basic/arm_neon.td === --- cfe/trunk/include/clang/Basic/arm_neon.td +++ cfe/trunk/include/clang/Basic/arm_neon.td @@ -531,6 +531,7 @@ let ArchGuard = "defined(__ARM_FEATURE_FMA)" in { def VFMA : SInst<"vfma", "", "fQf">; def VFMS : SOpInst<"vfms", "", "fQf", OP_FMLS>; + def FMLA_N_F32 : SOpInst<"vfma_n", "ddds", "fQf", OP_FMLA_N>; } @@ -621,7 +622,7 @@ // MUL, MLA, MLS, FMA, FMS definitions with scalar argument def VMUL_N_A64 : IOpInst<"vmul_n", "dds", "Qd", OP_MUL_N>; -def FMLA_N : SOpInst<"vfma_n", "ddds", "fdQfQd", OP_FMLA_N>; +def FMLA_N : SOpInst<"vfma_n", "ddds", "dQd", OP_FMLA_N>; def FMLS_N : SOpInst<"vfms_n", "ddds", "fdQfQd", OP_FMLS_N>; def MLA_N : SOpInst<"vmla_n", "ddds", "Qd", OP_MLA_N>; Index: cfe/trunk/test/CodeGen/arm-neon-fma.c === --- cfe/trunk/test/CodeGen/arm-neon-fma.c +++ cfe/trunk/test/CodeGen/arm-neon-fma.c @@ -20,3 +20,27 @@ float32x4_t test_fmaq_order(float32x4_t accum, float32x4_t lhs, float32x4_t rhs) { return vfmaq_f32(accum, lhs, rhs); } + +// CHECK-LABEL: define <2 x float> @test_vfma_n_f32(<2 x float> %a, <2 x float> %b, float %n) #0 { +// CHECK: [[VECINIT_I:%.*]] = insertelement <2 x float> undef, float %n, i32 0 +// CHECK: [[VECINIT1_I:%.*]] = insertelement <2 x float> [[VECINIT_I]], float %n, i32 1 +// CHECK: [[TMP1:%.*]] = bitcast <2 x float> %b to <8 x i8> +// CHECK: [[TMP2:%.*]] = bitcast <2 x float> [[VECINIT1_I]] to <8 x i8> +// CHECK: [[TMP3:%.*]]
[PATCH] D45668: [NEON] Define vget_high_f16() and vget_low_f16() intrinsics in AArch64 mode only
kosarev added a comment. Thanks Sjoerd and James. Just added a comment referring to this revision in https://reviews.llvm.org/rL330420. Repository: rL LLVM https://reviews.llvm.org/D45668 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D48440: [NEON] Support vldNq intrinsics in AArch32 (Clang part)
kosarev added a comment. Ping. https://reviews.llvm.org/D48440 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D48440: [NEON] Support vldNq intrinsics in AArch32 (Clang part)
kosarev added a comment. Yep, this patch removes `vld_dup.c` as it duplicates part of what we have in `arm-neon-vld.c`. Clicking 'Show File Contents' below the file displays its contents. Thanks for reviewing! https://reviews.llvm.org/D48440 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D48829: [NEON] Fix support for vrndi_f32(), vrndiq_f32() and vrndns_f32() intrinsics
kosarev created this revision. kosarev added reviewers: SjoerdMeijer, jgreenhalgh, rengolin. kosarev added a project: clang. Herald added a reviewer: javed.absar. Herald added a subscriber: kristof.beyls. This patch adds support for vrndi_f32() and vrndiq_f32() intrinsics in AArch32 mode and for vrndns_f32() intrinsic in AArch64 mode. https://reviews.llvm.org/D48829 Files: include/clang/Basic/arm_neon.td lib/CodeGen/CGBuiltin.cpp test/CodeGen/aarch64-neon-misc.c test/CodeGen/arm-neon-directed-rounding.c test/CodeGen/arm64-vrnd.c Index: test/CodeGen/arm64-vrnd.c === --- test/CodeGen/arm64-vrnd.c +++ test/CodeGen/arm64-vrnd.c @@ -2,50 +2,21 @@ #include -int32x2_t rnd1(float32x2_t a) { return vrnd_f32(a); } -// CHECK: call <2 x float> @llvm.trunc.v2f32(<2 x float> -int32x4_t rnd3(float32x4_t a) { return vrndq_f32(a); } -// CHECK: call <4 x float> @llvm.trunc.v4f32(<4 x float> int64x2_t rnd5(float64x2_t a) { return vrndq_f64(a); } // CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> - -int32x2_t rnd7(float32x2_t a) { return vrndn_f32(a); } -// CHECK: call <2 x float> @llvm.aarch64.neon.frintn.v2f32(<2 x float> -int32x4_t rnd8(float32x4_t a) { return vrndnq_f32(a); } -// CHECK: call <4 x float> @llvm.aarch64.neon.frintn.v4f32(<4 x float> -int64x2_t rnd9(float64x2_t a) { return vrndnq_f64(a); } -// CHECK: call <2 x double> @llvm.aarch64.neon.frintn.v2f64(<2 x double> -int64x2_t rnd10(float64x2_t a) { return vrndnq_f64(a); } +int64x2_t rnd9(float64x2_t a) { return vrndnq_f64(a); } // CHECK: call <2 x double> @llvm.aarch64.neon.frintn.v2f64(<2 x double> -int32x2_t rnd11(float32x2_t a) { return vrndm_f32(a); } -// CHECK: call <2 x float> @llvm.floor.v2f32(<2 x float> -int32x4_t rnd12(float32x4_t a) { return vrndmq_f32(a); } -// CHECK: call <4 x float> @llvm.floor.v4f32(<4 x float> int64x2_t rnd13(float64x2_t a) { return vrndmq_f64(a); } // CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> -int64x2_t rnd14(float64x2_t a) { return vrndmq_f64(a); } -// CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> -int32x2_t rnd15(float32x2_t a) { return vrndp_f32(a); } -// CHECK: call <2 x float> @llvm.ceil.v2f32(<2 x float> -int32x4_t rnd16(float32x4_t a) { return vrndpq_f32(a); } -// CHECK: call <4 x float> @llvm.ceil.v4f32(<4 x float> int64x2_t rnd18(float64x2_t a) { return vrndpq_f64(a); } // CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> -int32x2_t rnd19(float32x2_t a) { return vrnda_f32(a); } -// CHECK: call <2 x float> @llvm.round.v2f32(<2 x float> -int32x4_t rnd20(float32x4_t a) { return vrndaq_f32(a); } -// CHECK: call <4 x float> @llvm.round.v4f32(<4 x float> int64x2_t rnd22(float64x2_t a) { return vrndaq_f64(a); } // CHECK: call <2 x double> @llvm.round.v2f64(<2 x double> -int32x2_t rnd23(float32x2_t a) { return vrndx_f32(a); } -// CHECK: call <2 x float> @llvm.rint.v2f32(<2 x float> -int32x4_t rnd24(float32x4_t a) { return vrndxq_f32(a); } -// CHECK: call <4 x float> @llvm.rint.v4f32(<4 x float> int64x2_t rnd25(float64x2_t a) { return vrndxq_f64(a); } // CHECK: call <2 x double> @llvm.rint.v2f64(<2 x double> Index: test/CodeGen/arm-neon-directed-rounding.c === --- test/CodeGen/arm-neon-directed-rounding.c +++ test/CodeGen/arm-neon-directed-rounding.c @@ -1,96 +1,128 @@ // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 \ // RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ -// RUN: opt -S -mem2reg | FileCheck %s +// RUN: opt -S -mem2reg | FileCheck -check-prefixes=CHECK,CHECK-A32 %s +// RUN: %clang_cc1 -triple arm64-linux-gnueabihf -target-feature +neon \ +// RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -mem2reg | FileCheck -check-prefixes=CHECK,CHECK-A64 %s #include -// CHECK-LABEL: define <2 x float> @test_vrnda_f32(<2 x float> %a) #0 { -// CHECK: [[VRNDA_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrinta.v2f32(<2 x float> %a) #2 -// CHECK: ret <2 x float> [[VRNDA_V1_I]] +// CHECK-LABEL: define <2 x float> @test_vrnda_f32(<2 x float> %a) +// CHECK-A32: [[VRNDA_V1_I:%.*]] = call <2 x float> @llvm.arm.neon.vrinta.v2f32(<2 x float> %a) +// CHECK-A64: [[VRNDA_V1_I:%.*]] = call <2 x float> @llvm.round.v2f32(<2 x float> %a) +// CHECK: ret <2 x float> [[VRNDA_V1_I]] float32x2_t test_vrnda_f32(float32x2_t a) { return vrnda_f32(a); } -// CHECK-LABEL: define <4 x float> @test_vrndaq_f32(<4 x float> %a) #0 { -// CHECK: [[VRNDAQ_V1_I:%.*]] = call <4 x float> @llvm.arm.neon.vrinta.v4f32(<4 x float> %a) #2 -// CHECK: ret <4 x float> [[VRNDAQ_V1_I]] +// CHECK-LABEL: define <4 x float> @test_vrndaq_f32(<4 x float> %a) +// CHECK-A32: [[VRNDAQ_V1_I:%.*]] = call <4 x float> @llvm.arm.neon.vrinta.v4f32(<4 x float> %a) +// CHECK-A64: [[VRNDAQ_V1_I:%.*]] = call <4 x float> @llvm.round.v4f32(<4 x float> %a) +// CHECK: ret <4 x floa
[PATCH] D49075: [NEON] Define fp16 vld and vst intrinsics conditionally
kosarev created this revision. kosarev added reviewers: SjoerdMeijer, jgreenhalgh, rengolin. kosarev added a project: clang. Herald added a reviewer: javed.absar. This patch fixes definitions of vld and vst NEON intrinsics so that we only define them if half-precision arithmetic is supported on the target platform, as prescribed in ACLE 2.0. https://reviews.llvm.org/D49075 Files: include/clang/Basic/arm_neon.td test/CodeGen/arm-neon-vld.c test/CodeGen/arm-neon-vst.c Index: test/CodeGen/arm-neon-vst.c === --- test/CodeGen/arm-neon-vst.c +++ test/CodeGen/arm-neon-vst.c @@ -2,8 +2,8 @@ // RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ // RUN: FileCheck -check-prefixes=CHECK,CHECK-A64 %s // RUN: %clang_cc1 -triple armv8-none-linux-gnueabi -target-feature +neon \ -// RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ -// RUN: FileCheck -check-prefixes=CHECK,CHECK-A32 %s +// RUN: -target-feature +fp16 -S -disable-O0-optnone -emit-llvm -o - %s | \ +// RUN: opt -S -mem2reg | FileCheck -check-prefixes=CHECK,CHECK-A32 %s #include Index: test/CodeGen/arm-neon-vld.c === --- test/CodeGen/arm-neon-vld.c +++ test/CodeGen/arm-neon-vld.c @@ -2,8 +2,8 @@ // RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ // RUN: FileCheck -check-prefixes=CHECK,CHECK-A64 %s // RUN: %clang_cc1 -triple armv8-none-linux-gnueabi -target-feature +neon \ -// RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ -// RUN: FileCheck -check-prefixes=CHECK,CHECK-A32 %s +// RUN: -target-feature +fp16 -S -disable-O0-optnone -emit-llvm -o - %s | \ +// RUN: opt -S -mem2reg | FileCheck -check-prefixes=CHECK,CHECK-A32 %s #include Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -337,48 +337,78 @@ // E.3.14 Loads and stores of a single vector def VLD1 : WInst<"vld1", "dc", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; def VLD1_X2 : WInst<"vld1_x2", "2c", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VLD1_X3 : WInst<"vld1_x3", "3c", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VLD1_X4 : WInst<"vld1_x4", "4c", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VLD1_LANE : WInst<"vld1_lane", "dcdi", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; def VLD1_DUP : WInst<"vld1_dup", "dc", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; def VST1 : WInst<"vst1", "vpd", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; def VST1_X2 : WInst<"vst1_x2", "vp2", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VST1_X3 : WInst<"vst1_x3", "vp3", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VST1_X4 : WInst<"vst1_x4", "vp4", - "cfhilsUcUiUlUsQcQfQhQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; + "cfilsUcUiUlUsQcQfQiQlQsQUcQUiQUlQUsPcPsQPcQPs">; def VST1_LANE : WInst<"vst1_lane", "vpdi", - "QUcQUsQUiQUlQcQsQiQlQhQfQPcQPsUcUsUiUlcsilhfPcPs">; + "QUcQUsQUiQUlQcQsQiQlQfQPcQPsUcUsUiUlcsilfPcPs">; +let ArchGuard = "(__ARM_FP & 2)" in { +def VLD1_F16 : WInst<"vld1", "dc", "hQh">; +def VLD1_X2_F16 : WInst<"vld1_x2", "2c", "hQh">; +def VLD1_X3_F16 : WInst<"vld1_x3", "3c", "hQh">; +def VLD1_X4_F16 : WInst<"vld1_x4", "4c", "hQh">; +def VLD1_LANE_F16 : WInst<"vld1_lane", "dcdi", "hQh">; +def VLD1_DUP_F16 : WInst<"vld1_dup", "dc", "hQh">; +def VST1_F16 : WInst<"vst1", "vpd", "hQh">; +def VST1_X2_F16 : WInst<"vst1_x2", "vp2", "hQh">; +def VST1_X3_F16 : WInst<"vst1_x3", "vp3", "hQh">; +def VST1_X4_F16 : WInst<"vst1_x4", "vp4", "hQh">; +def VST1_LANE_F16 : WInst<"vst1_lane", "vpdi", "hQh">; +} ///
[PATCH] D48829: [NEON] Fix support for vrndi_f32(), vrndiq_f32() and vrndns_f32() intrinsics
kosarev added a comment. Ping. https://reviews.llvm.org/D48829 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49375: [NEON] Define half-precision vmaxnm intrinsics only when available
kosarev created this revision. kosarev added reviewers: SjoerdMeijer, jgreenhalgh, rengolin. kosarev added a project: clang. Herald added a reviewer: javed.absar. https://reviews.llvm.org/D49375 Files: include/clang/Basic/arm_neon.td test/Sema/arm-no-fp16.c Index: test/Sema/arm-no-fp16.c === --- test/Sema/arm-no-fp16.c +++ test/Sema/arm-no-fp16.c @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple thumbv7-none-eabi %s -target-feature +neon -target-feature -fp16 -fsyntax-only -verify +// RUN: %clang_cc1 -triple thumbv7-none-eabi %s -target-feature +neon \ +// RUN: -fallow-half-arguments-and-returns -target-feature -fp16 \ +// RUN: -fsyntax-only -verify #include @@ -9,3 +11,19 @@ float32x4_t test_vcvt_f32_f16(float16x4_t a) { return vcvt_f32_f16(a); // expected-warning{{implicit declaration of function 'vcvt_f32_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float32x4_t'}} } + +float16x4_t test_vmaxnm_f16(float16x4_t a, float16x4_t b) { + return vmaxnm_f16(a, b); // expected-warning{{implicit declaration of function 'vmaxnm_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vmaxnmq_f16(float16x8_t a, float16x8_t b) { + return vmaxnmq_f16(a, b); // expected-warning{{implicit declaration of function 'vmaxnmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vminnm_f16(float16x4_t a, float16x4_t b) { + return vminnm_f16(a, b); // expected-warning{{implicit declaration of function 'vminnm_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vminnmq_f16(float16x8_t a, float16x8_t b) { + return vminnmq_f16(a, b); // expected-warning{{implicit declaration of function 'vminnmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -1463,8 +1463,10 @@ // Max/Min def VMAXH : SInst<"vmax", "ddd", "hQh">; def VMINH : SInst<"vmin", "ddd", "hQh">; - def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; - def FMINNMH : SInst<"vminnm", "ddd", "hQh">; + let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in { +def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; +def FMINNMH : SInst<"vminnm", "ddd", "hQh">; + } // Multiplication/Division def VMULH : SOpInst<"vmul", "ddd", "hQh", OP_MUL>; Index: test/Sema/arm-no-fp16.c === --- test/Sema/arm-no-fp16.c +++ test/Sema/arm-no-fp16.c @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple thumbv7-none-eabi %s -target-feature +neon -target-feature -fp16 -fsyntax-only -verify +// RUN: %clang_cc1 -triple thumbv7-none-eabi %s -target-feature +neon \ +// RUN: -fallow-half-arguments-and-returns -target-feature -fp16 \ +// RUN: -fsyntax-only -verify #include @@ -9,3 +11,19 @@ float32x4_t test_vcvt_f32_f16(float16x4_t a) { return vcvt_f32_f16(a); // expected-warning{{implicit declaration of function 'vcvt_f32_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float32x4_t'}} } + +float16x4_t test_vmaxnm_f16(float16x4_t a, float16x4_t b) { + return vmaxnm_f16(a, b); // expected-warning{{implicit declaration of function 'vmaxnm_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vmaxnmq_f16(float16x8_t a, float16x8_t b) { + return vmaxnmq_f16(a, b); // expected-warning{{implicit declaration of function 'vmaxnmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vminnm_f16(float16x4_t a, float16x4_t b) { + return vminnm_f16(a, b); // expected-warning{{implicit declaration of function 'vminnm_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vminnmq_f16(float16x8_t a, float16x8_t b) { + return vminnmq_f16(a, b); // expected-warning{{implicit declaration of function 'vminnmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -1463,8 +1463,10 @@ // Max/Min def VMAXH : SInst<"vmax", "ddd", "hQh">; def VMINH : SInst<"vmin", "ddd", "hQh">; - def FMAXNMH : SInst<"vmaxnm", "ddd", "hQh">; - def FMINNMH : SInst<"
[PATCH] D49376: [NEON] Define half-precision vrnd intrinsics only when available
kosarev created this revision. kosarev added reviewers: SjoerdMeijer, jgreenhalgh, rengolin. kosarev added a project: clang. Herald added a reviewer: javed.absar. https://reviews.llvm.org/D49376 Files: include/clang/Basic/arm_neon.td test/Sema/arm-no-fp16.c Index: test/Sema/arm-no-fp16.c === --- test/Sema/arm-no-fp16.c +++ test/Sema/arm-no-fp16.c @@ -9,3 +9,59 @@ float32x4_t test_vcvt_f32_f16(float16x4_t a) { return vcvt_f32_f16(a); // expected-warning{{implicit declaration of function 'vcvt_f32_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float32x4_t'}} } + +float16x4_t test_vrnda_f16(float16x4_t a) { + return vrnda_f16(a); // expected-warning{{implicit declaration of function 'vrnda_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndaq_f16(float16x8_t a) { + return vrndaq_f16(a); // expected-warning{{implicit declaration of function 'vrndaq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrnd_f16(float16x4_t a) { + return vrnd_f16(a); // expected-warning{{implicit declaration of function 'vrnd_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndq_f16(float16x8_t a) { + return vrndq_f16(a); // expected-warning{{implicit declaration of function 'vrndq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndi_f16(float16x4_t a) { + return vrndi_f16(a); // expected-warning{{implicit declaration of function 'vrndi_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndiq_f16(float16x8_t a) { + return vrndiq_f16(a); // expected-warning{{implicit declaration of function 'vrndiq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndm_f16(float16x4_t a) { + return vrndm_f16(a); // expected-warning{{implicit declaration of function 'vrndm_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndmq_f16(float16x8_t a) { + return vrndmq_f16(a); // expected-warning{{implicit declaration of function 'vrndmq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndn_f16(float16x4_t a) { + return vrndn_f16(a); // expected-warning{{implicit declaration of function 'vrndn_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndnq_f16(float16x8_t a) { + return vrndnq_f16(a); // expected-warning{{implicit declaration of function 'vrndnq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndp_f16(float16x4_t a) { + return vrndp_f16(a); // expected-warning{{implicit declaration of function 'vrndp_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndpq_f16(float16x8_t a) { + return vrndpq_f16(a); // expected-warning{{implicit declaration of function 'vrndpq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} + +float16x4_t test_vrndx_f16(float16x4_t a) { + return vrndx_f16(a); // expected-warning{{implicit declaration of function 'vrndx_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x4_t'}} +} + +float16x8_t test_vrndxq_f16(float16x8_t a) { + return vrndxq_f16(a); // expected-warning{{implicit declaration of function 'vrndxq_f16'}} expected-error{{returning 'int' from a function with incompatible result type 'float16x8_t'}} +} Index: include/clang/Basic/arm_neon.td === --- include/clang/Basic/arm_neon.td +++ include/clang/Basic/arm_neon.td @@ -1416,12 +1416,14 @@ def VCVTP_U16: SInst<"vcvtp_u16", "ud", "hQh">; // Vector rounding - def FRINTZH : SInst<"vrnd", "dd", "hQh">; - def FRINTNH : SInst<"vrndn", "dd", "hQh">; - def FRINTAH : SInst<"vrnda", "dd", "hQh">; - def FRINTPH : SInst<"vrndp", "dd", "hQh">; - def FRINTMH : SInst<"vrndm", "dd", "hQh">; - def FRINTXH : SInst<"vrndx", "dd", "hQh">; + let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in { +def FRINTZH : SInst<"vrnd", "dd", "hQh">; +def FRINTNH : SInst<"vrndn", "dd", "hQh">; +def FRINTAH : SInst<"vrnda", "dd", "hQh">; +def FRINTPH : SInst<"vrndp", "dd", "hQh">; +def FRINTMH : SInst<"vr
[PATCH] D49075: [NEON] Define fp16 vld and vst intrinsics conditionally
kosarev added a comment. Ping. https://reviews.llvm.org/D49075 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits