Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1432,6 +1432,8 @@ Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } if (TBAAInfo) { + if (BaseInfo.getMayAlias()) + TBAAInfo = CGM.getTBAAInfo(getContext().CharTy); llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, TBAAOffset); if (TBAAPath) @@ -1522,6 +1524,8 @@ Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } if (TBAAInfo) { + if (BaseInfo.getMayAlias()) + TBAAInfo = CGM.getTBAAInfo(getContext().CharTy); llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, TBAAOffset); if (TBAAPath) @@ -3535,6 +3539,11 @@ getFieldAlignmentSource(BaseInfo.getAlignmentSource()); LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias()); + const RecordDecl *rec = field->getParent(); + bool mayAlias = rec->isUnion() || rec->hasAttr(); + if (mayAlias) + FieldBaseInfo.setMayAlias(true); + if (field->isBitField()) { const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(field->getParent()); @@ -3556,11 +3565,7 @@ return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo); } - const RecordDecl *rec = field->getParent(); QualType type = field->getType(); - - bool mayAlias = rec->hasAttr(); - Address addr = base.getAddress(); unsigned cvr = base.getVRQualifiers(); bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; Index: test/CodeGen/union-tbaa1.c =================================================================== --- /dev/null +++ test/CodeGen/union-tbaa1.c @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 %s -triple hexagon-unknown-elf -O2 -emit-llvm -o - | FileCheck %s + +typedef union __attribute__((aligned(4))) { + unsigned short uh[2]; + unsigned uw; +} vect32; + +void bar(vect32 p[][2]); + +// CHECK-LABEL: define void @fred +void fred(unsigned Num, int Vec[2], int *Index, int Arr[4][2]) { + vect32 Tmp[4][2]; +// Generate tbaa for the load of Index: +// CHECK: load i32, i32* %Index{{.*}}tbaa +// But no tbaa for the two stores: +// CHECK: %uw[[UW1:[0-9]*]] = getelementptr +// CHECK: store{{.*}}%uw[[UW1]] +// CHECK: tbaa ![[OCPATH:[0-9]+]] +// There will be a load after the store, and it will use tbaa. Make sure +// the check-not above doesn't find it: +// CHECK: load + Tmp[*Index][0].uw = Arr[*Index][0] * Num; +// CHECK: %uw[[UW2:[0-9]*]] = getelementptr +// CHECK: store{{.*}}%uw[[UW2]] +// CHECK: tbaa ![[OCPATH]] + Tmp[*Index][1].uw = Arr[*Index][1] * Num; +// Same here, don't generate tbaa for the loads: +// CHECK: %uh[[UH1:[0-9]*]] = bitcast %union.vect32 +// CHECK: %arrayidx[[AX1:[0-9]*]] = getelementptr{{.*}}%uh[[UH1]] +// CHECK: load i16, i16* %arrayidx[[AX1]] +// CHECK: tbaa ![[OCPATH]] +// CHECK: store + Vec[0] = Tmp[*Index][0].uh[1]; +// CHECK: %uh[[UH2:[0-9]*]] = bitcast %union.vect32 +// CHECK: %arrayidx[[AX2:[0-9]*]] = getelementptr{{.*}}%uh[[UH2]] +// CHECK: load i16, i16* %arrayidx[[AX2]] +// CHECK: tbaa ![[OCPATH]] +// CHECK: store + Vec[1] = Tmp[*Index][1].uh[1]; + bar(Tmp); +} + +// CHECK: ![[CHAR:[0-9]+]] = !{!"omnipotent char" +// CHECK: ![[OCPATH]] = !{![[CHAR]]