Skip to content

[CIR] Add test for begin/end range for statements #139134

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

Merged
merged 1 commit into from
May 9, 2025

Conversation

andykaylor
Copy link
Contributor

This adds a test to verify range for loops based on begin() and end() funtion calls. The functionality to enable this was added in previous commits, but those commits were only indirectly related to this test. The general intent of this commit is to work towards enabling iterator-based range for loops.

The test did reveal one minor problem in call argument handling, which is corrected here.

This adds a test to verify range for loops based on begin() and end()
funtion calls. The functionality to enable this was added in previous
commits, but those commits were only indirectly related to this test.
The general intent of this commit is to work towards enabling
iterator-based range for loops.

The test did reveal one minor problem in call argument handling, which is
corrected here.
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels May 8, 2025
@llvmbot
Copy link
Member

llvmbot commented May 8, 2025

@llvm/pr-subscribers-clang

Author: Andy Kaylor (andykaylor)

Changes

This adds a test to verify range for loops based on begin() and end() funtion calls. The functionality to enable this was added in previous commits, but those commits were only indirectly related to this test. The general intent of this commit is to work towards enabling iterator-based range for loops.

The test did reveal one minor problem in call argument handling, which is corrected here.


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

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+1-1)
  • (added) clang/test/CIR/CodeGen/forrange.cpp (+49)
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index bed0db28818f1..693e73ceb62ab 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -304,7 +304,7 @@ void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
 
   if (e->isGLValue()) {
     assert(e->getObjectKind() == OK_Ordinary);
-    args.add(emitReferenceBindingToExpr(e), argType);
+    return args.add(emitReferenceBindingToExpr(e), argType);
   }
 
   bool hasAggregateEvalKind = hasAggregateEvaluationKind(argType);
diff --git a/clang/test/CIR/CodeGen/forrange.cpp b/clang/test/CIR/CodeGen/forrange.cpp
new file mode 100644
index 0000000000000..80b936318334c
--- /dev/null
+++ b/clang/test/CIR/CodeGen/forrange.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
+
+struct Element {};
+struct Container {};
+
+Element *begin(Container &);
+Element *end(Container &);
+
+void for_range() {
+  Container c;
+  for (Element &e : c)
+    ;
+}
+
+// CIR: cir.func @_Z5beginR9Container(!cir.ptr<!rec_Container>) -> !cir.ptr<!rec_Element>
+// CIR: cir.func @_Z3endR9Container(!cir.ptr<!rec_Container>) -> !cir.ptr<!rec_Element
+
+// CIR: cir.func @_Z9for_rangev()
+// CIR:    %[[C_ADDR:.*]] = cir.alloca !rec_Container{{.*}} ["c"]
+// CIR:    cir.scope {
+// CIR:      %[[RANGE_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Container>{{.*}} ["__range1", init, const]
+// CIR:      %[[BEGIN_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Element>{{.*}} ["__begin1", init]
+// CIR:      %[[END_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Element>{{.*}} ["__end1", init]
+// CIR:      %[[E_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Element>{{.*}} ["e", init, const]
+// CIR:      cir.store %[[C_ADDR]], %[[RANGE_ADDR]]
+// CIR:      %[[C_REF:.*]] = cir.load %[[RANGE_ADDR]]
+// CIR:      %[[BEGIN:.*]] = cir.call @_Z5beginR9Container(%[[C_REF]])
+// CIR:      cir.store %[[BEGIN]], %[[BEGIN_ADDR]]
+// CIR:      %[[C_REF2:.*]] = cir.load %[[RANGE_ADDR]]
+// CIR:      %[[END:.*]] = cir.call @_Z3endR9Container(%[[C_REF2]])
+// CIR:      cir.store %[[END]], %[[END_ADDR]]
+// CIR:      cir.for : cond {
+// CIR:        %[[BEGIN:.*]] = cir.load %[[BEGIN_ADDR]]
+// CIR:        %[[END:.*]] = cir.load %[[END_ADDR]]
+// CIR:        %[[CMP:.*]] = cir.cmp(ne, %[[BEGIN]], %[[END]])
+// CIR:        cir.condition(%[[CMP]])
+// CIR:      } body {
+// CIR:        %[[E:.*]] = cir.load deref %[[BEGIN_ADDR]]
+// CIR:        cir.store %[[E]], %[[E_ADDR]]
+// CIR:        cir.yield
+// CIR:      } step {
+// CIR:        %[[BEGIN:.*]] = cir.load %[[BEGIN_ADDR]]
+// CIR:        %[[STEP:.*]] = cir.const #cir.int<1>
+// CIR:        %[[NEXT:.*]] = cir.ptr_stride(%[[BEGIN]] {{.*}}, %[[STEP]] {{.*}})
+// CIR:        cir.store %[[NEXT]], %[[BEGIN_ADDR]]
+// CIR:        cir.yield
+// CIR:      }
+// CIR:    }

@llvmbot
Copy link
Member

llvmbot commented May 8, 2025

@llvm/pr-subscribers-clangir

Author: Andy Kaylor (andykaylor)

Changes

This adds a test to verify range for loops based on begin() and end() funtion calls. The functionality to enable this was added in previous commits, but those commits were only indirectly related to this test. The general intent of this commit is to work towards enabling iterator-based range for loops.

The test did reveal one minor problem in call argument handling, which is corrected here.


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

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+1-1)
  • (added) clang/test/CIR/CodeGen/forrange.cpp (+49)
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index bed0db28818f1..693e73ceb62ab 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -304,7 +304,7 @@ void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
 
   if (e->isGLValue()) {
     assert(e->getObjectKind() == OK_Ordinary);
-    args.add(emitReferenceBindingToExpr(e), argType);
+    return args.add(emitReferenceBindingToExpr(e), argType);
   }
 
   bool hasAggregateEvalKind = hasAggregateEvaluationKind(argType);
diff --git a/clang/test/CIR/CodeGen/forrange.cpp b/clang/test/CIR/CodeGen/forrange.cpp
new file mode 100644
index 0000000000000..80b936318334c
--- /dev/null
+++ b/clang/test/CIR/CodeGen/forrange.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
+
+struct Element {};
+struct Container {};
+
+Element *begin(Container &);
+Element *end(Container &);
+
+void for_range() {
+  Container c;
+  for (Element &e : c)
+    ;
+}
+
+// CIR: cir.func @_Z5beginR9Container(!cir.ptr<!rec_Container>) -> !cir.ptr<!rec_Element>
+// CIR: cir.func @_Z3endR9Container(!cir.ptr<!rec_Container>) -> !cir.ptr<!rec_Element
+
+// CIR: cir.func @_Z9for_rangev()
+// CIR:    %[[C_ADDR:.*]] = cir.alloca !rec_Container{{.*}} ["c"]
+// CIR:    cir.scope {
+// CIR:      %[[RANGE_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Container>{{.*}} ["__range1", init, const]
+// CIR:      %[[BEGIN_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Element>{{.*}} ["__begin1", init]
+// CIR:      %[[END_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Element>{{.*}} ["__end1", init]
+// CIR:      %[[E_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Element>{{.*}} ["e", init, const]
+// CIR:      cir.store %[[C_ADDR]], %[[RANGE_ADDR]]
+// CIR:      %[[C_REF:.*]] = cir.load %[[RANGE_ADDR]]
+// CIR:      %[[BEGIN:.*]] = cir.call @_Z5beginR9Container(%[[C_REF]])
+// CIR:      cir.store %[[BEGIN]], %[[BEGIN_ADDR]]
+// CIR:      %[[C_REF2:.*]] = cir.load %[[RANGE_ADDR]]
+// CIR:      %[[END:.*]] = cir.call @_Z3endR9Container(%[[C_REF2]])
+// CIR:      cir.store %[[END]], %[[END_ADDR]]
+// CIR:      cir.for : cond {
+// CIR:        %[[BEGIN:.*]] = cir.load %[[BEGIN_ADDR]]
+// CIR:        %[[END:.*]] = cir.load %[[END_ADDR]]
+// CIR:        %[[CMP:.*]] = cir.cmp(ne, %[[BEGIN]], %[[END]])
+// CIR:        cir.condition(%[[CMP]])
+// CIR:      } body {
+// CIR:        %[[E:.*]] = cir.load deref %[[BEGIN_ADDR]]
+// CIR:        cir.store %[[E]], %[[E_ADDR]]
+// CIR:        cir.yield
+// CIR:      } step {
+// CIR:        %[[BEGIN:.*]] = cir.load %[[BEGIN_ADDR]]
+// CIR:        %[[STEP:.*]] = cir.const #cir.int<1>
+// CIR:        %[[NEXT:.*]] = cir.ptr_stride(%[[BEGIN]] {{.*}}, %[[STEP]] {{.*}})
+// CIR:        cir.store %[[NEXT]], %[[BEGIN_ADDR]]
+// CIR:        cir.yield
+// CIR:      }
+// CIR:    }

@andykaylor andykaylor merged commit c3ca0fb into llvm:main May 9, 2025
14 checks passed
@andykaylor andykaylor deleted the cir-test-forrange branch May 12, 2025 16:21
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.

4 participants