@@ -919,7 +919,8 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
919919 jl_svec_t *tt = ((jl_datatype_t *)at)->parameters ;
920920 size_t nargt = jl_svec_len (tt);
921921 SmallVector<llvm::Type*, 0 > argtypes;
922- SmallVector<Value *, 8 > argvals (nargt);
922+ SmallVector<Value *, 8 > argvals; // do not presize argvals, we will push_back only non-void arguments
923+ argvals.reserve (nargt);
923924 for (size_t i = 0 ; i < nargt; ++i) {
924925 jl_value_t *tti = jl_svecref (tt,i);
925926 bool toboxed;
@@ -933,9 +934,16 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
933934 jl_value_t *argi = args[4 + i];
934935 jl_cgval_t arg = emit_expr (ctx, argi);
935936
936- Value *v = julia_to_native (ctx, t, toboxed, tti, NULL , arg, false , i);
937- bool issigned = jl_signed_type && jl_subtype (tti, (jl_value_t *)jl_signed_type);
938- argvals[i] = llvm_type_rewrite (ctx, v, t, issigned);
937+ Value *v = julia_to_native (ctx, t, toboxed, tti, NULL , arg, false , i); // 1. If Void -> SKIP (do not push to argvals) 2. If empty struct -> push UndefValue 3. Normal case -> push value
938+ if (t->isVoidTy ()) {
939+ continue ;
940+ }
941+ if (v == NULL ){
942+ argvals.push_back (UndefValue::get (t));
943+ } else {
944+ bool issigned = jl_signed_type && jl_subtype (tti, (jl_value_t *)jl_signed_type);
945+ argvals.push_back (llvm_type_rewrite (ctx, v, t, issigned));
946+ }
939947 }
940948
941949 // Determine return type
@@ -963,11 +971,11 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
963971 // stringify arguments
964972 std::string arguments;
965973 raw_string_ostream argstream (arguments);
974+ int printed_args = 0 ;
966975 for (SmallVector<Type *, 0 >::iterator it = argtypes.begin (); it != argtypes.end (); ++it) {
967- if (it != argtypes. begin ())
968- argstream << " ," ;
976+ if ((*it)-> isVoidTy ()) continue ;
977+ if (printed_args++ > 0 ) argstream << " , " ;
969978 (*it)->print (argstream);
970- argstream << " " ;
971979 }
972980
973981 // stringify return type
@@ -991,17 +999,13 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
991999 if (!Mod) {
9921000 std::string compat_arguments;
9931001 raw_string_ostream compat_argstream (compat_arguments);
1002+ int printed_args = 0 ;
9941003 for (size_t i = 0 ; i < nargt; ++i) {
995- if (i > 0 )
996- compat_argstream << " ," ;
9971004 jl_value_t *tti = jl_svecref (tt, i);
998- Type *t;
999- if (jl_is_cpointer_type (tti))
1000- t = ctx.types ().T_size ;
1001- else
1002- t = argtypes[i];
1005+ Type *t = (jl_is_cpointer_type (tti)) ? ctx.types ().T_size : argtypes[i];
1006+ if (t->isVoidTy ()) continue ;
1007+ if (printed_args++ > 0 ) compat_argstream << " , " ;
10031008 t->print (compat_argstream);
1004- compat_argstream << " " ;
10051009 }
10061010
10071011 std::string compat_rstring;
@@ -1084,13 +1088,18 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
10841088
10851089 // backwards compatibility: support for IR with integer pointers
10861090 bool mismatched_pointers = false ;
1091+ int arg_idx = 0 ;
10871092 for (size_t i = 0 ; i < nargt; ++i) {
10881093 jl_value_t *tti = jl_svecref (tt, i);
1094+ Type *t = argtypes[i];
1095+ if (t->isVoidTy ())
1096+ continue ;
10891097 if (jl_is_cpointer_type (tti) &&
1090- !f->getFunctionType ()->getParamType (i )->isPointerTy ()) {
1098+ !f->getFunctionType ()->getParamType (arg_idx )->isPointerTy ()) {
10911099 mismatched_pointers = true ;
10921100 break ;
10931101 }
1102+ arg_idx++;
10941103 }
10951104 if (mismatched_pointers) {
10961105 if (jl_options.depwarn ) {
@@ -1128,9 +1137,13 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
11281137 BasicBlock *entry = BasicBlock::Create (ctx.builder .getContext (), " " , wrapper);
11291138 IRBuilder<> irbuilder (entry);
11301139 SmallVector<Value *, 0 > wrapper_args;
1140+ arg_idx = 0 ;
11311141 for (size_t i = 0 ; i < nargt; ++i) {
11321142 jl_value_t *tti = jl_svecref (tt, i);
1133- Value *v = wrapper->getArg (i);
1143+ Type *t = argtypes[i];
1144+ if (t->isVoidTy ())
1145+ continue ;
1146+ Value *v = wrapper->getArg (arg_idx++);
11341147 if (jl_is_cpointer_type (tti))
11351148 v = irbuilder.CreatePtrToInt (v, ctx.types ().T_size );
11361149 wrapper_args.push_back (v);
@@ -1150,18 +1163,21 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
11501163
11511164 // verify the function type
11521165 assert (f->getReturnType () == rettype);
1153- int i = 0 ;
1166+ arg_idx = 0 ;
11541167 for (SmallVector<Type *, 0 >::iterator it = argtypes.begin (); it != argtypes.end ();
1155- ++it, ++i) {
1156- if (*it != f->getFunctionType ()->getParamType (i)) {
1168+ ++it) {
1169+ if ((*it)->isVoidTy ())
1170+ continue ;
1171+ if (*it != f->getFunctionType ()->getParamType (arg_idx)) {
11571172 std::string message;
11581173 raw_string_ostream stream (message);
1159- stream << " Malformed llvmcall: argument " << i + 1 << " type "
1160- << *f->getFunctionType ()->getParamType (i )
1174+ stream << " Malformed llvmcall: argument " << arg_idx + 1 << " type "
1175+ << *f->getFunctionType ()->getParamType (arg_idx )
11611176 << " does not match expected argument type " << **it;
11621177 emit_error (ctx, stream.str ());
11631178 return jl_cgval_t ();
11641179 }
1180+ arg_idx++;
11651181 }
11661182
11671183 // copy module properties that should always match
@@ -1183,7 +1199,12 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
11831199 def->setLinkage (GlobalVariable::LinkOnceODRLinkage);
11841200
11851201 // generate a call
1186- FunctionType *decl_typ = FunctionType::get (rettype, argtypes, def->isVarArg ());
1202+ SmallVector<Type *, 0 > filtered_argtypes;
1203+ for (auto t : argtypes) {
1204+ if (!t->isVoidTy ())
1205+ filtered_argtypes.push_back (t);
1206+ }
1207+ FunctionType *decl_typ = FunctionType::get (rettype, filtered_argtypes, def->isVarArg ());
11871208 Function *decl = Function::Create (decl_typ, def->getLinkage (), def->getAddressSpace (),
11881209 def->getName (), jl_Module);
11891210 decl->setAttributes (def->getAttributes ());
0 commit comments