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.
This commit is contained in:
26
ctx.cpp
26
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<const ReferenceType *>(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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user