Skip to content

Conversation

@AmrDeveloper
Copy link
Member

Add support for the RequiresExpr

@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Dec 11, 2025
Comment on lines +17 to +18
// CIR: %[[CONST_TRUE:.*]] = cir.const #true
// CIR: cir.if %[[CONST_TRUE]] {
Copy link
Member Author

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 🤔

Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that makes sense

@llvmbot
Copy link
Member

llvmbot commented Dec 11, 2025

@llvm/pr-subscribers-clangir

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

Changes

Add support for the RequiresExpr


Full diff: https://github.com/llvm/llvm-project/pull/171818.diff

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+1-2)
  • (added) clang/test/CIR/CodeGen/requires-expr.cpp (+51)
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); }
+

@github-actions
Copy link

github-actions bot commented Dec 11, 2025

🐧 Linux x64 Test Results

  • 112923 tests passed
  • 4163 tests skipped

✅ The build succeeded and all tests passed.

Copy link
Contributor

@andykaylor andykaylor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Comment on lines +17 to +18
// CIR: %[[CONST_TRUE:.*]] = cir.const #true
// CIR: cir.if %[[CONST_TRUE]] {
Copy link
Contributor

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.

@AmrDeveloper AmrDeveloper merged commit 95e4dc6 into llvm:main Dec 13, 2025
10 checks passed
anonymouspc pushed a commit to anonymouspc/llvm that referenced this pull request Dec 15, 2025
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Dec 19, 2025
Priyanshu3820 pushed a commit to Priyanshu3820/llvm-project that referenced this pull request Dec 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants