summaryrefslogtreecommitdiff
path: root/source/slang/slang-lower-to-ir.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-03-24 20:17:46 -0700
committerGitHub <noreply@github.com>2023-03-24 20:17:46 -0700
commit666af0962b6ab41489a3a3287db83f77c2f6461a (patch)
tree81a1247188ac03f1e8132e58ec31ae0f28c8c530 /source/slang/slang-lower-to-ir.cpp
parent7292edbd3eba3da7e8490ad19169a7d18283057a (diff)
Switch to short circuiting semantics for scalar `?:` operator. (#2733)
Diffstat (limited to 'source/slang/slang-lower-to-ir.cpp')
-rw-r--r--source/slang/slang-lower-to-ir.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 9c27beb58..7144b3450 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -4003,6 +4003,43 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
return e;
}
+ LoweredValInfo visitSelectExpr(SelectExpr* expr)
+ {
+ // A vector typed `select` expr will turn into a normal `select` op.
+ if (!as<BasicExpressionType>(expr->arguments[0]->type.type))
+ {
+ return visitInvokeExpr(expr);
+ }
+
+ // In global scope? This is a constant, and we should emit as `select` inst.
+ if (!getParentFunc(context->irBuilder->getInsertLoc().getInst()))
+ {
+ return visitInvokeExpr(expr);
+ }
+
+ // A scalar typed `select` expr will turn into an if-else to implement short circuiting
+ // semantics.
+ auto builder = context->irBuilder;
+ auto thenBlock = builder->createBlock();
+ auto elseBlock = builder->createBlock();
+ auto afterBlock = builder->createBlock();
+ auto irCond = getSimpleVal(context, lowerRValueExpr(context, expr->arguments[0]));
+ builder->emitIfElse(irCond, thenBlock, elseBlock, afterBlock);
+ builder->insertBlock(thenBlock);
+ builder->setInsertInto(thenBlock);
+ auto trueVal = getSimpleVal(context, lowerRValueExpr(context, expr->arguments[1]));
+ builder->emitBranch(afterBlock, 1, &trueVal);
+ builder->insertBlock(elseBlock);
+ builder->setInsertInto(elseBlock);
+ auto falseVal = getSimpleVal(context, lowerRValueExpr(context, expr->arguments[2]));
+ builder->emitBranch(afterBlock, 1, &falseVal);
+ builder->insertBlock(afterBlock);
+ builder->setInsertInto(afterBlock);
+ auto paramType = lowerType(context, expr->type.type);
+ auto result = builder->emitParam(paramType);
+ return LoweredValInfo::simple(result);
+ }
+
LoweredValInfo visitInvokeExpr(InvokeExpr* expr)
{
return visitInvokeExprImpl(expr, TryClauseEnvironment());