-
Notifications
You must be signed in to change notification settings - Fork 15.6k
[CIR] Add support for the RequiresExpr #171818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| // CIR: %[[CONST_TRUE:.*]] = cir.const #true | ||
| // CIR: cir.if %[[CONST_TRUE]] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A nice pattern to fold but not sure how common it is 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should definitely fold that somewhere (though only when optimizations are enabled). I don't like that classic codegen folds this by default at -O0.
I wouldn't expect purely constant conditions like this to be common in the initially generated IR, but after other optimizations it happens fairly often.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that makes sense
|
@llvm/pr-subscribers-clangir @llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) ChangesAdd support for the RequiresExpr Full diff: https://github.com/llvm/llvm-project/pull/171818.diff 2 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 3887433e5e181..60bd76f89b00b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -850,8 +850,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
return {};
}
mlir::Value VisitRequiresExpr(const RequiresExpr *e) {
- cgf.cgm.errorNYI(e->getSourceRange(), "ScalarExprEmitter: requires");
- return {};
+ return builder.getBool(e->isSatisfied(), cgf.getLoc(e->getExprLoc()));
}
mlir::Value VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *e) {
cgf.cgm.errorNYI(e->getSourceRange(),
diff --git a/clang/test/CIR/CodeGen/requires-expr.cpp b/clang/test/CIR/CodeGen/requires-expr.cpp
new file mode 100644
index 0000000000000..6ca6da9802508
--- /dev/null
+++ b/clang/test/CIR/CodeGen/requires-expr.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+template <typename T> void summable(T a) {
+ if (requires { a + a; }) {
+ T b = a + a;
+ }
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
+// CIR: cir.store %[[ARG_A:.*]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CIR: cir.scope {
+// CIR: %[[CONST_TRUE:.*]] = cir.const #true
+// CIR: cir.if %[[CONST_TRUE]] {
+// CIR: %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
+// CIR: %[[TMP_A_1:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[TMP_A_2:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[RESULT:.*]] = cir.binop(add, %[[TMP_A_1]], %[[TMP_A_2]]) nsw : !s32i
+// CIR: cir.store {{.*}} %[[RESULT]], %[[B_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CIR: }
+// CIR: }
+
+// LLVM: %[[B_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: store i32 %[[ARG_A:.*]], ptr %[[A_ADDR]], align 4
+// LLVM: br label %[[IF_COND:.*]]
+// LLVM: [[IF_COND]]:
+// LLVM: br i1 true, label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+// LLVM: [[IF_THEN]]:
+// LLVM: %[[TMP_A_1:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// LLVM: %[[TMP_A_2:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// LLVM: %[[RESULT:.*]] = add nsw i32 %[[TMP_A_1]], %[[TMP_A_2]]
+// LLVM: store i32 %[[RESULT]], ptr %[[B_ADDR]], align 4
+// LLVM: br label %[[IF_END]]
+// LLVM: [[IF_END]]:
+// LLVM: br label %[[RET:.*]]
+
+// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[B_ADDR:.*]] = alloca i32, align 4
+// OGCG: store i32 %[[ARG_A:.*]], ptr %[[A_ADDR]], align 4
+// OGCG: %[[TMP_A_1:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// OGCG: %[[TMP_A_2:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// OGCG: %[[RESULT:.*]] = add nsw i32 %[[TMP_A_1]], %[[TMP_A_2]]
+// OGCG: store i32 %[[RESULT]], ptr %[[B_ADDR]], align 4
+
+void call_function_with_requires_expr() { summable(1); }
+
|
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
andykaylor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
| // CIR: %[[CONST_TRUE:.*]] = cir.const #true | ||
| // CIR: cir.if %[[CONST_TRUE]] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should definitely fold that somewhere (though only when optimizations are enabled). I don't like that classic codegen folds this by default at -O0.
I wouldn't expect purely constant conditions like this to be common in the initially generated IR, but after other optimizations it happens fairly often.
Add support for the RequiresExpr
Add support for the RequiresExpr
Add support for the RequiresExpr
Add support for the RequiresExpr