From c750234674531788ee26958954a5f9a6b59ea866 Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Tue, 23 Jul 2024 23:10:42 -0400 Subject: [PATCH 1/8] [clang codegen] Emit int TBAA metadata on more FP math libcalls Follow PR96025, except expf, more FP math libcalls in libm should also be supported. Fix https://github.com/llvm/llvm-project/issues/86635 --- clang/lib/CodeGen/CGBuiltin.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index a0d03b87ccdc9..a9696ebe61e3a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -692,23 +692,22 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD, RValue Call = CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot()); - // Check the supported intrinsic. + ASTContext &Context = CGF.getContext(); if (unsigned BuiltinID = FD->getBuiltinID()) { auto IsErrnoIntrinsic = [&]() -> unsigned { - switch (BuiltinID) { - case Builtin::BIexpf: - case Builtin::BI__builtin_expf: - case Builtin::BI__builtin_expf128: + // Check whether a FP math builtin function, such as BI__builtin_expf + QualType ResultTy = FD->getReturnType(); + bool IsMathLibCall = + Context.BuiltinInfo.isLibFunction(BuiltinID) || + Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID); + if (IsMathLibCall && CGF.ConvertType(ResultTy)->isFloatingPointTy()) return true; - } - // TODO: support more FP math libcalls return false; }(); // Restrict to target with errno, for example, MacOS doesn't set errno. if (IsErrnoIntrinsic && CGF.CGM.getLangOpts().MathErrno && !CGF.Builder.getIsFPConstrained()) { - ASTContext &Context = CGF.getContext(); // Emit "int" TBAA metadata on FP math libcalls. clang::QualType IntTy = Context.IntTy; TBAAAccessInfo TBAAInfo = CGF.CGM.getTBAAAccessInfo(IntTy); From fb81f300280582b2e820e32094dee9e6ed1da75f Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Wed, 24 Jul 2024 03:38:42 -0400 Subject: [PATCH 2/8] Add a new test calls fabs --- clang/test/CodeGen/math-libcalls-tbaa.cpp | 29 +++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/clang/test/CodeGen/math-libcalls-tbaa.cpp b/clang/test/CodeGen/math-libcalls-tbaa.cpp index f15938dee0272..2812e82abe652 100644 --- a/clang/test/CodeGen/math-libcalls-tbaa.cpp +++ b/clang/test/CodeGen/math-libcalls-tbaa.cpp @@ -4,23 +4,40 @@ // RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,NewStructPathTBAA extern "C" float expf(float); +extern "C" double fabs(double); // Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis // CHECK-LABEL: define dso_local float @foo( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], float noundef [[R2INV:%.*]], i32 noundef [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] -// CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR2:[0-9]+]], !tbaa [[TBAA6:![0-9]+]] +// CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR4:[0-9]+]], !tbaa [[TBAA6:![0-9]+]] // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] // CHECK-NEXT: ret float [[MUL]] // -extern "C" float foo (float num[], float r2inv, int n) { - const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf +extern "C" float foo (float num[]) { + const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf float tmp = expm2 * num[10]; return tmp; } + +// CHECK-LABEL: define dso_local double @foo_fabs( +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 +// CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8:![0-9]+]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call double @llvm.fabs.f64(double [[TMP0]]) +// CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[TMP1]] +// CHECK-NEXT: ret double [[MUL]] +// +extern "C" double foo_fabs (double num[]) { + const double expm2 = fabs(num[10]); // Emit TBAA metadata on @fabs + double tmp = expm2 * num[10]; + return tmp; +} + //. // NoNewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} // NoNewStructPathTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0} @@ -28,6 +45,8 @@ extern "C" float foo (float num[], float r2inv, int n) { // NoNewStructPathTBAA: [[META5]] = !{!"Simple C++ TBAA"} // NoNewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} // NoNewStructPathTBAA: [[META7]] = !{!"int", [[META4]], i64 0} +// NoNewStructPathTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} +// NoNewStructPathTBAA: [[META9]] = !{!"double", [[META4]], i64 0} //. // NewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0, i64 4} // NewStructPathTBAA: [[META3]] = !{[[META4:![0-9]+]], i64 4, !"float"} @@ -35,6 +54,8 @@ extern "C" float foo (float num[], float r2inv, int n) { // NewStructPathTBAA: [[META5]] = !{!"Simple C++ TBAA"} // NewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0, i64 4} // NewStructPathTBAA: [[META7]] = !{[[META4]], i64 4, !"int"} +// NewStructPathTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0, i64 8} +// NewStructPathTBAA: [[META9]] = !{[[META4]], i64 8, !"double"} //. //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: // NewStructPathTBAA: {{.*}} From b4cbc0545a8c96cfcb9e463c3a23828a2158d194 Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Thu, 25 Jul 2024 07:42:57 -0400 Subject: [PATCH 3/8] Update with isConstWithoutErrnoAndExceptions --- clang/lib/CodeGen/CGBuiltin.cpp | 8 ++++---- clang/test/CodeGen/math-libcalls-tbaa.cpp | 20 +++++++++++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index a9696ebe61e3a..addb6e1df4b15 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -697,10 +697,10 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD, auto IsErrnoIntrinsic = [&]() -> unsigned { // Check whether a FP math builtin function, such as BI__builtin_expf QualType ResultTy = FD->getReturnType(); - bool IsMathLibCall = - Context.BuiltinInfo.isLibFunction(BuiltinID) || - Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID); - if (IsMathLibCall && CGF.ConvertType(ResultTy)->isFloatingPointTy()) + bool ConstWithoutErrnoAndExceptions = + Context.BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID); + if (ConstWithoutErrnoAndExceptions && + CGF.ConvertType(ResultTy)->isFloatingPointTy()) return true; return false; }(); diff --git a/clang/test/CodeGen/math-libcalls-tbaa.cpp b/clang/test/CodeGen/math-libcalls-tbaa.cpp index 2812e82abe652..ce1373bde2ead 100644 --- a/clang/test/CodeGen/math-libcalls-tbaa.cpp +++ b/clang/test/CodeGen/math-libcalls-tbaa.cpp @@ -4,6 +4,7 @@ // RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,NewStructPathTBAA extern "C" float expf(float); +extern "C" double remainder(double, double); extern "C" double fabs(double); // Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis @@ -23,6 +24,8 @@ extern "C" float foo (float num[]) { return tmp; } +// +// Negative test: fabs cannot set errno // CHECK-LABEL: define dso_local double @foo_fabs( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] @@ -33,7 +36,22 @@ extern "C" float foo (float num[]) { // CHECK-NEXT: ret double [[MUL]] // extern "C" double foo_fabs (double num[]) { - const double expm2 = fabs(num[10]); // Emit TBAA metadata on @fabs + const double expm2 = fabs(num[10]); // Don't emit TBAA metadata + double tmp = expm2 * num[10]; + return tmp; +} + +// CHECK-LABEL: define dso_local double @foo_remainder( +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 +// CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] +// CHECK-NEXT: [[CALL:%.*]] = tail call double @remainder(double noundef [[TMP0]], double noundef [[A]]) #[[ATTR4]], !tbaa [[TBAA6]] +// CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] +// CHECK-NEXT: ret double [[MUL]] +// +extern "C" double foo_remainder (double num[], double a) { + const double expm2 = remainder(num[10], a); // Emit TBAA metadata double tmp = expm2 * num[10]; return tmp; } From ce42e64b916a3820f9fb0af34e03016e29b642f0 Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Sun, 28 Jul 2024 20:51:28 -0400 Subject: [PATCH 4/8] Address comments --- clang/lib/CodeGen/CGBuiltin.cpp | 18 ++--- ...libcalls-tbaa.cpp => math-libcalls-tbaa.c} | 78 +++++++++++++++---- 2 files changed, 70 insertions(+), 26 deletions(-) rename clang/test/CodeGen/{math-libcalls-tbaa.cpp => math-libcalls-tbaa.c} (50%) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index addb6e1df4b15..8110811c210f5 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -692,21 +692,13 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD, RValue Call = CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot()); - ASTContext &Context = CGF.getContext(); if (unsigned BuiltinID = FD->getBuiltinID()) { - auto IsErrnoIntrinsic = [&]() -> unsigned { - // Check whether a FP math builtin function, such as BI__builtin_expf - QualType ResultTy = FD->getReturnType(); - bool ConstWithoutErrnoAndExceptions = - Context.BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID); - if (ConstWithoutErrnoAndExceptions && - CGF.ConvertType(ResultTy)->isFloatingPointTy()) - return true; - return false; - }(); - + // Check whether a FP math builtin function, such as BI__builtin_expf + ASTContext &Context = CGF.getContext(); + bool ConstWithoutErrnoAndExceptions = + Context.BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID); // Restrict to target with errno, for example, MacOS doesn't set errno. - if (IsErrnoIntrinsic && CGF.CGM.getLangOpts().MathErrno && + if (ConstWithoutErrnoAndExceptions && CGF.CGM.getLangOpts().MathErrno && !CGF.Builder.getIsFPConstrained()) { // Emit "int" TBAA metadata on FP math libcalls. clang::QualType IntTy = Context.IntTy; diff --git a/clang/test/CodeGen/math-libcalls-tbaa.cpp b/clang/test/CodeGen/math-libcalls-tbaa.c similarity index 50% rename from clang/test/CodeGen/math-libcalls-tbaa.cpp rename to clang/test/CodeGen/math-libcalls-tbaa.c index ce1373bde2ead..270f0ab7769f3 100644 --- a/clang/test/CodeGen/math-libcalls-tbaa.cpp +++ b/clang/test/CodeGen/math-libcalls-tbaa.c @@ -1,11 +1,13 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 -// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,NoNewStructPathTBAA -// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,NewStructPathTBAA +// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NoNewStructPathTBAA +// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NewStructPathTBAA -extern "C" float expf(float); -extern "C" double remainder(double, double); -extern "C" double fabs(double); +float expf(float); +double remainder(double, double); +double fabs(double); +double frexp(double, int *exp); +void sincos(float a, float *s, float *c); // Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis @@ -14,11 +16,11 @@ extern "C" double fabs(double); // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] -// CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR4:[0-9]+]], !tbaa [[TBAA6:![0-9]+]] +// CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR9:[0-9]+]], !tbaa [[TBAA6:![0-9]+]] // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] // CHECK-NEXT: ret float [[MUL]] // -extern "C" float foo (float num[]) { +float foo (float num[]) { const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf float tmp = expm2 * num[10]; return tmp; @@ -27,7 +29,7 @@ extern "C" float foo (float num[]) { // // Negative test: fabs cannot set errno // CHECK-LABEL: define dso_local double @foo_fabs( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8:![0-9]+]] @@ -35,7 +37,7 @@ extern "C" float foo (float num[]) { // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[TMP1]] // CHECK-NEXT: ret double [[MUL]] // -extern "C" double foo_fabs (double num[]) { +double foo_fabs (double num[]) { const double expm2 = fabs(num[10]); // Don't emit TBAA metadata double tmp = expm2 * num[10]; return tmp; @@ -46,21 +48,71 @@ extern "C" double foo_fabs (double num[]) { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] -// CHECK-NEXT: [[CALL:%.*]] = tail call double @remainder(double noundef [[TMP0]], double noundef [[A]]) #[[ATTR4]], !tbaa [[TBAA6]] +// CHECK-NEXT: [[CALL:%.*]] = tail call double @remainder(double noundef [[TMP0]], double noundef [[A]]) #[[ATTR9]], !tbaa [[TBAA6]] // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] // CHECK-NEXT: ret double [[MUL]] // -extern "C" double foo_remainder (double num[], double a) { +double foo_remainder (double num[], double a) { const double expm2 = remainder(num[10], a); // Emit TBAA metadata double tmp = expm2 * num[10]; return tmp; } +// +// Negative test: frexp is not subject to any errors. +// CHECK-LABEL: define dso_local double @foo_frexp( +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[E:%.*]] = alloca i32, align 4 +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 16 +// CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] +// CHECK-NEXT: [[CALL:%.*]] = call double @frexp(double noundef [[TMP0]], ptr noundef nonnull [[E]]) #[[ATTR9]] +// CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] +// CHECK-NEXT: ret double [[MUL]] +// +double foo_frexp (double num[], double a) { + int e; + double expm2 = frexp(num[2], &e); // Don't emit TBAA metadata + double tmp = expm2 * num[2]; + return tmp; +} + +// +// Negative test: sincos is a library function, but is not a builtin function +// checked in CodeGenFunction::EmitCallExpr. +// CHECK-LABEL: define dso_local float @foo_sincos( +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], float noundef [[A:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[SIN:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[COS:%.*]] = alloca float, align 4 +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] +// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[COS]]) #[[ATTR9]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 8 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @sincos(float noundef [[TMP0]], ptr noundef nonnull [[SIN]], ptr noundef nonnull [[COS]]) #[[ATTR9]] +// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[SIN]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[COS]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP1]], [[TMP2]] +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[ADD:%.*]] = fadd float [[MUL]], [[TMP3]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[COS]]) #[[ATTR9]] +// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] +// CHECK-NEXT: ret float [[ADD]] +// +float foo_sincos (float num[], float a) { + float sin, cos; + sincos(num[2], &sin, &cos); // Don't emit TBAA metadata + float tmp = sin * cos + num[2]; + return tmp; +} + //. // NoNewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} // NoNewStructPathTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0} // NoNewStructPathTBAA: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} -// NoNewStructPathTBAA: [[META5]] = !{!"Simple C++ TBAA"} +// NoNewStructPathTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} // NoNewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} // NoNewStructPathTBAA: [[META7]] = !{!"int", [[META4]], i64 0} // NoNewStructPathTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} @@ -69,7 +121,7 @@ extern "C" double foo_remainder (double num[], double a) { // NewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0, i64 4} // NewStructPathTBAA: [[META3]] = !{[[META4:![0-9]+]], i64 4, !"float"} // NewStructPathTBAA: [[META4]] = !{[[META5:![0-9]+]], i64 1, !"omnipotent char"} -// NewStructPathTBAA: [[META5]] = !{!"Simple C++ TBAA"} +// NewStructPathTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} // NewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0, i64 4} // NewStructPathTBAA: [[META7]] = !{[[META4]], i64 4, !"int"} // NewStructPathTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0, i64 8} From 8d804335032184f12bc3a51794076f5536db6d13 Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Mon, 29 Jul 2024 23:25:54 -0400 Subject: [PATCH 5/8] workaroud the unsupported complex type builtin --- clang/lib/CodeGen/CGBuiltin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 8110811c210f5..5275f222c74d6 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -698,8 +698,9 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD, bool ConstWithoutErrnoAndExceptions = Context.BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID); // Restrict to target with errno, for example, MacOS doesn't set errno. + // TODO: Support builtin function with complex type returned, eg: cacosh if (ConstWithoutErrnoAndExceptions && CGF.CGM.getLangOpts().MathErrno && - !CGF.Builder.getIsFPConstrained()) { + !CGF.Builder.getIsFPConstrained() && Call.isScalar()) { // Emit "int" TBAA metadata on FP math libcalls. clang::QualType IntTy = Context.IntTy; TBAAAccessInfo TBAAInfo = CGF.CGM.getTBAAAccessInfo(IntTy); From 8ea876621ba589d70a550efffbaa6be33fa3a95c Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Tue, 30 Jul 2024 02:22:04 -0400 Subject: [PATCH 6/8] Add 2 tests builtin and _Complex type --- clang/test/CodeGen/math-libcalls-tbaa.c | 45 ++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/clang/test/CodeGen/math-libcalls-tbaa.c b/clang/test/CodeGen/math-libcalls-tbaa.c index 270f0ab7769f3..d2e4135995568 100644 --- a/clang/test/CodeGen/math-libcalls-tbaa.c +++ b/clang/test/CodeGen/math-libcalls-tbaa.c @@ -8,6 +8,8 @@ double remainder(double, double); double fabs(double); double frexp(double, int *exp); void sincos(float a, float *s, float *c); +float _Complex cacoshf(float _Complex); +float crealf(float _Complex); // Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis @@ -26,6 +28,21 @@ float foo (float num[]) { return tmp; } +// CHECK-LABEL: define dso_local float @foo_buildin( +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR9]], !tbaa [[TBAA6]] +// CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] +// CHECK-NEXT: ret float [[MUL]] +// +float foo_buildin (float num[]) { + const float expm2 = __builtin_expf(num[10]); // Emit TBAA metadata on @expf + float tmp = expm2 * num[10]; + return tmp; +} + // // Negative test: fabs cannot set errno // CHECK-LABEL: define dso_local double @foo_fabs( @@ -61,7 +78,7 @@ double foo_remainder (double num[], double a) { // // Negative test: frexp is not subject to any errors. // CHECK-LABEL: define dso_local double @foo_frexp( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[E:%.*]] = alloca i32, align 4 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] @@ -72,7 +89,7 @@ double foo_remainder (double num[], double a) { // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] // CHECK-NEXT: ret double [[MUL]] // -double foo_frexp (double num[], double a) { +double foo_frexp (double num[]) { int e; double expm2 = frexp(num[2], &e); // Don't emit TBAA metadata double tmp = expm2 * num[2]; @@ -83,7 +100,7 @@ double foo_frexp (double num[], double a) { // Negative test: sincos is a library function, but is not a builtin function // checked in CodeGenFunction::EmitCallExpr. // CHECK-LABEL: define dso_local float @foo_sincos( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], float noundef [[A:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SIN:%.*]] = alloca float, align 4 // CHECK-NEXT: [[COS:%.*]] = alloca float, align 4 @@ -101,13 +118,33 @@ double foo_frexp (double num[], double a) { // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] // CHECK-NEXT: ret float [[ADD]] // -float foo_sincos (float num[], float a) { +float foo_sincos (float num[]) { float sin, cos; sincos(num[2], &sin, &cos); // Don't emit TBAA metadata float tmp = sin * cos + num[2]; return tmp; } +// TODO: The builtin return a complex type +// CHECK-LABEL: define dso_local float @foo_cacoshf( +// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 8 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [2 x float] poison, float [[TMP0]], 0 +// CHECK-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue [2 x float] [[DOTFCA_0_INSERT]], float 0.000000e+00, 1 +// CHECK-NEXT: [[CALL:%.*]] = tail call { float, float } @cacoshf([2 x float] noundef alignstack(8) [[DOTFCA_1_INSERT]]) #[[ATTR9]] +// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { float, float } [[CALL]], 0 +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[TMP2]] +// CHECK-NEXT: ret float [[ADD]] +// +float foo_cacoshf (float num[]) { + float _Complex z = cacoshf(num[2]); // Don't emit TBAA metadata + float tmp = crealf(z) + num[2]; + return tmp; +} + //. // NoNewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} // NoNewStructPathTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0} From e03ab416ce89e55a19f9c69c2ecb0f9acfc96eab Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Tue, 30 Jul 2024 04:58:58 -0400 Subject: [PATCH 7/8] Fix testname --- clang/test/CodeGen/math-libcalls-tbaa.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clang/test/CodeGen/math-libcalls-tbaa.c b/clang/test/CodeGen/math-libcalls-tbaa.c index d2e4135995568..86b132e8ac499 100644 --- a/clang/test/CodeGen/math-libcalls-tbaa.c +++ b/clang/test/CodeGen/math-libcalls-tbaa.c @@ -13,7 +13,7 @@ float crealf(float _Complex); // Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis -// CHECK-LABEL: define dso_local float @foo( +// CHECK-LABEL: define dso_local float @foo_expf( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 @@ -22,13 +22,13 @@ float crealf(float _Complex); // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] // CHECK-NEXT: ret float [[MUL]] // -float foo (float num[]) { +float foo_expf (float num[]) { const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf float tmp = expm2 * num[10]; return tmp; } -// CHECK-LABEL: define dso_local float @foo_buildin( +// CHECK-LABEL: define dso_local float @foo_builtin_expf( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 @@ -37,7 +37,7 @@ float foo (float num[]) { // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] // CHECK-NEXT: ret float [[MUL]] // -float foo_buildin (float num[]) { +float foo_builtin_expf (float num[]) { const float expm2 = __builtin_expf(num[10]); // Emit TBAA metadata on @expf float tmp = expm2 * num[10]; return tmp; @@ -76,7 +76,8 @@ double foo_remainder (double num[], double a) { } // -// Negative test: frexp is not subject to any errors. +// TODO: frexp is not subject to any errors, but also writes to +// its int pointer out argument, so it could emit int TBAA metadata. // CHECK-LABEL: define dso_local double @foo_frexp( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] From 4770e71eb7dd612d4619aa201a5558c0500e0cea Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Tue, 30 Jul 2024 07:20:54 -0400 Subject: [PATCH 8/8] Rename test function --- clang/test/CodeGen/math-libcalls-tbaa.c | 68 ++++++++++++------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/clang/test/CodeGen/math-libcalls-tbaa.c b/clang/test/CodeGen/math-libcalls-tbaa.c index 86b132e8ac499..9c86eea67d14d 100644 --- a/clang/test/CodeGen/math-libcalls-tbaa.c +++ b/clang/test/CodeGen/math-libcalls-tbaa.c @@ -1,7 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 -// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NoNewStructPathTBAA -// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NewStructPathTBAA +// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NONEWSTRUCTPATHTBAA +// RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NEWSTRUCTPATHTBAA float expf(float); double remainder(double, double); @@ -13,7 +13,7 @@ float crealf(float _Complex); // Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis -// CHECK-LABEL: define dso_local float @foo_expf( +// CHECK-LABEL: define dso_local float @test_expf( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 @@ -22,13 +22,13 @@ float crealf(float _Complex); // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] // CHECK-NEXT: ret float [[MUL]] // -float foo_expf (float num[]) { +float test_expf (float num[]) { const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf float tmp = expm2 * num[10]; return tmp; } -// CHECK-LABEL: define dso_local float @foo_builtin_expf( +// CHECK-LABEL: define dso_local float @test_builtin_expf( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 @@ -37,7 +37,7 @@ float foo_expf (float num[]) { // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] // CHECK-NEXT: ret float [[MUL]] // -float foo_builtin_expf (float num[]) { +float test_builtin_expf (float num[]) { const float expm2 = __builtin_expf(num[10]); // Emit TBAA metadata on @expf float tmp = expm2 * num[10]; return tmp; @@ -45,7 +45,7 @@ float foo_builtin_expf (float num[]) { // // Negative test: fabs cannot set errno -// CHECK-LABEL: define dso_local double @foo_fabs( +// CHECK-LABEL: define dso_local double @test_fabs( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 @@ -54,13 +54,13 @@ float foo_builtin_expf (float num[]) { // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[TMP1]] // CHECK-NEXT: ret double [[MUL]] // -double foo_fabs (double num[]) { +double test_fabs (double num[]) { const double expm2 = fabs(num[10]); // Don't emit TBAA metadata double tmp = expm2 * num[10]; return tmp; } -// CHECK-LABEL: define dso_local double @foo_remainder( +// CHECK-LABEL: define dso_local double @test_remainder( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 @@ -69,7 +69,7 @@ double foo_fabs (double num[]) { // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] // CHECK-NEXT: ret double [[MUL]] // -double foo_remainder (double num[], double a) { +double test_remainder (double num[], double a) { const double expm2 = remainder(num[10], a); // Emit TBAA metadata double tmp = expm2 * num[10]; return tmp; @@ -78,7 +78,7 @@ double foo_remainder (double num[], double a) { // // TODO: frexp is not subject to any errors, but also writes to // its int pointer out argument, so it could emit int TBAA metadata. -// CHECK-LABEL: define dso_local double @foo_frexp( +// CHECK-LABEL: define dso_local double @test_frexp( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[E:%.*]] = alloca i32, align 4 @@ -90,7 +90,7 @@ double foo_remainder (double num[], double a) { // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] // CHECK-NEXT: ret double [[MUL]] // -double foo_frexp (double num[]) { +double test_frexp (double num[]) { int e; double expm2 = frexp(num[2], &e); // Don't emit TBAA metadata double tmp = expm2 * num[2]; @@ -100,7 +100,7 @@ double foo_frexp (double num[]) { // // Negative test: sincos is a library function, but is not a builtin function // checked in CodeGenFunction::EmitCallExpr. -// CHECK-LABEL: define dso_local float @foo_sincos( +// CHECK-LABEL: define dso_local float @test_sincos( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SIN:%.*]] = alloca float, align 4 @@ -119,7 +119,7 @@ double foo_frexp (double num[]) { // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] // CHECK-NEXT: ret float [[ADD]] // -float foo_sincos (float num[]) { +float test_sincos (float num[]) { float sin, cos; sincos(num[2], &sin, &cos); // Don't emit TBAA metadata float tmp = sin * cos + num[2]; @@ -127,7 +127,7 @@ float foo_sincos (float num[]) { } // TODO: The builtin return a complex type -// CHECK-LABEL: define dso_local float @foo_cacoshf( +// CHECK-LABEL: define dso_local float @test_cacoshf( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 8 @@ -140,31 +140,31 @@ float foo_sincos (float num[]) { // CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[TMP2]] // CHECK-NEXT: ret float [[ADD]] // -float foo_cacoshf (float num[]) { +float test_cacoshf (float num[]) { float _Complex z = cacoshf(num[2]); // Don't emit TBAA metadata float tmp = crealf(z) + num[2]; return tmp; } //. -// NoNewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} -// NoNewStructPathTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0} -// NoNewStructPathTBAA: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} -// NoNewStructPathTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} -// NoNewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} -// NoNewStructPathTBAA: [[META7]] = !{!"int", [[META4]], i64 0} -// NoNewStructPathTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} -// NoNewStructPathTBAA: [[META9]] = !{!"double", [[META4]], i64 0} +// NONEWSTRUCTPATHTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} +// NONEWSTRUCTPATHTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META7]] = !{!"int", [[META4]], i64 0} +// NONEWSTRUCTPATHTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} +// NONEWSTRUCTPATHTBAA: [[META9]] = !{!"double", [[META4]], i64 0} //. -// NewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0, i64 4} -// NewStructPathTBAA: [[META3]] = !{[[META4:![0-9]+]], i64 4, !"float"} -// NewStructPathTBAA: [[META4]] = !{[[META5:![0-9]+]], i64 1, !"omnipotent char"} -// NewStructPathTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} -// NewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0, i64 4} -// NewStructPathTBAA: [[META7]] = !{[[META4]], i64 4, !"int"} -// NewStructPathTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0, i64 8} -// NewStructPathTBAA: [[META9]] = !{[[META4]], i64 8, !"double"} +// NEWSTRUCTPATHTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0, i64 4} +// NEWSTRUCTPATHTBAA: [[META3]] = !{[[META4:![0-9]+]], i64 4, !"float"} +// NEWSTRUCTPATHTBAA: [[META4]] = !{[[META5:![0-9]+]], i64 1, !"omnipotent char"} +// NEWSTRUCTPATHTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} +// NEWSTRUCTPATHTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0, i64 4} +// NEWSTRUCTPATHTBAA: [[META7]] = !{[[META4]], i64 4, !"int"} +// NEWSTRUCTPATHTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0, i64 8} +// NEWSTRUCTPATHTBAA: [[META9]] = !{[[META4]], i64 8, !"double"} //. //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -// NewStructPathTBAA: {{.*}} -// NoNewStructPathTBAA: {{.*}} +// NEWSTRUCTPATHTBAA: {{.*}} +// NONEWSTRUCTPATHTBAA: {{.*}}