-
Notifications
You must be signed in to change notification settings - Fork 14k
[TBAA] Emit "omnipotent char" for intrinsics with type cast #107793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
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 llvm#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.
@llvm/pr-subscribers-clang Author: None (huhu233) ChangesFor the case,
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. Full diff: https://github.com/llvm/llvm-project/pull/107793.diff 6 Files Affected:
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
new file mode 100644
index 00000000000000..e9078ecb4370ad
--- /dev/null
+++ b/clang/test/CodeGen/tbaa-sve-store-acle.c
@@ -0,0 +1,17 @@
+// 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]+]] = !{![[CHAR]], ![[CHAR]], i64 0}
|
@llvm/pr-subscribers-clang-codegen Author: None (huhu233) ChangesFor the case,
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. Full diff: https://github.com/llvm/llvm-project/pull/107793.diff 6 Files Affected:
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
new file mode 100644
index 00000000000000..e9078ecb4370ad
--- /dev/null
+++ b/clang/test/CodeGen/tbaa-sve-store-acle.c
@@ -0,0 +1,17 @@
+// 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]+]] = !{![[CHAR]], ![[CHAR]], i64 0}
|
I don't understand this. The code is a strict aliasing violation, so why should clang work around it? |
Hi, @arsenm, the violation is due to the compiler emitting different TBAA for |
I'll need to look to see if the TBAA metadata we're adding matches what we initially envisaged but my gut feeling matches @arsenm. I'm assuming the original code emitted an error, something along the lines of "no version of svst1 available for long long*", which you've "fixed" by introducing a cast that breaks strict aliasing rules. I recall warnings relating to strict aliasing violations being hit and miss? but perhaps we can do better. |
Hi, @paulwalker-arm, ACLE allows users to do instruction-level development, but mixing intrinsic and regular C code may break some of the rules set by the compiler. For example, in this case, the explict cast causes |
The rules are still there. You can always use a union or copy to avoid violating the rules. I don't think it makes sense to special case any intrinsics |
For the case,
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.