Skip to content

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