[clang] [CIR] Upstream lowering of conditional operators to TernaryOp (PR #138156)
Andy Kaylor via cfe-commits
cfe-commits at lists.llvm.org
Thu May 1 15:41:46 PDT 2025
================
@@ -948,6 +950,165 @@ void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
emitLValue(e);
}
+// Handle the case where the condition is a constant evaluatable simple integer,
+// which means we don't have to separately handle the true/false blocks.
+static std::optional<LValue> handleConditionalOperatorLValueSimpleCase(
+ CIRGenFunction &cgf, const AbstractConditionalOperator *e) {
+ const Expr *condExpr = e->getCond();
+ bool condExprBool = false;
+ if (cgf.constantFoldsToSimpleInteger(condExpr, condExprBool)) {
+ const Expr *live = e->getTrueExpr(), *dead = e->getFalseExpr();
+ if (!condExprBool)
+ std::swap(live, dead);
+
+ if (!cgf.containsLabel(dead)) {
+ // If the true case is live, we need to track its region.
+ if (condExprBool) {
+ assert(!cir::MissingFeatures::incrementProfileCounter());
+ }
+ // If a throw expression we emit it and return an undefined lvalue
+ // because it can't be used.
+ if (isa<CXXThrowExpr>(live->IgnoreParens())) {
+ assert(!cir::MissingFeatures::throwOp());
+ cgf.cgm.errorNYI(live->getSourceRange(),
+ "throw expressions in conditional operator");
+ return std::nullopt;
+ }
+ return cgf.emitLValue(live);
+ }
+ }
+ return std::nullopt;
+}
+
+/// Emit the operand of a glvalue conditional operator. This is either a glvalue
+/// or a (possibly-parenthesized) throw-expression. If this is a throw, no
+/// LValue is returned and the current block has been terminated.
+static std::optional<LValue> emitLValueOrThrowExpression(CIRGenFunction &cgf,
+ const Expr *operand) {
+ if (isa<CXXThrowExpr>(operand->IgnoreParens())) {
+ assert(!cir::MissingFeatures::throwOp());
+ cgf.cgm.errorNYI(operand->getSourceRange(),
+ "throw expressions in conditional operator");
+ return std::nullopt;
+ }
+
+ return cgf.emitLValue(operand);
+}
+
+// Create and generate the 3 blocks for a conditional operator.
+// Leaves the 'current block' in the continuation basic block.
+template <typename FuncTy>
+CIRGenFunction::ConditionalInfo
+CIRGenFunction::emitConditionalBlocks(const AbstractConditionalOperator *e,
+ const FuncTy &branchGenFunc) {
+ ConditionalInfo info;
+ CIRGenFunction &cgf = *this;
+ ConditionalEvaluation eval(cgf);
+ mlir::Location loc = cgf.getLoc(e->getSourceRange());
+ CIRGenBuilderTy &builder = cgf.getBuilder();
----------------
andykaylor wrote:
The use of `cgf` throughout this function is odd. In the classic codegen it was a standalone function that took `CGF` as a parameter, but since it's a member function here, there's no reason to do that. Also, `builder` here is shadowing the `builder` member variable in `CIRGenFunction`.
https://github.com/llvm/llvm-project/pull/138156
More information about the cfe-commits
mailing list