aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
diff options
context:
space:
mode:
authorAndres-Salamanca <andrealebarbaritos@gmail.com>2025-04-08 19:50:53 -0500
committerGitHub <noreply@github.com>2025-04-08 17:50:53 -0700
commitccf22848da9f050e00f23c5d4bc412ab19e81645 (patch)
treebe1cee6608b423d1f29ac178da255f260ba6c474 /clang/lib/CIR/CodeGen/CIRGenFunction.cpp
parent34d586fdd548a34911caa068b557c4c0442f4d1d (diff)
downloadllvm-ccf22848da9f050e00f23c5d4bc412ab19e81645.zip
llvm-ccf22848da9f050e00f23c5d4bc412ab19e81645.tar.gz
llvm-ccf22848da9f050e00f23c5d4bc412ab19e81645.tar.bz2
[CIR] Add if statement support (#134333)
This patch adds support for if statements in the CIR dialect Additionally, multiple RUN lines were introduced to improve codegen test coverage
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenFunction.cpp')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 2465ccf..b123fc3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -135,6 +135,71 @@ mlir::Location CIRGenFunction::getLoc(mlir::Location lhs, mlir::Location rhs) {
return mlir::FusedLoc::get(locs, metadata, &getMLIRContext());
}
+bool CIRGenFunction::containsLabel(const Stmt *s, bool ignoreCaseStmts) {
+ // Null statement, not a label!
+ if (!s)
+ return false;
+
+ // If this is a label, we have to emit the code, consider something like:
+ // if (0) { ... foo: bar(); } goto foo;
+ //
+ // TODO: If anyone cared, we could track __label__'s, since we know that you
+ // can't jump to one from outside their declared region.
+ if (isa<LabelStmt>(s))
+ return true;
+
+ // If this is a case/default statement, and we haven't seen a switch, we
+ // have to emit the code.
+ if (isa<SwitchCase>(s) && !ignoreCaseStmts)
+ return true;
+
+ // If this is a switch statement, we want to ignore case statements when we
+ // recursively process the sub-statements of the switch. If we haven't
+ // encountered a switch statement, we treat case statements like labels, but
+ // if we are processing a switch statement, case statements are expected.
+ if (isa<SwitchStmt>(s))
+ ignoreCaseStmts = true;
+
+ // Scan subexpressions for verboten labels.
+ return std::any_of(s->child_begin(), s->child_end(),
+ [=](const Stmt *subStmt) {
+ return containsLabel(subStmt, ignoreCaseStmts);
+ });
+}
+
+/// If the specified expression does not fold to a constant, or if it does but
+/// contains a label, return false. If it constant folds return true and set
+/// the boolean result in Result.
+bool CIRGenFunction::constantFoldsToBool(const Expr *cond, bool &resultBool,
+ bool allowLabels) {
+ llvm::APSInt resultInt;
+ if (!constantFoldsToSimpleInteger(cond, resultInt, allowLabels))
+ return false;
+
+ resultBool = resultInt.getBoolValue();
+ return true;
+}
+
+/// If the specified expression does not fold to a constant, or if it does
+/// fold but contains a label, return false. If it constant folds, return
+/// true and set the folded value.
+bool CIRGenFunction::constantFoldsToSimpleInteger(const Expr *cond,
+ llvm::APSInt &resultInt,
+ bool allowLabels) {
+ // FIXME: Rename and handle conversion of other evaluatable things
+ // to bool.
+ Expr::EvalResult result;
+ if (!cond->EvaluateAsInt(result, getContext()))
+ return false; // Not foldable, not integer or not fully evaluatable.
+
+ llvm::APSInt intValue = result.Val.getInt();
+ if (!allowLabels && containsLabel(cond))
+ return false; // Contains a label.
+
+ resultInt = intValue;
+ return true;
+}
+
void CIRGenFunction::emitAndUpdateRetAlloca(QualType type, mlir::Location loc,
CharUnits alignment) {
if (!type->isVoidType()) {