[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 16:34:32 PDT 2025
================
@@ -875,6 +877,174 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
// NOTE: We don't need to EnsureInsertPoint() like LLVM codegen.
return Visit(e->getRHS());
}
+
+ mlir::Value VisitBinLAnd(const clang::BinaryOperator *e) {
+ if (e->getType()->isVectorType()) {
+ assert(!cir::MissingFeatures::vectorType());
+ return {};
+ }
+
+ bool instrumentRegions = cgf.cgm.getCodeGenOpts().hasProfileClangInstr();
+ mlir::Type resTy = cgf.convertType(e->getType());
+ mlir::Location loc = cgf.getLoc(e->getExprLoc());
+
+ // If we have 0 && RHS, see if we can elide RHS, if so, just return 0.
+ // If we have 1 && X, just emit X without inserting the control flow.
+ bool lhsCondVal;
+ if (cgf.constantFoldsToSimpleInteger(e->getLHS(), lhsCondVal)) {
+ if (lhsCondVal) { // If we have 1 && X, just emit X.
+
+ mlir::Value rhsCond = cgf.evaluateExprAsBool(e->getRHS());
+
+ if (instrumentRegions) {
+ assert(!cir::MissingFeatures::instrumenation());
+ cgf.cgm.errorNYI(e->getExprLoc(), "instrumenation");
+ }
+ // ZExt result to int or bool.
+ return builder.createZExtOrBitCast(rhsCond.getLoc(), rhsCond, resTy);
+ }
+ // 0 && RHS: If it is safe, just elide the RHS, and return 0/false.
+ if (!cgf.containsLabel(e->getRHS()))
+ return builder.getNullValue(resTy, loc);
+ }
+
+ CIRGenFunction::ConditionalEvaluation eval(cgf);
+
+ mlir::Value lhsCondV = cgf.evaluateExprAsBool(e->getLHS());
+ auto resOp = builder.create<cir::TernaryOp>(
+ loc, lhsCondV, /*trueBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ CIRGenFunction::LexicalScope lexScope{cgf, loc,
+ b.getInsertionBlock()};
+ cgf.curLexScope->setAsTernary();
+ mlir::Value rhsCondV = cgf.evaluateExprAsBool(e->getRHS());
+ auto res = b.create<cir::TernaryOp>(
----------------
andykaylor wrote:
I think this second ternary is entirely unnecessary. This code is effectively doing this for `a && b`:
```
t1 = evaluateExprAsBool(a);
if (t1) {
t2 = evaluateExprAsBool(b);
if (t2) {
result = true;
} else {
result = false;
}
} else {
result = false;
}
```
Couldn't the same result be accomplished like this?
```
t1 = evaluateExprAsBool(a);
if (t1) {
result = evaluateExprAsBool(b);
} else {
result = t1;
}
```
Similar reasoning applies to the LOr handling below.
https://github.com/llvm/llvm-project/pull/138156
More information about the cfe-commits
mailing list