[clang] [TBAA] Emit int TBAA metadata on FP math libcalls (PR #96025)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 25 04:22:28 PDT 2024


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

>From ed6292fd0e9119322c39e5f37e2225c76e324101 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Tue, 18 Jun 2024 09:21:07 -0400
Subject: [PATCH 1/4] [TBAA] Emit int TBAA metadata on FP math libcalls

Base on the discussion https://discourse.llvm.org/t/fp-can-we-add-pure-attribute-for-math-library-functions-default/79459,
math libcalls set errno, so it should emit "int" TBAA metadata on FP libcalls
to solve the alias issue.

Fix https://github.com/llvm/llvm-project/issues/86635
---
 clang/lib/CodeGen/CGBuiltin.cpp           | 33 ++++++++++++++++++++++-
 clang/test/CodeGen/math-libcalls-tbaa.cpp | 22 +++++++++++++++
 2 files changed, 54 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGen/math-libcalls-tbaa.cpp

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 08a89bd123d03..dc4af109cdbdb 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -707,7 +707,38 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
                               const CallExpr *E, llvm::Constant *calleeValue) {
   CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
   CGCallee callee = CGCallee::forDirect(calleeValue, GlobalDecl(FD));
-  return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
+  RValue Call =
+      CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
+
+  // Check the supported intrinsic.
+  if (unsigned BuiltinID = FD->getBuiltinID()) {
+    auto IntrinsicID = [&]() -> unsigned {
+      switch (BuiltinID) {
+      case Builtin::BIexpf:
+      case Builtin::BI__builtin_expf:
+      case Builtin::BI__builtin_expf128:
+        return true;
+      }
+      // TODO: support more FP math libcalls
+      return false;
+    }();
+
+    if (IntrinsicID) {
+      llvm::MDBuilder MDHelper(CGF.getLLVMContext());
+      MDNode *RootMD;
+      if (CGF.getLangOpts().CPlusPlus)
+        RootMD = MDHelper.createTBAARoot("Simple C++ TBAA");
+      else
+        RootMD = MDHelper.createTBAARoot("Simple C/C++ TBAA");
+      // Emit "int" TBAA metadata on FP math libcalls.
+      MDNode *AliasType = MDHelper.createTBAANode("int", RootMD);
+      MDNode *MDInt = MDHelper.createTBAAStructTagNode(AliasType, AliasType, 0);
+
+      Value *Val = Call.getScalarVal();
+      cast<llvm::Instruction>(Val)->setMetadata(LLVMContext::MD_tbaa, MDInt);
+    }
+  }
+  return Call;
 }
 
 /// Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.*
diff --git a/clang/test/CodeGen/math-libcalls-tbaa.cpp b/clang/test/CodeGen/math-libcalls-tbaa.cpp
new file mode 100644
index 0000000000000..d5b0741a476cb
--- /dev/null
+++ b/clang/test/CodeGen/math-libcalls-tbaa.cpp
@@ -0,0 +1,22 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
+// RUN:  %clang -S -O3 -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK
+
+#include <math.h>
+
+
+// Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis
+
+// CHECK-LABEL: define dso_local noundef float @_Z3fooPffi
+// CHECK-SAME: (ptr nocapture noundef readonly [[NUM:%.*]], float noundef [[R2INV:%.*]], i32 noundef [[N:%.*]]) 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 [[TBAA6:![0-9]+]]
+// CHECK-NEXT:    [[CALL_I:%.*]] = tail call noundef float @expf(float noundef [[TMP0]]) #[[ATTR2:[0-9]+]], !tbaa [[TBAA10:![0-9]+]]
+// CHECK-NEXT:    [[MUL:%.*]] = fmul float [[TMP0]], [[CALL_I]]
+// CHECK-NEXT:    ret float [[MUL]]
+//
+float foo (float num[], float r2inv, int n) {
+   const float expm2 =  std::exp(num[10]);  // Emit TBAA metadata on @expf
+   float tmp = expm2 * num[10];
+   return tmp;
+}

>From 9990877a2b9736c684c8cabeb03c6d98a3d078ce Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Thu, 20 Jun 2024 02:29:11 -0400
Subject: [PATCH 2/4] Address comment, reuse CodeGenTBAA::getRoot

---
 clang/lib/CodeGen/CGBuiltin.cpp           |  6 +-----
 clang/lib/CodeGen/CodeGenModule.h         |  2 ++
 clang/lib/CodeGen/CodeGenTBAA.h           |  8 ++++----
 clang/test/CodeGen/math-libcalls-tbaa.cpp | 20 +++++++++++++++-----
 4 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index dc4af109cdbdb..3f448e11bca1a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -725,11 +725,7 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
 
     if (IntrinsicID) {
       llvm::MDBuilder MDHelper(CGF.getLLVMContext());
-      MDNode *RootMD;
-      if (CGF.getLangOpts().CPlusPlus)
-        RootMD = MDHelper.createTBAARoot("Simple C++ TBAA");
-      else
-        RootMD = MDHelper.createTBAARoot("Simple C/C++ TBAA");
+      MDNode *RootMD = CGF.CGM.getTBAARoot();
       // Emit "int" TBAA metadata on FP math libcalls.
       MDNode *AliasType = MDHelper.createTBAANode("int", RootMD);
       MDNode *MDInt = MDHelper.createTBAAStructTagNode(AliasType, AliasType, 0);
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 9b63f47ef42cb..ea77007fdc48d 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -783,6 +783,8 @@ class CodeGenModule : public CodeGenTypeCache {
   CtorList &getGlobalCtors() { return GlobalCtors; }
   CtorList &getGlobalDtors() { return GlobalDtors; }
 
+  llvm::MDNode *getTBAARoot() { return TBAA->getRoot(); };
+
   /// getTBAATypeInfo - Get metadata used to describe accesses to objects of
   /// the given type.
   llvm::MDNode *getTBAATypeInfo(QualType QTy);
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index 5d9ecec3ff0fe..2a3a73bd3fd34 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -140,10 +140,6 @@ class CodeGenTBAA {
   llvm::MDNode *Root;
   llvm::MDNode *Char;
 
-  /// getRoot - This is the mdnode for the root of the metadata type graph
-  /// for this translation unit.
-  llvm::MDNode *getRoot();
-
   /// getChar - This is the mdnode for "char", which is special, and any types
   /// considered to be equivalent to it.
   llvm::MDNode *getChar();
@@ -178,6 +174,10 @@ class CodeGenTBAA {
               MangleContext &MContext);
   ~CodeGenTBAA();
 
+  /// getRoot - This is the mdnode for the root of the metadata type graph
+  /// for this translation unit.
+  llvm::MDNode *getRoot();
+
   /// getTypeInfo - Get metadata used to describe accesses to objects of the
   /// given type.
   llvm::MDNode *getTypeInfo(QualType QTy);
diff --git a/clang/test/CodeGen/math-libcalls-tbaa.cpp b/clang/test/CodeGen/math-libcalls-tbaa.cpp
index d5b0741a476cb..b0a748b86e423 100644
--- a/clang/test/CodeGen/math-libcalls-tbaa.cpp
+++ b/clang/test/CodeGen/math-libcalls-tbaa.cpp
@@ -1,14 +1,16 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The test may fail as time out on windows
+// REQUIRES: system-linux
+
 // RUN:  %clang -S -O3 -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK
 
 #include <math.h>
 
-
 // Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis
 
-// CHECK-LABEL: define dso_local noundef float @_Z3fooPffi
-// CHECK-SAME: (ptr nocapture noundef readonly [[NUM:%.*]], float noundef [[R2INV:%.*]], i32 noundef [[N:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-// CHECK-NEXT:  entry:
+// CHECK-LABEL: define dso_local noundef float @_Z3fooPffi(
+// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], float noundef [[R2INV:%.*]], i32 noundef [[N:%.*]]) 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 [[TBAA6:![0-9]+]]
 // CHECK-NEXT:    [[CALL_I:%.*]] = tail call noundef float @expf(float noundef [[TMP0]]) #[[ATTR2:[0-9]+]], !tbaa [[TBAA10:![0-9]+]]
@@ -20,3 +22,11 @@ float foo (float num[], float r2inv, int n) {
    float tmp = expm2 * num[10];
    return tmp;
 }
+//.
+// CHECK: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0}
+// CHECK: [[META7]] = !{!"float", [[META8:![0-9]+]], i64 0}
+// CHECK: [[META8]] = !{!"omnipotent char", [[META9:![0-9]+]], i64 0}
+// CHECK: [[META9]] = !{!"Simple C++ TBAA"}
+// CHECK: [[TBAA10]] = !{[[META11:![0-9]+]], [[META11]], i64 0}
+// CHECK: [[META11]] = !{!"int", [[META9]]}
+//.

>From 3f2c23e24e6329d7279aefd7b0b00baaf6a5b2c9 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Sat, 22 Jun 2024 03:30:03 -0400
Subject: [PATCH 3/4] Restrict to target system and update to
 createTBAAScalarTypeNode

---
 clang/lib/CodeGen/CGBuiltin.cpp           | 6 ++++--
 clang/test/CodeGen/math-libcalls-tbaa.cpp | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 3f448e11bca1a..71ba267ee1dd1 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -723,11 +723,13 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
       return false;
     }();
 
-    if (IntrinsicID) {
+    const llvm::Triple &T = CGF.getTarget().getTriple();
+    // Restrict to Linux because not all targets set errno, such as MacOS.
+    if (IntrinsicID && T.getOS() == llvm::Triple::Linux) {
       llvm::MDBuilder MDHelper(CGF.getLLVMContext());
       MDNode *RootMD = CGF.CGM.getTBAARoot();
       // Emit "int" TBAA metadata on FP math libcalls.
-      MDNode *AliasType = MDHelper.createTBAANode("int", RootMD);
+      MDNode *AliasType = MDHelper.createTBAAScalarTypeNode("int", RootMD);
       MDNode *MDInt = MDHelper.createTBAAStructTagNode(AliasType, AliasType, 0);
 
       Value *Val = Call.getScalarVal();
diff --git a/clang/test/CodeGen/math-libcalls-tbaa.cpp b/clang/test/CodeGen/math-libcalls-tbaa.cpp
index b0a748b86e423..ef70fa3518a21 100644
--- a/clang/test/CodeGen/math-libcalls-tbaa.cpp
+++ b/clang/test/CodeGen/math-libcalls-tbaa.cpp
@@ -28,5 +28,5 @@ float foo (float num[], float r2inv, int n) {
 // CHECK: [[META8]] = !{!"omnipotent char", [[META9:![0-9]+]], i64 0}
 // CHECK: [[META9]] = !{!"Simple C++ TBAA"}
 // CHECK: [[TBAA10]] = !{[[META11:![0-9]+]], [[META11]], i64 0}
-// CHECK: [[META11]] = !{!"int", [[META9]]}
+// CHECK: [[META11]] = !{!"int", [[META9]], i64 0}
 //.

>From 6be8a2a55c325237c1272f15271ffce6860f14b4 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Tue, 25 Jun 2024 01:06:54 -0400
Subject: [PATCH 4/4] support new-struct-path-tbaa and update with
 getTBAATypeInfo

---
 clang/lib/CodeGen/CGBuiltin.cpp           | 15 ++++++++------
 clang/lib/CodeGen/CodeGenModule.h         |  2 --
 clang/lib/CodeGen/CodeGenTBAA.h           |  8 ++++----
 clang/test/CodeGen/math-libcalls-tbaa.cpp | 25 ++++++++++++++++-------
 4 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 71ba267ee1dd1..a7970e5b8d10d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -723,15 +723,18 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
       return false;
     }();
 
-    const llvm::Triple &T = CGF.getTarget().getTriple();
-    // Restrict to Linux because not all targets set errno, such as MacOS.
-    if (IntrinsicID && T.getOS() == llvm::Triple::Linux) {
+    // Restrict to target with errno, for example, MacOS doesn't set errno.
+    if (IntrinsicID && CGF.CGM.getLangOpts().MathErrno) {
       llvm::MDBuilder MDHelper(CGF.getLLVMContext());
-      MDNode *RootMD = CGF.CGM.getTBAARoot();
+      ASTContext &Context = CGF.getContext();
       // Emit "int" TBAA metadata on FP math libcalls.
-      MDNode *AliasType = MDHelper.createTBAAScalarTypeNode("int", RootMD);
+      clang::QualType IntTy = Context.IntTy;
+      MDNode *AliasType = CGF.CGM.getTBAATypeInfo(IntTy);
       MDNode *MDInt = MDHelper.createTBAAStructTagNode(AliasType, AliasType, 0);
-
+      if (CGF.CGM.getCodeGenOpts().NewStructPathTBAA) {
+        uint64_t Size = Context.getTypeSizeInChars(IntTy).getQuantity();
+        MDInt = MDHelper.createTBAAAccessTag(AliasType, AliasType, 0, Size);
+      }
       Value *Val = Call.getScalarVal();
       cast<llvm::Instruction>(Val)->setMetadata(LLVMContext::MD_tbaa, MDInt);
     }
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index ea77007fdc48d..9b63f47ef42cb 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -783,8 +783,6 @@ class CodeGenModule : public CodeGenTypeCache {
   CtorList &getGlobalCtors() { return GlobalCtors; }
   CtorList &getGlobalDtors() { return GlobalDtors; }
 
-  llvm::MDNode *getTBAARoot() { return TBAA->getRoot(); };
-
   /// getTBAATypeInfo - Get metadata used to describe accesses to objects of
   /// the given type.
   llvm::MDNode *getTBAATypeInfo(QualType QTy);
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index 2a3a73bd3fd34..5d9ecec3ff0fe 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -140,6 +140,10 @@ class CodeGenTBAA {
   llvm::MDNode *Root;
   llvm::MDNode *Char;
 
+  /// getRoot - This is the mdnode for the root of the metadata type graph
+  /// for this translation unit.
+  llvm::MDNode *getRoot();
+
   /// getChar - This is the mdnode for "char", which is special, and any types
   /// considered to be equivalent to it.
   llvm::MDNode *getChar();
@@ -174,10 +178,6 @@ class CodeGenTBAA {
               MangleContext &MContext);
   ~CodeGenTBAA();
 
-  /// getRoot - This is the mdnode for the root of the metadata type graph
-  /// for this translation unit.
-  llvm::MDNode *getRoot();
-
   /// getTypeInfo - Get metadata used to describe accesses to objects of the
   /// given type.
   llvm::MDNode *getTypeInfo(QualType QTy);
diff --git a/clang/test/CodeGen/math-libcalls-tbaa.cpp b/clang/test/CodeGen/math-libcalls-tbaa.cpp
index ef70fa3518a21..37cf5dae10f40 100644
--- a/clang/test/CodeGen/math-libcalls-tbaa.cpp
+++ b/clang/test/CodeGen/math-libcalls-tbaa.cpp
@@ -2,7 +2,8 @@
 // The test may fail as time out on windows
 // REQUIRES: system-linux
 
-// RUN:  %clang -S -O3 -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK
+// RUN:  %clang -S -O3 -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,NoNewStructPathTBAA
+// RUN:  %clang -S -O3 -Xclang -new-struct-path-tbaa -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,NewStructPathTBAA
 
 #include <math.h>
 
@@ -23,10 +24,20 @@ float foo (float num[], float r2inv, int n) {
    return tmp;
 }
 //.
-// CHECK: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0}
-// CHECK: [[META7]] = !{!"float", [[META8:![0-9]+]], i64 0}
-// CHECK: [[META8]] = !{!"omnipotent char", [[META9:![0-9]+]], i64 0}
-// CHECK: [[META9]] = !{!"Simple C++ TBAA"}
-// CHECK: [[TBAA10]] = !{[[META11:![0-9]+]], [[META11]], i64 0}
-// CHECK: [[META11]] = !{!"int", [[META9]], i64 0}
+// NoNewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0}
+// NoNewStructPathTBAA: [[META7]] = !{!"float", [[META8:![0-9]+]], i64 0}
+// NoNewStructPathTBAA: [[META8]] = !{!"omnipotent char", [[META9:![0-9]+]], i64 0}
+// NoNewStructPathTBAA: [[META9]] = !{!"Simple C++ TBAA"}
+// NoNewStructPathTBAA: [[TBAA10]] = !{[[META11:![0-9]+]], [[META11]], i64 0}
+// NoNewStructPathTBAA: [[META11]] = !{!"int", [[META8]], i64 0}
 //.
+// NewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0, i64 4}
+// NewStructPathTBAA: [[META7]] = !{[[META8:![0-9]+]], i64 4, !"float"}
+// NewStructPathTBAA: [[META8]] = !{[[META9:![0-9]+]], i64 1, !"omnipotent char"}
+// NewStructPathTBAA: [[META9]] = !{!"Simple C++ TBAA"}
+// NewStructPathTBAA: [[TBAA10]] = !{[[META11:![0-9]+]], [[META11]], i64 0, i64 4}
+// NewStructPathTBAA: [[META11]] = !{[[META8]], i64 4, !"int"}
+//.
+//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+// NewStructPathTBAA: {{.*}}
+// NoNewStructPathTBAA: {{.*}}



More information about the cfe-commits mailing list