Skip to content
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

ORC cannot run initializers with non-void signatures #54797

Open
hahnjo opened this issue Apr 7, 2022 · 7 comments
Open

ORC cannot run initializers with non-void signatures #54797

hahnjo opened this issue Apr 7, 2022 · 7 comments
Assignees
Labels

Comments

@hahnjo
Copy link
Member

hahnjo commented Apr 7, 2022

Consider the following program in C:

#include <stdio.h>

__attribute__((constructor(1001)))
static int constructor(void *ptr) {
  puts("constructor");
  return 0;
}

int main() {
  return 0;
}

or the (stripped down) version in LLVM IR:

@.str = private unnamed_addr constant [12 x i8] c"constructor\00", align 1
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 1001, void ()* bitcast (i32 (i8*)* @constructor to void ()*), i8* null }]

define internal i32 @constructor(i8* noundef %ptr) {
entry:
  %ptr.addr = alloca i8*, align 8
  store i8* %ptr, i8** %ptr.addr, align 8
  %call = call i32 @puts(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i64 0, i64 0))
  ret i32 0
}

declare i32 @puts(i8* noundef)

define dso_local i32 @main() {
entry:
  %retval = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  ret i32 0
}

When trying to run with lli --jit-kind=orc constructor.min.ll, there is a segmentation fault because the llvm::Function * and its type are null pointers. This is because the CtorDtorIterator in ExecutionUtils.cpp expects another ConstantExpr in the first operand of a cast, that could be fixed as follows:

diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index ae2d47fb8c5e..cbc27980f57a 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -62,7 +62,7 @@ CtorDtorIterator::Element CtorDtorIterator::operator*() const {
       break;
     } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) {
       if (CE->isCast())
-        FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0));
+        FuncC = CE->getOperand(0);
       else
         break;
     } else {

However, then an assertion trips because the code expects to call a function without parameters:

llvm/lib/IR/Instructions.cpp:525: void llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, const llvm::Twine&): Assertion `(Args.size() == FTy->getNumParams() || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Calling a function with bad signature!"' failed.

This at least matches MCJIT:

llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:523: virtual llvm::GenericValue llvm::MCJIT::runFunction(llvm::Function*, llvm::ArrayRef<llvm::GenericValue>): Assertion `(FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && "Wrong number of arguments passed into function!"' failed.

@lhames

@hahnjo hahnjo added the orcjit label Apr 7, 2022
@llvmbot
Copy link
Collaborator

llvmbot commented Apr 7, 2022

@llvm/issue-subscribers-orcjit

@lhames
Copy link
Contributor

lhames commented Apr 8, 2022

Thanks @hahnjo! I've committed a fix in a76209c.

The aim is to move to to the ORC Runtime for running initializers in the future, and the ORC runtime should be able to match the behavior of the dynamic loaders (cast initializer address to void() and call it). Is there any valid use case for non-void initializers though? These feel like something that we might want to warn about in the compiler.

@hahnjo
Copy link
Member Author

hahnjo commented Apr 8, 2022

@lhames as far as I can tell, you only committed the diff that I put above, that I could have done myself. However, as also noted above, this doesn't work if the constructor takes arguments so now it will crash in a different place. Regarding the question if that is valid, it's currently accepted by both Clang and GCC so there may be code using it. In fact, Clang's CUDA support generates constructors taking an argument - I'll have to see today if that can be removed.

@hahnjo
Copy link
Member Author

hahnjo commented Apr 8, 2022

Regarding the question if that is valid, it's currently accepted by both Clang and GCC so there may be code using it.

Yes, if registered via .init_array at least glibc will pass in (argc, argv, envp) to the function. See for example:

#include <stdio.h>

__attribute__((constructor))
static void constructor(int argc, char *argv[], char *envp[]) {
  printf("arguments:\n");
  for (int i = 0; i < argc; i++) {
    printf("  %s\n", argv[i]);
  }
  printf("\nenvironment:\n");
  while (*envp != NULL) {
    printf("  %s\n", *envp);
    envp++;
  }
}

int main() {
  return 0;
}

We don't need that for CUDA, so I'm proposing to remove the argument in https://reviews.llvm.org/D123370.

hahnjo added a commit to vgvassilev/root that referenced this issue Apr 8, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
@lhames
Copy link
Contributor

lhames commented Apr 8, 2022

Yes, if registered via .init_array at least glibc will pass in (argc, argv, envp) to the function. See for example:

Interesting. I haven't come across this before.

Updating the LLJIT "Generic Platform" support to do this is probably awkward but doable. If you don't need it (and nobody else has asked for it) I'm not sure it's worth the effort for now, but if you'd like to tackle it the right place to look would be in GlobalCtorDtorScraper::operator().

Doing this in the ORC runtime should be more natural, and it's the right long term place to implement this. I think we could leave this bug open to track implementing this in the ORC runtime.

@lhames lhames self-assigned this Apr 8, 2022
@hahnjo
Copy link
Member Author

hahnjo commented Apr 9, 2022

I've just committed e4903d8 to avoid this situation with CUDA. We'll go with this solution for Cling, so we don't have a requirement for it. I agree that this should be kept open until this is implemented somewhere when / if need arises.

@llvmbot
Copy link
Collaborator

llvmbot commented Apr 9, 2022

@llvm/issue-subscribers-clang-codegen

vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 1, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 1, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 2, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 7, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 8, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
hahnjo added a commit to vgvassilev/root that referenced this issue May 13, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 14, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 14, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 14, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
hahnjo added a commit to vgvassilev/root that referenced this issue May 15, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 16, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 17, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue May 26, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue Jun 2, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
hahnjo added a commit to vgvassilev/root that referenced this issue Jun 13, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue Jul 27, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue Jul 30, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
Axel-Naumann pushed a commit to vgvassilev/root that referenced this issue Sep 12, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
Axel-Naumann pushed a commit to vgvassilev/root that referenced this issue Sep 12, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
Axel-Naumann pushed a commit to vgvassilev/root that referenced this issue Sep 15, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue Sep 22, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
hahnjo added a commit to vgvassilev/root that referenced this issue Oct 6, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
Axel-Naumann pushed a commit to vgvassilev/root that referenced this issue Oct 7, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue Nov 1, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue Nov 11, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue Dec 6, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
Axel-Naumann pushed a commit to Axel-Naumann/root that referenced this issue Dec 7, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue Dec 9, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/root that referenced this issue Dec 9, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
vgvassilev pushed a commit to vgvassilev/clang that referenced this issue Dec 28, 2022
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm/llvm-project#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
Axel-Naumann pushed a commit to root-project/llvm-project that referenced this issue May 17, 2023
This works around a bug + missing support in ORC for constructors with
non-void signatures (llvm#54797).
Also submitted upstream, see https://reviews.llvm.org/D123370
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants