[clang] [clang codegen] Emit int TBAA metadata on more FP math libcalls (PR #100302)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 29 20:59:35 PDT 2024


https://github.com/vfdff updated https://github.com/llvm/llvm-project/pull/100302

>From c750234674531788ee26958954a5f9a6b59ea866 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Tue, 23 Jul 2024 23:10:42 -0400
Subject: [PATCH 1/5] [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 <zhongyunde at huawei.com>
Date: Wed, 24 Jul 2024 03:38:42 -0400
Subject: [PATCH 2/5] 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 <zhongyunde at huawei.com>
Date: Thu, 25 Jul 2024 07:42:57 -0400
Subject: [PATCH 3/5] 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 <zhongyunde at huawei.com>
Date: Sun, 28 Jul 2024 20:51:28 -0400
Subject: [PATCH 4/5] 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 <zhongyunde at huawei.com>
Date: Mon, 29 Jul 2024 23:25:54 -0400
Subject: [PATCH 5/5] 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);



More information about the cfe-commits mailing list