[CodeGen] Pessimize aliasing for member unions (and may-alias) objects

Use the TBAA info of the omnipotent char for these objects.

Differential Revision: https://reviews.llvm.org/D33328

llvm-svn: 303851
This commit is contained in:
Krzysztof Parzyszek 2017-05-25 12:55:47 +00:00
parent a929063233
commit 5960a57ef7
3 changed files with 106 additions and 14 deletions

View File

@ -1432,11 +1432,12 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
}
if (TBAAInfo) {
llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
TBAAOffset);
if (TBAAPath)
CGM.DecorateInstructionWithTBAA(Load, TBAAPath,
false /*ConvertTypeToTag*/);
bool MayAlias = BaseInfo.getMayAlias();
llvm::MDNode *TBAA = MayAlias
? CGM.getTBAAInfo(getContext().CharTy)
: CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, TBAAOffset);
if (TBAA)
CGM.DecorateInstructionWithTBAA(Load, TBAA, MayAlias);
}
if (EmitScalarRangeCheck(Load, Ty, Loc)) {
@ -1522,11 +1523,12 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
}
if (TBAAInfo) {
llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
TBAAOffset);
if (TBAAPath)
CGM.DecorateInstructionWithTBAA(Store, TBAAPath,
false /*ConvertTypeToTag*/);
bool MayAlias = BaseInfo.getMayAlias();
llvm::MDNode *TBAA = MayAlias
? CGM.getTBAAInfo(getContext().CharTy)
: CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, TBAAOffset);
if (TBAA)
CGM.DecorateInstructionWithTBAA(Store, TBAA, MayAlias);
}
}
@ -3535,6 +3537,11 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
getFieldAlignmentSource(BaseInfo.getAlignmentSource());
LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias());
const RecordDecl *rec = field->getParent();
if (rec->isUnion() || rec->hasAttr<MayAliasAttr>())
FieldBaseInfo.setMayAlias(true);
bool mayAlias = FieldBaseInfo.getMayAlias();
if (field->isBitField()) {
const CGRecordLayout &RL =
CGM.getTypes().getCGRecordLayout(field->getParent());
@ -3556,11 +3563,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo);
}
const RecordDecl *rec = field->getParent();
QualType type = field->getType();
bool mayAlias = rec->hasAttr<MayAliasAttr>();
Address addr = base.getAddress();
unsigned cvr = base.getVRQualifiers();
bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA;

View File

@ -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-DAG: ![[CHAR:[0-9]+]] = !{!"omnipotent char"
// CHECK-DAG: ![[OCPATH]] = !{![[CHAR]], ![[CHAR]], i64 0}

View File

@ -0,0 +1,45 @@
// RUN: %clang_cc1 %s -O2 -std=c++11 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 -target-feature +sse4.2 -target-feature +avx -emit-llvm -o - | FileCheck %s
// Testcase from llvm.org/PR32056
extern "C" int printf (const char *__restrict __format, ...);
typedef double __m256d __attribute__((__vector_size__(32)));
static __inline __m256d __attribute__((__always_inline__, __nodebug__,
__target__("avx")))
_mm256_setr_pd(double __a, double __b, double __c, double __d) {
return (__m256d){ __a, __b, __c, __d };
}
struct A {
A () {
// Check that the TBAA information generated for the stores to the
// union members is based on the omnipotent char.
// CHECK: store <4 x double>
// CHECK: tbaa ![[OCPATH:[0-9]+]]
// CHECK: store <4 x double>
// CHECK: tbaa ![[OCPATH]]
// CHECK: call
a = _mm256_setr_pd(0.0, 1.0, 2.0, 3.0);
b = _mm256_setr_pd(4.0, 5.0, 6.0, 7.0);
}
const double *begin() { return c; }
const double *end() { return c+8; }
union {
struct { __m256d a, b; };
double c[8];
};
};
int main(int argc, char *argv[]) {
A a;
for (double value : a)
printf("%f ", value);
return 0;
}
// CHECK-DAG: ![[CHAR:[0-9]+]] = !{!"omnipotent char"
// CHECK-DAG: ![[OCPATH]] = !{![[CHAR]], ![[CHAR]], i64 0}