diff --git a/ctx.cpp b/ctx.cpp index 43d5771b..df1129b8 100644 --- a/ctx.cpp +++ b/ctx.cpp @@ -3617,8 +3617,12 @@ FunctionEmitContext::LaunchInst(llvm::Value *callee, AssertPos(currentPos, llvm::isa(callee)); std::vector argTypes; - for (unsigned int i = 0; i < argVals.size(); i++) - argTypes.push_back(argVals[i]->getType()); + + llvm::Function *F = llvm::dyn_cast(callee); + const unsigned int nArgs = F->arg_size(); + llvm::Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); + for (; I != E; ++I) + argTypes.push_back(I->getType()); llvm::Type *st = llvm::StructType::get(*g->ctx, argTypes); llvm::StructType *argStructType = static_cast(st); llvm::Value *structSize = g->target->SizeOf(argStructType, bblock); @@ -3661,6 +3665,13 @@ FunctionEmitContext::LaunchInst(llvm::Value *callee, // don't need to do masked store here, I think StoreInst(argVals[i], ptr); } + if (nArgs == argVals.size() + 1) { + // copy in the mask + llvm::Value *mask = GetFullMask(); + llvm::Value *ptr = AddElementOffset(argmem, argVals.size(), NULL, + "funarg_mask"); + StoreInst(mask, ptr); + } BranchInst(if_false); /**********************/ diff --git a/decl.cpp b/decl.cpp index 7b321dde..0366dd73 100644 --- a/decl.cpp +++ b/decl.cpp @@ -531,12 +531,6 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) { returnType = returnType->ResolveUnboundVariability(Variability::Varying); bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0); - -#if 1 /* evghenii: without this, PTX fails on some examples, like deferred, with #if 0 */ - if (isTask && g->target->getISA() == Target::NVPTX) - ds->typeQualifiers |= TYPEQUAL_UNMASKED; -#endif - bool isExternC = ds && (ds->storageClass == SC_EXTERN_C); bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0); bool isUnmasked = ds && ((ds->typeQualifiers & TYPEQUAL_UNMASKED) != 0); diff --git a/func.cpp b/func.cpp index bff29e32..3923e780 100644 --- a/func.cpp +++ b/func.cpp @@ -359,7 +359,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function, // entire thing inside code that tests to see if the mask is all // on, all off, or mixed. If this is a simple function, then this // isn't worth the code bloat / overhead. - bool checkMask = (type->isTask == true && g->target->getISA() != Target::NVPTX) || + bool checkMask = (type->isTask == true) || ( #if defined(LLVM_3_1) (function->hasFnAttr(llvm::Attribute::AlwaysInline) == false) diff --git a/module.cpp b/module.cpp index 38853419..4be06df7 100644 --- a/module.cpp +++ b/module.cpp @@ -795,6 +795,7 @@ Module::AddFunctionDeclaration(const std::string &name, #else // LLVM 3.1 and 3.3+ function->addFnAttr(llvm::Attribute::AlwaysInline); #endif + /* evghenii: fails function verification when "if" executed in nvptx target */ if (functionType->isTask && g->target->getISA() != Target::NVPTX) // This also applies transitively to members I think? #if defined(LLVM_3_1)