From 9920b303185e2bfdfaec451fcac2e260bdf4ce03 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Wed, 14 Dec 2011 06:00:05 -0800 Subject: [PATCH] Fix bug that led to incorrect code with return statements. The conceptual error was the assumption that not being under varying control flow implied that the mask was all on; this is not the case if some of the instances have executed a return earlier in the function's execution. The error in practice would be that the mask would be assumed to be all-on for things like memory writes, so there would be unintended side-effects for the instances that had returned. --- ctx.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/ctx.cpp b/ctx.cpp index 041473c6..cc3b9e09 100644 --- a/ctx.cpp +++ b/ctx.cpp @@ -312,11 +312,7 @@ FunctionEmitContext::GetFunctionMask() { llvm::Value * FunctionEmitContext::GetInternalMask() { - if (VaryingCFDepth() == 0 && - !g->opt.disableMaskAllOnOptimizations) - return LLVMMaskAllOn; - else - return LoadInst(internalMaskPointer, "load_mask"); + return LoadInst(internalMaskPointer, "load_mask"); } @@ -798,13 +794,19 @@ FunctionEmitContext::CurrentLanesReturned(Expr *expr, bool doCoherenceCheck) { expr = TypeConvertExpr(expr, returnType, "return statement"); if (expr != NULL) { llvm::Value *retVal = expr->GetValue(this); - if (retVal != NULL) - // Use a masked store to store the value of the expression - // in the return value memory; this preserves the return - // values from other lanes that may have executed return - // statements previously. - StoreInst(retVal, returnValuePtr, GetInternalMask(), - PointerType::GetUniform(returnType)); + if (retVal != NULL) { + if (returnType->IsUniformType() || + dynamic_cast(returnType) != NULL) + StoreInst(retVal, returnValuePtr); + else { + // Use a masked store to store the value of the expression + // in the return value memory; this preserves the return + // values from other lanes that may have executed return + // statements previously. + StoreInst(retVal, returnValuePtr, GetInternalMask(), + PointerType::GetUniform(returnType)); + } + } } }