https://github.com/huhu233 created https://github.com/llvm/llvm-project/pull/107793
For the case, ``` long long res2[SIZE]; svst1(pa, (long *)&res2[0], v2); /* use res2[i] */ ``` svst1 is emitted with TBAA metadata for "long", but other users of "res2" use "long long", which is a strict aliasing violation and may cause incorrect optimization like https://github.com/llvm/llvm-project/issues/97783. The root cause is we explictly cast the type of res2 when calling svst1, and the compiler emits an improper type. This patch fixes the case by emitting "omnipotent char" for intrinsics with type cast. >From 433a80915de87098093302b57f8554bbf33fdeca Mon Sep 17 00:00:00 2001 From: zhangtiehu <zhangti...@huawei.com> Date: Tue, 3 Sep 2024 14:43:50 +0800 Subject: [PATCH 1/2] [TBAA] Precommit a test for tbaa enhancement --- clang/test/CodeGen/tbaa-sve-store-acle.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 clang/test/CodeGen/tbaa-sve-store-acle.c diff --git a/clang/test/CodeGen/tbaa-sve-store-acle.c b/clang/test/CodeGen/tbaa-sve-store-acle.c new file mode 100644 index 00000000000000..3a7c49c27e41ca --- /dev/null +++ b/clang/test/CodeGen/tbaa-sve-store-acle.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -O1 %s \ +// RUN: -emit-llvm -o - | FileCheck %s -check-prefix=TBAA +#include <arm_sve.h> + +// TBAA: store <vscale x 2 x i64> +// TBAA: !tbaa ![[TBAA6:[0-9]+]] +long long sveStoreWithTypeCast(int *datas) { + long long res2[16]; + svbool_t pa = svptrue_b32(); + svint32_t v1 = svld1(pa, &datas[0]); + svint64_t v2 = svunpklo(v1); + svst1(pa, (long *)&res2[0], v2); + return res2[0] + res2[1]; +} + +// TBAA: ![[CHAR:[0-9]+]] = !{!"omnipotent char", +// TBAA: ![[TBAA6:[0-9]+]] = !{![[LONG:.+]], ![[LONG]], i64 0} +// TBAA: ![[LONG:[0-9]+]] = !{!"long", ![[CHAR]], i64 0} >From dbe0528ad1599a0ed89929647bec5f7b7118e1b3 Mon Sep 17 00:00:00 2001 From: zhangtiehu <zhangti...@huawei.com> Date: Mon, 2 Sep 2024 17:45:23 +0800 Subject: [PATCH 2/2] [TBAA] Emit "omnipotent char" for intrinsics with type cast For the case, long long res2[SIZE]; svst1(pa, (long *)&res2[0], v2); /* use res2[i] */ svst1 is emitted with TBAA metadata for "long", but other users of "res2" use "long long", which is a strict aliasing violation and may cause incorrect optimization like #97783. The root cause is we explictly cast the type of res2 when calling svst1, and the compiler emits an improper type. This patch fixes the case by emitting "omnipotent char" for intrinsics with type cast. --- clang/lib/CodeGen/CGBuiltin.cpp | 10 ++++++++++ clang/lib/CodeGen/CodeGenModule.cpp | 4 ++++ clang/lib/CodeGen/CodeGenModule.h | 2 ++ clang/lib/CodeGen/CodeGenTBAA.cpp | 5 +++++ clang/lib/CodeGen/CodeGenTBAA.h | 2 ++ clang/test/CodeGen/tbaa-sve-store-acle.c | 3 +-- 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index da7a1a55da5313..27fd5ce976bec5 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -10155,6 +10155,11 @@ Value *CodeGenFunction::EmitSVEMaskedLoad(const CallExpr *E, auto *Load = cast<llvm::Instruction>(Builder.CreateCall(F, {Predicate, BasePtr})); auto TBAAInfo = CGM.getTBAAAccessInfo(LangPTy->getPointeeType()); + if (auto *CastE = dyn_cast<CastExpr>(E->getArg(1))) { + CastKind CK = CastE->getCastKind(); + if (CK == CK_BitCast) + TBAAInfo = CGM.genConservativeTBAA(LangPTy->getPointeeType()); + } CGM.DecorateInstructionWithTBAA(Load, TBAAInfo); if (IsQuadLoad) @@ -10207,6 +10212,11 @@ Value *CodeGenFunction::EmitSVEMaskedStore(const CallExpr *E, auto *Store = cast<llvm::Instruction>(Builder.CreateCall(F, {Val, Predicate, BasePtr})); auto TBAAInfo = CGM.getTBAAAccessInfo(LangPTy->getPointeeType()); + if (auto *CastE = dyn_cast<CastExpr>(E->getArg(1))) { + CastKind CK = CastE->getCastKind(); + if (CK == CK_BitCast) + TBAAInfo = CGM.genConservativeTBAA(LangPTy->getPointeeType()); + } CGM.DecorateInstructionWithTBAA(Store, TBAAInfo); return Store; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index df4c13c9ad97aa..7c25591d08a92a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1499,6 +1499,10 @@ TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) { return TBAA->getAccessInfo(AccessType); } +TBAAAccessInfo CodeGenModule::genConservativeTBAA(QualType AccessType) { + return TBAA->genConservativeTBAA(AccessType); +} + TBAAAccessInfo CodeGenModule::getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType) { if (!TBAA) diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index c58bb88035ca8a..2c30429850907e 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -811,6 +811,8 @@ class CodeGenModule : public CodeGenTypeCache { /// an object of the given type. TBAAAccessInfo getTBAAAccessInfo(QualType AccessType); + TBAAAccessInfo genConservativeTBAA(QualType AccessType); + /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an /// access to a virtual table pointer. TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType); diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 5b3393ec150e44..be285ba0dbff2a 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -306,6 +306,11 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) { return MetadataCache[Ty] = TypeNode; } +TBAAAccessInfo CodeGenTBAA::genConservativeTBAA(QualType AccessType) { + uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity(); + return TBAAAccessInfo(getChar(), Size); +} + TBAAAccessInfo CodeGenTBAA::getAccessInfo(QualType AccessType) { // Pointee values may have incomplete types, but they shall never be // dereferenced. diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h index ba74a39a4d25ee..de89783bc13e17 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.h +++ b/clang/lib/CodeGen/CodeGenTBAA.h @@ -213,6 +213,8 @@ class CodeGenTBAA { /// purpose of memory transfer calls. TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, TBAAAccessInfo SrcInfo); + + TBAAAccessInfo genConservativeTBAA(QualType AccessType); }; } // end namespace CodeGen diff --git a/clang/test/CodeGen/tbaa-sve-store-acle.c b/clang/test/CodeGen/tbaa-sve-store-acle.c index 3a7c49c27e41ca..e9078ecb4370ad 100644 --- a/clang/test/CodeGen/tbaa-sve-store-acle.c +++ b/clang/test/CodeGen/tbaa-sve-store-acle.c @@ -14,5 +14,4 @@ long long sveStoreWithTypeCast(int *datas) { } // TBAA: ![[CHAR:[0-9]+]] = !{!"omnipotent char", -// TBAA: ![[TBAA6:[0-9]+]] = !{![[LONG:.+]], ![[LONG]], i64 0} -// TBAA: ![[LONG:[0-9]+]] = !{!"long", ![[CHAR]], i64 0} +// TBAA: ![[TBAA6:[0-9]+]] = !{![[CHAR]], ![[CHAR]], i64 0} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits