-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[clang] Automatically add the returns_twice attribute to certain functions even if -fno-builtin is set
#133511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…nctions even if `-fno-builtin` is set Certain functions require the `returns_twice` attribute in order to produce correct codegen. However, `-fno-builtin` removes all knowledge of functions that require this attribute, so this PR modifies Clang to add the `returns_twice` attribute even if `-fno-builtin` is set. This behavior is also consistent with what GCC does. It's not (easily) possible to get the builtin information from `Builtins.td` because `-fno-builtin` causes Clang to never initialize any builtins, so functions never get tokenized as functions/builtins that require `returns_twice`. Therefore, the most straightforward solution is to explicitly hard code the function names that require `returns_twice`. Fixes llvm#122840
|
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Alan Zhao (alanzhao1) ChangesCertain functions require the It's not (easily) possible to get the builtin information from Fixes #122840 Full diff: https://github.com/llvm/llvm-project/pull/133511.diff 3 Files Affected:
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 7aa77e55dbfcc..76119617f22e6 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2607,6 +2607,15 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
if (shouldDisableTailCalls())
FuncAttrs.addAttribute("disable-tail-calls", "true");
+ // These functions require the returns_twice attribute for correct codegen,
+ // but the attribute may not be added if -fno-builtin is specified. We
+ // explicitly add that attribute here.
+ static const llvm::StringSet<> ReturnsTwiceFn{
+ "_setjmpex", "setjmp", "_setjmp", "vfork",
+ "sigsetjmp", "__sigsetjmp", "savectx", "getcontext"};
+ if (ReturnsTwiceFn.contains(Name))
+ FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
+
// CPU/feature overrides. addDefaultFunctionDefinitionAttributes
// handles these separately to set them based on the global defaults.
GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs);
diff --git a/clang/test/CodeGen/2003-08-20-vfork-bug.c b/clang/test/CodeGen/2003-08-20-vfork-bug.c
index 4966ab20904d4..438604f321da3 100644
--- a/clang/test/CodeGen/2003-08-20-vfork-bug.c
+++ b/clang/test/CodeGen/2003-08-20-vfork-bug.c
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 -emit-llvm %s -o /dev/null
+// RUN: %clang_cc1 -x c %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x c %s -triple x86_64-linux-gnu -emit-llvm -fno-builtin -o - | FileCheck %s
+// CHECK: ; Function Attrs: returns_twice
+// CHECK-NEXT: declare {{.*}} @vfork(
extern int vfork(void);
void test() {
vfork();
diff --git a/clang/test/CodeGen/setjmp.c b/clang/test/CodeGen/setjmp.c
index 77dde35e69cae..00341e459941a 100644
--- a/clang/test/CodeGen/setjmp.c
+++ b/clang/test/CodeGen/setjmp.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -x c %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x c %s -triple x86_64-linux-gnu -emit-llvm -fno-builtin -o - | FileCheck %s
// RUN: %clang_cc1 -x c++ %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
#ifdef __cplusplus
@@ -6,13 +7,17 @@ extern "C" {
#endif
struct __jmp_buf_tag { int n; };
+struct __ucontext_t_tag { int n; };
int setjmp(struct __jmp_buf_tag*);
int sigsetjmp(struct __jmp_buf_tag*, int);
int _setjmp(struct __jmp_buf_tag*);
int __sigsetjmp(struct __jmp_buf_tag*, int);
+int _setjmpex(struct __jmp_buf_tag* env);
+int getcontext(struct __ucontext_t_tag*);
typedef struct __jmp_buf_tag jmp_buf[1];
typedef struct __jmp_buf_tag sigjmp_buf[1];
+typedef struct __ucontext_t_tag ucontext_t[1];
#ifdef __cplusplus
}
@@ -20,6 +25,7 @@ typedef struct __jmp_buf_tag sigjmp_buf[1];
void f(void) {
jmp_buf jb;
+ ucontext_t ut;
// CHECK: call {{.*}}@setjmp(
setjmp(jb);
// CHECK: call {{.*}}@sigsetjmp(
@@ -28,6 +34,10 @@ void f(void) {
_setjmp(jb);
// CHECK: call {{.*}}@__sigsetjmp(
__sigsetjmp(jb, 0);
+ // CHECK: call {{.*}}@_setjmpex(
+ _setjmpex(jb);
+ // CHECK: call {{.*}}@getcontext(
+ getcontext(ut);
}
// CHECK: ; Function Attrs: returns_twice
@@ -42,3 +52,8 @@ void f(void) {
// CHECK: ; Function Attrs: returns_twice
// CHECK-NEXT: declare {{.*}} @__sigsetjmp(
+// CHECK: ; Function Attrs: returns_twice
+// CHECK-NEXT: declare {{.*}} @_setjmpex(
+
+// CHECK: ; Function Attrs: returns_twice
+// CHECK-NEXT: declare {{.*}} @getcontext(
|
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/51/builds/13556 Here is the relevant piece of the build log for the reference |
Certain functions require the
returns_twiceattribute in order to produce correct codegen. However,-fno-builtinremoves all knowledge of functions that require this attribute, so this PR modifies Clang to add thereturns_twiceattribute even if-fno-builtinis set. This behavior is also consistent with what GCC does.It's not (easily) possible to get the builtin information from
Builtins.tdbecause-fno-builtincauses Clang to never initialize any builtins, so functions never get tokenized as functions/builtins that requirereturns_twice. Therefore, the most straightforward solution is to explicitly hard code the function names that requirereturns_twice.Fixes #122840