[llvm] [CFI][annotation] Leave alone function pointers in function annotations (PR #80173)

via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 10:51:59 PST 2024


https://github.com/yozhu updated https://github.com/llvm/llvm-project/pull/80173

>From c91a3a6f07488703d9f939a0d2477023589fc1fe Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at meta.com>
Date: Thu, 25 Jan 2024 20:37:10 -0800
Subject: [PATCH 1/7] [CFI][annotation] Leave alone function pointers in
 function annotations

Function annotation, as part of llvm.metadata, is for the function itself
and doesn't apply to its corresponding jump table entry, so with CFI we
shouldn't replace function pointer in function annotation with pointer to
its corresponding jump table entry.
---
 llvm/lib/Transforms/IPO/LowerTypeTests.cpp | 30 +++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index 733f290b1bc93a..f6630019eaec66 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -470,6 +470,9 @@ class LowerTypeTestsModule {
 
   Function *WeakInitializerFn = nullptr;
 
+  GlobalVariable *GlobalAnnotation;
+  std::set<void *> FunctionAnnotations;
+
   bool shouldExportConstantsAsAbsoluteSymbols();
   uint8_t *exportTypeId(StringRef TypeId, const TypeIdLowering &TIL);
   TypeIdLowering importTypeId(StringRef TypeId);
@@ -531,6 +534,10 @@ class LowerTypeTestsModule {
   /// replace each use, which is a direct function call.
   void replaceDirectCalls(Value *Old, Value *New);
 
+  bool isFunctionAnnotation(void *GV) {
+    return FunctionAnnotations.count(GV) != 0;
+  }
+
 public:
   LowerTypeTestsModule(Module &M, ModuleAnalysisManager &AM,
                        ModuleSummaryIndex *ExportSummary,
@@ -1377,8 +1384,11 @@ void LowerTypeTestsModule::replaceWeakDeclarationWithJumpTablePtr(
   // (all?) targets. Switch to a runtime initializer.
   SmallSetVector<GlobalVariable *, 8> GlobalVarUsers;
   findGlobalVariableUsersOf(F, GlobalVarUsers);
-  for (auto *GV : GlobalVarUsers)
+  for (auto *GV : GlobalVarUsers) {
+    if (GV == GlobalAnnotation)
+      continue;
     moveInitializerToModuleConstructor(GV);
+  }
 
   // Can not RAUW F with an expression that uses F. Replace with a temporary
   // placeholder first.
@@ -1392,6 +1402,10 @@ void LowerTypeTestsModule::replaceWeakDeclarationWithJumpTablePtr(
   // Don't use range based loop, because use list will be modified.
   while (!PlaceholderFn->use_empty()) {
     Use &U = *PlaceholderFn->use_begin();
+    if (isFunctionAnnotation(U.getUser())) {
+      U.set(F);
+      continue;
+    }
     auto *InsertPt = dyn_cast<Instruction>(U.getUser());
     assert(InsertPt && "Non-instruction users should have been eliminated");
     auto *PN = dyn_cast<PHINode>(InsertPt);
@@ -1837,6 +1851,16 @@ LowerTypeTestsModule::LowerTypeTestsModule(
   }
   OS = TargetTriple.getOS();
   ObjectFormat = TargetTriple.getObjectFormat();
+
+  // Function annotation describes or applies to function itself, and
+  // shouldn't be associated with jump table thunk generated for CFI.
+  GlobalAnnotation = M.getGlobalVariable("llvm.global.annotations");
+  auto *C = dyn_cast_or_null<Constant>(GlobalAnnotation);
+  if (C && C->getNumOperands() == 1) {
+    C = cast<Constant>(C->getOperand(0));
+    for (auto &Op : C->operands())
+      FunctionAnnotations.insert(Op.get());
+  }
 }
 
 bool LowerTypeTestsModule::runForTesting(Module &M, ModuleAnalysisManager &AM) {
@@ -1900,6 +1924,10 @@ void LowerTypeTestsModule::replaceCfiUses(Function *Old, Value *New,
     if (isDirectCall(U) && (Old->isDSOLocal() || !IsJumpTableCanonical))
       continue;
 
+    // Skip function annotation
+    if (isFunctionAnnotation(U.getUser()))
+      continue;
+
     // Must handle Constants specially, we cannot call replaceUsesOfWith on a
     // constant because they are uniqued.
     if (auto *C = dyn_cast<Constant>(U.getUser())) {

>From a6fef79167066afdf715c6f1bb7834a9d04d575e Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Wed, 31 Jan 2024 23:48:21 -0800
Subject: [PATCH 2/7] Address review feedback

---
 llvm/lib/Transforms/IPO/LowerTypeTests.cpp    | 16 ++++-----
 llvm/test/CodeGen/AArch64/cfi-annotation.test | 35 +++++++++++++++++++
 2 files changed, 43 insertions(+), 8 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/cfi-annotation.test

diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index f6630019eaec66..e5e7a022763c0e 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -471,7 +471,7 @@ class LowerTypeTestsModule {
   Function *WeakInitializerFn = nullptr;
 
   GlobalVariable *GlobalAnnotation;
-  std::set<void *> FunctionAnnotations;
+  DenseSet<Value *> FunctionAnnotations;
 
   bool shouldExportConstantsAsAbsoluteSymbols();
   uint8_t *exportTypeId(StringRef TypeId, const TypeIdLowering &TIL);
@@ -534,8 +534,8 @@ class LowerTypeTestsModule {
   /// replace each use, which is a direct function call.
   void replaceDirectCalls(Value *Old, Value *New);
 
-  bool isFunctionAnnotation(void *GV) {
-    return FunctionAnnotations.count(GV) != 0;
+  bool isFunctionAnnotation(Value *V) {
+    return FunctionAnnotations.count(V) != 0;
   }
 
 public:
@@ -1855,11 +1855,11 @@ LowerTypeTestsModule::LowerTypeTestsModule(
   // Function annotation describes or applies to function itself, and
   // shouldn't be associated with jump table thunk generated for CFI.
   GlobalAnnotation = M.getGlobalVariable("llvm.global.annotations");
-  auto *C = dyn_cast_or_null<Constant>(GlobalAnnotation);
-  if (C && C->getNumOperands() == 1) {
-    C = cast<Constant>(C->getOperand(0));
-    for (auto &Op : C->operands())
-      FunctionAnnotations.insert(Op.get());
+  if (GlobalAnnotation && GlobalAnnotation->getNumOperands() == 1) {
+    const ConstantArray *CA =
+        cast<ConstantArray>(GlobalAnnotation->getOperand(0));
+    for (Value *Op : CA->operands())
+      FunctionAnnotations.insert(Op);
   }
 }
 
diff --git a/llvm/test/CodeGen/AArch64/cfi-annotation.test b/llvm/test/CodeGen/AArch64/cfi-annotation.test
new file mode 100644
index 00000000000000..d1191a66ea1a5c
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cfi-annotation.test
@@ -0,0 +1,35 @@
+; RUN: echo -e "int (*fptr1)(int);"                                        > %t.c
+; RUN: echo -e "int (*fptr2)(int);"                                       >> %t.c
+; RUN: echo -e "__attribute__((annotate(\"test_foo\"))) int foo(int);"    >> %t.c
+; RUN: echo -e "__attribute__((annotate(\"test_goo\"))) int goo(int);"    >> %t.c
+; RUN: echo -e "__attribute__((annotate(\"test_bar\"))) int bar(int x) {" >> %t.c
+; RUN: echo -e "  return foo(x) + goo(x);"                                >> %t.c
+; RUN: echo -e "}"                                                        >> %t.c
+; RUN: echo -e "int test(int x) {"                                        >> %t.c
+; RUN: echo -e "  if (x > 10) {"                                          >> %t.c
+; RUN: echo -e "    fptr1 = bar;"                                         >> %t.c
+; RUN: echo -e "    fptr2 = foo;"                                         >> %t.c
+; RUN: echo -e "  } else if (x > 0) {"                                    >> %t.c
+; RUN: echo -e "    fptr1 = bar;"                                         >> %t.c
+; RUN: echo -e "    fptr2 = goo;"                                         >> %t.c
+; RUN: echo -e "  } else {"                                               >> %t.c
+; RUN: echo -e "    fptr1 = goo;"                                         >> %t.c
+; RUN: echo -e "    fptr2 = foo;"                                         >> %t.c
+; RUN: echo -e "  }"                                                      >> %t.c
+; RUN: echo -e "  return fptr1(fptr2(x));"                                >> %t.c
+; RUN: echo -e "}"                                                        >> %t.c
+
+; RUN: clang -target aarch64-none-linux-gnu -c -o %t.o -fPIC -flto=full \
+; RUN: -fno-sanitize-cfi-canonical-jump-tables -fsanitize=cfi-icall \
+; RUN: -fno-sanitize-ignorelist %t.c
+; RUN: ld.lld -shared -o %t.so %t.o --save-temps
+; RUN: llvm-dis %t.so.0.4.opt.bc
+
+; REM: Find the `llvm.global.annotations` symbol in `%t.so.0.4.opt.ll` and
+: REM: verify that no function annotation references CFI jump table entry.
+
+; RUN: grep llvm.global.annotations %t.so.0.4.opt.ll > %t.annotations
+; RUN: grep bar %t.annotations
+; RUN: grep foo %t.annotations
+; RUN: grep goo %t.annotations
+; RUN: not grep cfi %t.annotations

>From f8cfc2dd567ffd842c362eb9b8bd7356930e3e37 Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Thu, 1 Feb 2024 13:50:23 -0800
Subject: [PATCH 3/7] Address review feedback 2

---
 llvm/lib/Transforms/IPO/LowerTypeTests.cpp    |  12 +-
 llvm/test/CodeGen/AArch64/cfi-annotation.ll   | 112 ++++++++++++++++++
 llvm/test/CodeGen/AArch64/cfi-annotation.test |  35 ------
 3 files changed, 116 insertions(+), 43 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/cfi-annotation.ll
 delete mode 100644 llvm/test/CodeGen/AArch64/cfi-annotation.test

diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index e5e7a022763c0e..da27b7dd755f78 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -534,8 +534,8 @@ class LowerTypeTestsModule {
   /// replace each use, which is a direct function call.
   void replaceDirectCalls(Value *Old, Value *New);
 
-  bool isFunctionAnnotation(Value *V) {
-    return FunctionAnnotations.count(V) != 0;
+  bool isFunctionAnnotation(Value *V) const {
+    return FunctionAnnotations.contains(V);
   }
 
 public:
@@ -1402,10 +1402,6 @@ void LowerTypeTestsModule::replaceWeakDeclarationWithJumpTablePtr(
   // Don't use range based loop, because use list will be modified.
   while (!PlaceholderFn->use_empty()) {
     Use &U = *PlaceholderFn->use_begin();
-    if (isFunctionAnnotation(U.getUser())) {
-      U.set(F);
-      continue;
-    }
     auto *InsertPt = dyn_cast<Instruction>(U.getUser());
     assert(InsertPt && "Non-instruction users should have been eliminated");
     auto *PN = dyn_cast<PHINode>(InsertPt);
@@ -1855,9 +1851,9 @@ LowerTypeTestsModule::LowerTypeTestsModule(
   // Function annotation describes or applies to function itself, and
   // shouldn't be associated with jump table thunk generated for CFI.
   GlobalAnnotation = M.getGlobalVariable("llvm.global.annotations");
-  if (GlobalAnnotation && GlobalAnnotation->getNumOperands() == 1) {
+  if (GlobalAnnotation && GlobalAnnotation->hasInitializer()) {
     const ConstantArray *CA =
-        cast<ConstantArray>(GlobalAnnotation->getOperand(0));
+        cast<ConstantArray>(GlobalAnnotation->getInitializer());
     for (Value *Op : CA->operands())
       FunctionAnnotations.insert(Op);
   }
diff --git a/llvm/test/CodeGen/AArch64/cfi-annotation.ll b/llvm/test/CodeGen/AArch64/cfi-annotation.ll
new file mode 100644
index 00000000000000..065289cc39ec4c
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/cfi-annotation.ll
@@ -0,0 +1,112 @@
+; RUN: opt %s -o %t.bc
+; RUN: llvm-lto2 run %t.bc -r %t.bc,bar,px -r %t.bc,foo,px -r %t.bc,test,px \
+; RUN: -r %t.bc,fptr1,px -r %t.bc,fptr2,px -save-temps -o %t.o
+; RUN: llvm-dis %t.*.opt.bc
+
+; REM: Find the `llvm.global.annotations` symbol in `%t.*.opt.ll` and
+; REM: verify that no function annotation references CFI jump table entry.
+
+; RUN: grep llvm.global.annotations %t.*.opt.ll > %t.annotations
+; RUN: grep bar %t.annotations
+; RUN: grep foo %t.annotations
+; RUN: not grep cfi %t.annotations
+
+; ModuleID = 'cfi-annotation'
+source_filename = "ld-temp.o"
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-gnu"
+
+ at llvm.global.annotations = appending global [2 x { ptr, ptr, ptr, i32, ptr }] [{ ptr, ptr, ptr, i32, ptr } { ptr @bar, ptr @.str, ptr @.str.1, i32 4, ptr null }, { ptr, ptr, ptr, i32, ptr } { ptr @foo, ptr @.str.2, ptr @.str.1, i32 3, ptr null }], section "llvm.metadata"
+ at fptr1 = global ptr null, align 8
+ at fptr2 = global ptr null, align 8
+ at .str = private unnamed_addr constant [9 x i8] c"test_bar\00", section "llvm.metadata"
+ at .str.1 = private unnamed_addr constant [17 x i8] c"cfi-annotation.c\00", section "llvm.metadata"
+ at .str.2 = private unnamed_addr constant [9 x i8] c"test_foo\00", section "llvm.metadata"
+
+; Function Attrs: noinline nounwind optnone uwtable
+define i32 @bar(i32 noundef %0) #0 !type !8 !type !9 {
+  %2 = alloca i32, align 4
+  store i32 %0, ptr %2, align 4
+  %3 = load i32, ptr %2, align 4
+  %4 = add nsw i32 %3, -1
+  store i32 %4, ptr %2, align 4
+  %5 = call i32 @foo(i32 noundef %4)
+  %6 = load i32, ptr %2, align 4
+  %7 = add nsw i32 %6, 1
+  store i32 %7, ptr %2, align 4
+  %8 = call i32 @foo(i32 noundef %7)
+  %9 = add nsw i32 %5, %8
+  ret i32 %9
+}
+
+declare !type !8 !type !9 i32 @foo(i32 noundef) #1
+
+; Function Attrs: noinline nounwind optnone uwtable
+define i32 @test(i32 noundef %0) #0 !type !8 !type !9 {
+  %2 = alloca i32, align 4
+  store i32 %0, ptr %2, align 4
+  %3 = load i32, ptr %2, align 4
+  %4 = icmp sgt i32 %3, 0
+  br i1 %4, label %5, label %6
+
+5:                                                ; preds = %1
+  store ptr @bar, ptr @fptr1, align 8
+  store ptr @foo, ptr @fptr2, align 8
+  br label %7
+
+6:                                                ; preds = %1
+  store ptr @bar, ptr @fptr1, align 8
+  store ptr @foo, ptr @fptr2, align 8
+  br label %7
+
+7:                                                ; preds = %6, %5
+  %8 = load ptr, ptr @fptr1, align 8
+  %9 = call i1 @llvm.type.test(ptr %8, metadata !"_ZTSFiiE"), !nosanitize !10
+  br i1 %9, label %11, label %10, !nosanitize !10
+
+10:                                               ; preds = %7
+  call void @llvm.ubsantrap(i8 2) #4, !nosanitize !10
+  unreachable, !nosanitize !10
+
+11:                                               ; preds = %7
+  %12 = load ptr, ptr @fptr2, align 8
+  %13 = call i1 @llvm.type.test(ptr %12, metadata !"_ZTSFiiE"), !nosanitize !10
+  br i1 %13, label %15, label %14, !nosanitize !10
+
+14:                                               ; preds = %11
+  call void @llvm.ubsantrap(i8 2) #4, !nosanitize !10
+  unreachable, !nosanitize !10
+
+15:                                               ; preds = %11
+  %16 = load i32, ptr %2, align 4
+  %17 = call i32 %12(i32 noundef %16)
+  %18 = call i32 %8(i32 noundef %17)
+  ret i32 %18
+}
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare i1 @llvm.type.test(ptr, metadata) #2
+
+; Function Attrs: cold noreturn nounwind
+declare void @llvm.ubsantrap(i8 immarg) #3
+
+attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
+attributes #1 = { "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
+attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #3 = { cold noreturn nounwind }
+attributes #4 = { noreturn nounwind }
+
+!llvm.ident = !{!0}
+!llvm.module.flags = !{!1, !2, !3, !4, !5, !6, !7}
+
+!0 = !{!"clang version 19.0.0git (https://github.com/yozhu/llvm-project.git a6fef79167066afdf715c6f1bb7834a9d04d575e)"}
+!1 = !{i32 1, !"wchar_size", i32 4}
+!2 = !{i32 4, !"CFI Canonical Jump Tables", i32 0}
+!3 = !{i32 8, !"PIC Level", i32 2}
+!4 = !{i32 7, !"uwtable", i32 2}
+!5 = !{i32 7, !"frame-pointer", i32 1}
+!6 = !{i32 1, !"ThinLTO", i32 0}
+!7 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
+!8 = !{i64 0, !"_ZTSFiiE"}
+!9 = !{i64 0, !"_ZTSFiiE.generalized"}
+!10 = !{}
diff --git a/llvm/test/CodeGen/AArch64/cfi-annotation.test b/llvm/test/CodeGen/AArch64/cfi-annotation.test
deleted file mode 100644
index d1191a66ea1a5c..00000000000000
--- a/llvm/test/CodeGen/AArch64/cfi-annotation.test
+++ /dev/null
@@ -1,35 +0,0 @@
-; RUN: echo -e "int (*fptr1)(int);"                                        > %t.c
-; RUN: echo -e "int (*fptr2)(int);"                                       >> %t.c
-; RUN: echo -e "__attribute__((annotate(\"test_foo\"))) int foo(int);"    >> %t.c
-; RUN: echo -e "__attribute__((annotate(\"test_goo\"))) int goo(int);"    >> %t.c
-; RUN: echo -e "__attribute__((annotate(\"test_bar\"))) int bar(int x) {" >> %t.c
-; RUN: echo -e "  return foo(x) + goo(x);"                                >> %t.c
-; RUN: echo -e "}"                                                        >> %t.c
-; RUN: echo -e "int test(int x) {"                                        >> %t.c
-; RUN: echo -e "  if (x > 10) {"                                          >> %t.c
-; RUN: echo -e "    fptr1 = bar;"                                         >> %t.c
-; RUN: echo -e "    fptr2 = foo;"                                         >> %t.c
-; RUN: echo -e "  } else if (x > 0) {"                                    >> %t.c
-; RUN: echo -e "    fptr1 = bar;"                                         >> %t.c
-; RUN: echo -e "    fptr2 = goo;"                                         >> %t.c
-; RUN: echo -e "  } else {"                                               >> %t.c
-; RUN: echo -e "    fptr1 = goo;"                                         >> %t.c
-; RUN: echo -e "    fptr2 = foo;"                                         >> %t.c
-; RUN: echo -e "  }"                                                      >> %t.c
-; RUN: echo -e "  return fptr1(fptr2(x));"                                >> %t.c
-; RUN: echo -e "}"                                                        >> %t.c
-
-; RUN: clang -target aarch64-none-linux-gnu -c -o %t.o -fPIC -flto=full \
-; RUN: -fno-sanitize-cfi-canonical-jump-tables -fsanitize=cfi-icall \
-; RUN: -fno-sanitize-ignorelist %t.c
-; RUN: ld.lld -shared -o %t.so %t.o --save-temps
-; RUN: llvm-dis %t.so.0.4.opt.bc
-
-; REM: Find the `llvm.global.annotations` symbol in `%t.so.0.4.opt.ll` and
-: REM: verify that no function annotation references CFI jump table entry.
-
-; RUN: grep llvm.global.annotations %t.so.0.4.opt.ll > %t.annotations
-; RUN: grep bar %t.annotations
-; RUN: grep foo %t.annotations
-; RUN: grep goo %t.annotations
-; RUN: not grep cfi %t.annotations

>From b8e7d0a7423b2fb7b03a32128bf2af4a5e428acc Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Fri, 2 Feb 2024 10:35:36 -0800
Subject: [PATCH 4/7] Address review feedback 3

---
 llvm/lib/Transforms/IPO/LowerTypeTests.cpp  |  4 ++--
 llvm/test/CodeGen/AArch64/cfi-annotation.ll | 20 +++++++++++---------
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index da27b7dd755f78..633fcb3314c42f 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -1916,11 +1916,11 @@ void LowerTypeTestsModule::replaceCfiUses(Function *Old, Value *New,
     if (isa<BlockAddress, NoCFIValue>(U.getUser()))
       continue;
 
-    // Skip direct calls to externally defined or non-dso_local functions
+    // Skip direct calls to externally defined or non-dso_local functions.
     if (isDirectCall(U) && (Old->isDSOLocal() || !IsJumpTableCanonical))
       continue;
 
-    // Skip function annotation
+    // Skip function annotation.
     if (isFunctionAnnotation(U.getUser()))
       continue;
 
diff --git a/llvm/test/CodeGen/AArch64/cfi-annotation.ll b/llvm/test/CodeGen/AArch64/cfi-annotation.ll
index 065289cc39ec4c..71859fa84ce328 100644
--- a/llvm/test/CodeGen/AArch64/cfi-annotation.ll
+++ b/llvm/test/CodeGen/AArch64/cfi-annotation.ll
@@ -1,15 +1,17 @@
 ; RUN: opt %s -o %t.bc
-; RUN: llvm-lto2 run %t.bc -r %t.bc,bar,px -r %t.bc,foo,px -r %t.bc,test,px \
-; RUN: -r %t.bc,fptr1,px -r %t.bc,fptr2,px -save-temps -o %t.o
-; RUN: llvm-dis %t.*.opt.bc
+; RUN: opt -passes=lowertypetests %t.bc -o %t.o
 
-; REM: Find the `llvm.global.annotations` symbol in `%t.*.opt.ll` and
-; REM: verify that no function annotation references CFI jump table entry.
+; REM: Find the `llvm.global.annotations` symbol in `%t.*.ll` and verify
+; REM: that no function annotation references CFI jump table entry.
 
-; RUN: grep llvm.global.annotations %t.*.opt.ll > %t.annotations
-; RUN: grep bar %t.annotations
-; RUN: grep foo %t.annotations
-; RUN: not grep cfi %t.annotations
+; RUN: llvm-dis %t.o -o - | FileCheck %s --check-prefix=CHECK-bar
+; CHECK-bar: {{llvm.global.annotations = .*bar, }}
+
+; RUN: llvm-dis %t.o -o - | FileCheck %s --check-prefix=CHECK-foo
+; CHECK-foo: {{llvm.global.annotations = .*foo, }}
+
+; RUN: llvm-dis %t.o -o - | FileCheck %s --check-prefix=CHECK-cfi
+; CHECK-cfi-NOT: {{llvm.global.annotations = .*cfi.*}}
 
 ; ModuleID = 'cfi-annotation'
 source_filename = "ld-temp.o"

>From 083cb199d5090acf734c2613d232e7926e783158 Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Tue, 6 Feb 2024 09:43:26 -0800
Subject: [PATCH 5/7] Address review feedback 4

---
 .../LowerTypeTests}/cfi-annotation.ll             | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)
 rename llvm/test/{CodeGen/AArch64 => Transforms/LowerTypeTests}/cfi-annotation.ll (89%)

diff --git a/llvm/test/CodeGen/AArch64/cfi-annotation.ll b/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll
similarity index 89%
rename from llvm/test/CodeGen/AArch64/cfi-annotation.ll
rename to llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll
index 71859fa84ce328..83d5da48ab91b6 100644
--- a/llvm/test/CodeGen/AArch64/cfi-annotation.ll
+++ b/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll
@@ -1,21 +1,14 @@
-; RUN: opt %s -o %t.bc
-; RUN: opt -passes=lowertypetests %t.bc -o %t.o
+; RUN: opt -passes=lowertypetests %s -o %t.o
 
 ; REM: Find the `llvm.global.annotations` symbol in `%t.*.ll` and verify
 ; REM: that no function annotation references CFI jump table entry.
 
-; RUN: llvm-dis %t.o -o - | FileCheck %s --check-prefix=CHECK-bar
-; CHECK-bar: {{llvm.global.annotations = .*bar, }}
-
-; RUN: llvm-dis %t.o -o - | FileCheck %s --check-prefix=CHECK-foo
-; CHECK-foo: {{llvm.global.annotations = .*foo, }}
+; RUN: llvm-dis %t.o -o - | FileCheck %s --check-prefix=CHECK-foobar
+; CHECK-foobar: {{llvm.global.annotations = .*[foo|bar], .*[foo|bar],}}
 
 ; RUN: llvm-dis %t.o -o - | FileCheck %s --check-prefix=CHECK-cfi
 ; CHECK-cfi-NOT: {{llvm.global.annotations = .*cfi.*}}
 
-; ModuleID = 'cfi-annotation'
-source_filename = "ld-temp.o"
-target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 target triple = "aarch64-none-linux-gnu"
 
 @llvm.global.annotations = appending global [2 x { ptr, ptr, ptr, i32, ptr }] [{ ptr, ptr, ptr, i32, ptr } { ptr @bar, ptr @.str, ptr @.str.1, i32 4, ptr null }, { ptr, ptr, ptr, i32, ptr } { ptr @foo, ptr @.str.2, ptr @.str.1, i32 3, ptr null }], section "llvm.metadata"
@@ -101,7 +94,7 @@ attributes #4 = { noreturn nounwind }
 !llvm.ident = !{!0}
 !llvm.module.flags = !{!1, !2, !3, !4, !5, !6, !7}
 
-!0 = !{!"clang version 19.0.0git (https://github.com/yozhu/llvm-project.git a6fef79167066afdf715c6f1bb7834a9d04d575e)"}
+!0 = !{!"clang version 19.0.0git"}
 !1 = !{i32 1, !"wchar_size", i32 4}
 !2 = !{i32 4, !"CFI Canonical Jump Tables", i32 0}
 !3 = !{i32 8, !"PIC Level", i32 2}

>From 40eef6f1378df9b241346fa19df6f86e27ec4088 Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Wed, 7 Feb 2024 10:00:34 -0800
Subject: [PATCH 6/7] Remove unnecessary stuff from the test

---
 .../LowerTypeTests/cfi-annotation.ll          | 129 +++++-------------
 1 file changed, 34 insertions(+), 95 deletions(-)

diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll b/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll
index 83d5da48ab91b6..c5d4822a009e5e 100644
--- a/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll
+++ b/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll
@@ -1,107 +1,46 @@
 ; RUN: opt -passes=lowertypetests %s -o %t.o
-
-; REM: Find the `llvm.global.annotations` symbol in `%t.*.ll` and verify
-; REM: that no function annotation references CFI jump table entry.
-
 ; RUN: llvm-dis %t.o -o - | FileCheck %s --check-prefix=CHECK-foobar
 ; CHECK-foobar: {{llvm.global.annotations = .*[foo|bar], .*[foo|bar],}}
-
 ; RUN: llvm-dis %t.o -o - | FileCheck %s --check-prefix=CHECK-cfi
 ; CHECK-cfi-NOT: {{llvm.global.annotations = .*cfi.*}}
 
 target triple = "aarch64-none-linux-gnu"
 
- at llvm.global.annotations = appending global [2 x { ptr, ptr, ptr, i32, ptr }] [{ ptr, ptr, ptr, i32, ptr } { ptr @bar, ptr @.str, ptr @.str.1, i32 4, ptr null }, { ptr, ptr, ptr, i32, ptr } { ptr @foo, ptr @.str.2, ptr @.str.1, i32 3, ptr null }], section "llvm.metadata"
- at fptr1 = global ptr null, align 8
- at fptr2 = global ptr null, align 8
- at .str = private unnamed_addr constant [9 x i8] c"test_bar\00", section "llvm.metadata"
- at .str.1 = private unnamed_addr constant [17 x i8] c"cfi-annotation.c\00", section "llvm.metadata"
- at .str.2 = private unnamed_addr constant [9 x i8] c"test_foo\00", section "llvm.metadata"
-
-; Function Attrs: noinline nounwind optnone uwtable
-define i32 @bar(i32 noundef %0) #0 !type !8 !type !9 {
-  %2 = alloca i32, align 4
-  store i32 %0, ptr %2, align 4
-  %3 = load i32, ptr %2, align 4
-  %4 = add nsw i32 %3, -1
-  store i32 %4, ptr %2, align 4
-  %5 = call i32 @foo(i32 noundef %4)
-  %6 = load i32, ptr %2, align 4
-  %7 = add nsw i32 %6, 1
-  store i32 %7, ptr %2, align 4
-  %8 = call i32 @foo(i32 noundef %7)
-  %9 = add nsw i32 %5, %8
-  ret i32 %9
+ at fptr = global ptr null, align 8
+ at .src = private unnamed_addr constant [7 x i8] c"test.c\00", align 1
+ at anon.eb4aa7a5d41c72267995d92d93c37bde.0 = private unnamed_addr constant { i16, i16, [14 x i8] } { i16 -1, i16 0, [14 x i8] c"'void (void)'\00" }
+ at .str = private unnamed_addr constant [30 x i8] c"annotation_string_literal_bar\00", section "llvm.metadata"
+ at .str.1 = private unnamed_addr constant [7 x i8] c"test.c\00", section "llvm.metadata"
+ at .str.2 = private unnamed_addr constant [30 x i8] c"annotation_string_literal_foo\00", section "llvm.metadata"
+ at llvm.global.annotations = appending global [2 x { ptr, ptr, ptr, i32, ptr }] [{ ptr, ptr, ptr, i32, ptr } { ptr @bar, ptr @.str, ptr @.str.1, i32 3, ptr null }, { ptr, ptr, ptr, i32, ptr } { ptr @foo, ptr @.str.2, ptr @.str.1, i32 2, ptr null }], section "llvm.metadata"
+
+define void @bar() {
+entry:
+  ret void
 }
 
-declare !type !8 !type !9 i32 @foo(i32 noundef) #1
-
-; Function Attrs: noinline nounwind optnone uwtable
-define i32 @test(i32 noundef %0) #0 !type !8 !type !9 {
-  %2 = alloca i32, align 4
-  store i32 %0, ptr %2, align 4
-  %3 = load i32, ptr %2, align 4
-  %4 = icmp sgt i32 %3, 0
-  br i1 %4, label %5, label %6
-
-5:                                                ; preds = %1
-  store ptr @bar, ptr @fptr1, align 8
-  store ptr @foo, ptr @fptr2, align 8
-  br label %7
-
-6:                                                ; preds = %1
-  store ptr @bar, ptr @fptr1, align 8
-  store ptr @foo, ptr @fptr2, align 8
-  br label %7
-
-7:                                                ; preds = %6, %5
-  %8 = load ptr, ptr @fptr1, align 8
-  %9 = call i1 @llvm.type.test(ptr %8, metadata !"_ZTSFiiE"), !nosanitize !10
-  br i1 %9, label %11, label %10, !nosanitize !10
-
-10:                                               ; preds = %7
-  call void @llvm.ubsantrap(i8 2) #4, !nosanitize !10
-  unreachable, !nosanitize !10
-
-11:                                               ; preds = %7
-  %12 = load ptr, ptr @fptr2, align 8
-  %13 = call i1 @llvm.type.test(ptr %12, metadata !"_ZTSFiiE"), !nosanitize !10
-  br i1 %13, label %15, label %14, !nosanitize !10
-
-14:                                               ; preds = %11
-  call void @llvm.ubsantrap(i8 2) #4, !nosanitize !10
-  unreachable, !nosanitize !10
-
-15:                                               ; preds = %11
-  %16 = load i32, ptr %2, align 4
-  %17 = call i32 %12(i32 noundef %16)
-  %18 = call i32 %8(i32 noundef %17)
-  ret i32 %18
+define void @test(i32 noundef %x) {
+entry:
+  %x.addr = alloca i32, align 4
+  store i32 %x, ptr %x.addr, align 4
+  %0 = load i32, ptr %x.addr, align 4
+  %cmp = icmp sgt i32 %0, 0
+  %1 = zext i1 %cmp to i64
+  %cond = select i1 %cmp, ptr @foo, ptr @bar
+  store ptr %cond, ptr @fptr, align 8
+  %2 = load ptr, ptr @fptr, align 8
+  %3 = call i1 @llvm.type.test(ptr %2, metadata !"_ZTSFvvE"), !nosanitize !{}
+  br i1 %3, label %cont, label %trap, !nosanitize !{}
+
+trap:
+  call void @llvm.ubsantrap(i8 2) #4, !nosanitize !{}
+  unreachable, !nosanitize !{}
+
+cont:
+  call void %2()
+  ret void
 }
 
-; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
-declare i1 @llvm.type.test(ptr, metadata) #2
-
-; Function Attrs: cold noreturn nounwind
-declare void @llvm.ubsantrap(i8 immarg) #3
-
-attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
-attributes #1 = { "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
-attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
-attributes #3 = { cold noreturn nounwind }
-attributes #4 = { noreturn nounwind }
-
-!llvm.ident = !{!0}
-!llvm.module.flags = !{!1, !2, !3, !4, !5, !6, !7}
-
-!0 = !{!"clang version 19.0.0git"}
-!1 = !{i32 1, !"wchar_size", i32 4}
-!2 = !{i32 4, !"CFI Canonical Jump Tables", i32 0}
-!3 = !{i32 8, !"PIC Level", i32 2}
-!4 = !{i32 7, !"uwtable", i32 2}
-!5 = !{i32 7, !"frame-pointer", i32 1}
-!6 = !{i32 1, !"ThinLTO", i32 0}
-!7 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
-!8 = !{i64 0, !"_ZTSFiiE"}
-!9 = !{i64 0, !"_ZTSFiiE.generalized"}
-!10 = !{}
+declare void @foo(...)
+declare i1 @llvm.type.test(ptr, metadata)
+declare void @llvm.ubsantrap(i8 immarg)

>From 3ddede4d7ae12f9cdc37fadb749009872ad8f8a3 Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Thu, 8 Feb 2024 10:51:27 -0800
Subject: [PATCH 7/7] Address review feedback 5

---
 .../LowerTypeTests/cfi-annotation.ll          | 74 ++++++++++++-------
 1 file changed, 47 insertions(+), 27 deletions(-)

diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll b/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll
index c5d4822a009e5e..6e6d5a7bd45682 100644
--- a/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll
+++ b/llvm/test/Transforms/LowerTypeTests/cfi-annotation.ll
@@ -6,41 +6,61 @@
 
 target triple = "aarch64-none-linux-gnu"
 
- at fptr = global ptr null, align 8
 @.src = private unnamed_addr constant [7 x i8] c"test.c\00", align 1
- at anon.eb4aa7a5d41c72267995d92d93c37bde.0 = private unnamed_addr constant { i16, i16, [14 x i8] } { i16 -1, i16 0, [14 x i8] c"'void (void)'\00" }
 @.str = private unnamed_addr constant [30 x i8] c"annotation_string_literal_bar\00", section "llvm.metadata"
 @.str.1 = private unnamed_addr constant [7 x i8] c"test.c\00", section "llvm.metadata"
 @.str.2 = private unnamed_addr constant [30 x i8] c"annotation_string_literal_foo\00", section "llvm.metadata"
- at llvm.global.annotations = appending global [2 x { ptr, ptr, ptr, i32, ptr }] [{ ptr, ptr, ptr, i32, ptr } { ptr @bar, ptr @.str, ptr @.str.1, i32 3, ptr null }, { ptr, ptr, ptr, i32, ptr } { ptr @foo, ptr @.str.2, ptr @.str.1, i32 2, ptr null }], section "llvm.metadata"
+ at llvm.global.annotations = appending global [2 x { ptr, ptr, ptr, i32, ptr }] [{ ptr, ptr, ptr, i32, ptr } { ptr @bar, ptr @.str, ptr @.str.1, i32 2, ptr null }, { ptr, ptr, ptr, i32, ptr } { ptr @foo, ptr @.str.2, ptr @.str.1, i32 1, ptr null }], section "llvm.metadata"
 
-define void @bar() {
-entry:
-  ret void
+define i32 @bar(i32 noundef %0) #0 !type !8 !type !9 {
+  %2 = alloca i32, align 4
+  store i32 %0, ptr %2, align 4
+  %3 = load i32, ptr %2, align 4
+  %4 = call i32 @foo(i32 noundef %3)
+  ret i32 %4
 }
 
-define void @test(i32 noundef %x) {
-entry:
-  %x.addr = alloca i32, align 4
-  store i32 %x, ptr %x.addr, align 4
-  %0 = load i32, ptr %x.addr, align 4
-  %cmp = icmp sgt i32 %0, 0
-  %1 = zext i1 %cmp to i64
-  %cond = select i1 %cmp, ptr @foo, ptr @bar
-  store ptr %cond, ptr @fptr, align 8
-  %2 = load ptr, ptr @fptr, align 8
-  %3 = call i1 @llvm.type.test(ptr %2, metadata !"_ZTSFvvE"), !nosanitize !{}
-  br i1 %3, label %cont, label %trap, !nosanitize !{}
-
-trap:
-  call void @llvm.ubsantrap(i8 2) #4, !nosanitize !{}
-  unreachable, !nosanitize !{}
-
-cont:
-  call void %2()
-  ret void
+declare !type !8 !type !9 i32 @foo(i32 noundef) #1
+
+define i32 @test(i32 noundef %0) #0 !type !8 !type !9 {
+  %2 = alloca i32, align 4
+  %3 = alloca ptr, align 8
+  store i32 %0, ptr %2, align 4
+  %4 = load i32, ptr %2, align 4
+  %5 = icmp sgt i32 %4, 0
+  %6 = zext i1 %5 to i64
+  %7 = select i1 %5, ptr @foo, ptr @bar
+  store ptr %7, ptr %3, align 8
+  %8 = load ptr, ptr %3, align 8
+  %9 = call i1 @llvm.type.test(ptr %8, metadata !"_ZTSFiiE"), !nosanitize !10
+  br i1 %9, label %11, label %10, !nosanitize !10
+
+10:
+  call void @llvm.ubsantrap(i8 2) #4, !nosanitize !10
+  unreachable, !nosanitize !10
+
+11:
+  %12 = load i32, ptr %2, align 4
+  %13 = call i32 %8(i32 noundef %12)
+  ret i32 %13
 }
 
-declare void @foo(...)
 declare i1 @llvm.type.test(ptr, metadata)
 declare void @llvm.ubsantrap(i8 immarg)
+
+attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
+attributes #1 = { "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
+attributes #4 = { noreturn nounwind }
+
+!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 4, !"CFI Canonical Jump Tables", i32 0}
+!2 = !{i32 8, !"PIC Level", i32 2}
+!3 = !{i32 7, !"uwtable", i32 2}
+!4 = !{i32 7, !"frame-pointer", i32 1}
+!5 = !{i32 1, !"ThinLTO", i32 0}
+!6 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
+!8 = !{i64 0, !"_ZTSFiiE"}
+!9 = !{i64 0, !"_ZTSFiiE.generalized"}
+!10 = !{}



More information about the llvm-commits mailing list