Skip to content

Conversation

ghost
Copy link

@ghost ghost commented Sep 7, 2025

These tests were migrated from clang/test/CIR-Incubator to clang/test/CIR without modification.

  • Only tests that pass under the current configuration were moved.
  • No refactors, no removals, no CMake or lit changes were made.
  • This is part of the incremental upstreaming effort.

Test discovery and migration were semi-automated based on lit output.

@andykaylor
#156747

@github-actions
Copy link

github-actions bot commented Sep 7, 2025

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Sep 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 7, 2025

@llvm/pr-subscribers-clangir

@llvm/pr-subscribers-clang

Author: Burhan Söğüt (bursot)

Changes

These tests were migrated from clang/test/CIR-Incubator to clang/test/CIR without modification.

  • Only tests that pass under the current configuration were moved.
  • No refactors, no removals, no CMake or lit changes were made.
  • This is part of the incremental upstreaming effort.

Test discovery and migration were semi-automated based on lit output.

cc: @AndyNZhang


Patch is 72.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/157333.diff

48 Files Affected:

  • (added) clang/test/CIR/CodeGen/OpenMP/taskwait.cpp (+9)
  • (added) clang/test/CIR/CodeGen/StringExample.cpp (+34)
  • (added) clang/test/CIR/CodeGen/binassign.cpp (+75)
  • (added) clang/test/CIR/CodeGen/bswap.cpp (+30)
  • (added) clang/test/CIR/CodeGen/c89-implicit-int.c (+10)
  • (added) clang/test/CIR/CodeGen/comma.cpp (+30)
  • (added) clang/test/CIR/CodeGen/complex-cast.c (+264)
  • (added) clang/test/CIR/CodeGen/compound-literal-empty.c (+18)
  • (added) clang/test/CIR/CodeGen/expressions.cpp (+11)
  • (added) clang/test/CIR/CodeGen/func_dsolocal_pie.c (+34)
  • (added) clang/test/CIR/CodeGen/gnu89.c (+5)
  • (added) clang/test/CIR/CodeGen/if-constexpr.cpp (+92)
  • (added) clang/test/CIR/CodeGen/implicit-return.cpp (+26)
  • (added) clang/test/CIR/CodeGen/inc-bool.cpp (+14)
  • (added) clang/test/CIR/CodeGen/inc-dec.cpp (+55)
  • (added) clang/test/CIR/CodeGen/lalg.c (+20)
  • (added) clang/test/CIR/CodeGen/literals.c (+9)
  • (added) clang/test/CIR/CodeGen/literals.cpp (+8)
  • (added) clang/test/CIR/CodeGen/loop-scope.cpp (+32)
  • (added) clang/test/CIR/CodeGen/lvalue-refs.cpp (+19)
  • (added) clang/test/CIR/CodeGen/ms-intrinsics-other.c (+55)
  • (added) clang/test/CIR/CodeGen/no-pie.c (+11)
  • (added) clang/test/CIR/CodeGen/no-proto-fun-ptr.c (+27)
  • (added) clang/test/CIR/CodeGen/no-proto-is-void.cpp (+13)
  • (added) clang/test/CIR/CodeGen/null-arithmatic-expression.c (+12)
  • (added) clang/test/CIR/CodeGen/operators.cpp (+14)
  • (added) clang/test/CIR/CodeGen/optimization-attr.cpp (+32)
  • (added) clang/test/CIR/CodeGen/pointer.cpp (+6)
  • (added) clang/test/CIR/CodeGen/return.cpp (+33)
  • (added) clang/test/CIR/CodeGen/shift.cpp (+8)
  • (added) clang/test/CIR/CodeGen/spelling-locations.cpp (+100)
  • (added) clang/test/CIR/CodeGen/std-array.cpp (+13)
  • (added) clang/test/CIR/CodeGen/stmt-expr.c (+42)
  • (added) clang/test/CIR/CodeGen/store.c (+29)
  • (added) clang/test/CIR/CodeGen/switch-unreachable-after-break.cpp (+49)
  • (added) clang/test/CIR/CodeGen/trap.cpp (+28)
  • (added) clang/test/CIR/CodeGen/types-IEEE-quad.c (+32)
  • (added) clang/test/CIR/CodeGen/types-nullptr.cpp (+9)
  • (added) clang/test/CIR/CodeGen/types.c (+46)
  • (added) clang/test/CIR/CodeGen/unary.c (+44)
  • (added) clang/test/CIR/CodeGen/unreachable.cpp (+28)
  • (added) clang/test/CIR/Lowering/bitfieils.c (+32)
  • (added) clang/test/CIR/Lowering/global-ptr.c (+55)
  • (added) clang/test/CIR/Lowering/nested-switch.cpp (+69)
  • (added) clang/test/CIR/Lowering/str.c (+9)
  • (added) clang/test/CIR/Lowering/switch-while.c (+84)
  • (added) clang/test/CIR/hello.c (+5)
  • (added) clang/test/CIR/test.c (+1)
diff --git a/clang/test/CIR/CodeGen/OpenMP/taskwait.cpp b/clang/test/CIR/CodeGen/OpenMP/taskwait.cpp
new file mode 100644
index 0000000000000..3b2059a8b9655
--- /dev/null
+++ b/clang/test/CIR/CodeGen/OpenMP/taskwait.cpp
@@ -0,0 +1,9 @@
+// TODO: fix crash in emitTaskWaitCall
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fopenmp-enable-irbuilder -fopenmp -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+// CHECK: cir.func
+void omp_taskwait_1(){
+// CHECK-DISABLE: omp.taskwait
+//  #pragma omp taskwait
+}
diff --git a/clang/test/CIR/CodeGen/StringExample.cpp b/clang/test/CIR/CodeGen/StringExample.cpp
new file mode 100644
index 0000000000000..a2c0ef374f1ca
--- /dev/null
+++ b/clang/test/CIR/CodeGen/StringExample.cpp
@@ -0,0 +1,34 @@
+// RUN: true
+
+int strlen(char const *);
+void puts(char const *);
+
+struct String {
+  long size;
+  long capacity;
+  char *storage;
+
+  String() : size{0}, capacity{0}, storage{nullptr} {}
+  String(char const *s) : size{strlen(s)}, capacity{size},
+                          storage{new char[capacity]} {}
+};
+
+struct StringView {
+  long size;
+  char *storage;
+
+  StringView(const String &s) : size{s.size}, storage{s.storage} {}
+  StringView() : size{0}, storage{nullptr} {}
+};
+
+int main() {
+  StringView sv;
+  {
+    String s = "Hi";
+    sv = s;
+
+    puts(sv.storage);
+  }
+
+  puts(sv.storage);
+}
diff --git a/clang/test/CIR/CodeGen/binassign.cpp b/clang/test/CIR/CodeGen/binassign.cpp
new file mode 100644
index 0000000000000..934742d13404a
--- /dev/null
+++ b/clang/test/CIR/CodeGen/binassign.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+int foo(int a, int b) {
+  int x = a * b;
+  x *= b;
+  x /= b;
+  x %= b;
+  x += b;
+  x -= b;
+  x >>= b;
+  x <<= b;
+  x &= b;
+  x ^= b;
+  x |= b;
+  return x;
+}
+
+// CHECK: [[Value:%[0-9]+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init] {alignment = 4 : i64}
+// CHECK: = cir.binop(mul,
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: = cir.binop(mul,
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: cir.binop(div,
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: = cir.binop(rem,  {{.*}} loc([[SourceLocation:#loc[0-9]+]])
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: = cir.binop(add,
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: = cir.binop(sub,
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: = cir.shift(right
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: = cir.shift(left
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: = cir.binop(and,
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: = cir.binop(xor,
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+// CHECK: = cir.load {{.*}}[[Value]]
+// CHECK: = cir.binop(or,
+// CHECK: cir.store{{.*}} {{.*}}[[Value]]
+
+typedef enum {
+  A = 3,
+} enumy;
+
+enumy getty();
+
+void exec() {
+  enumy r;
+  if ((r = getty()) < 0) {}
+}
+
+// CHECK: cir.func dso_local @_Z4execv()
+// CHECK:   %0 = cir.alloca !u32i, !cir.ptr<!u32i>, ["r"] {alignment = 4 : i64}
+// CHECK:   cir.scope {
+// CHECK:     %1 = cir.call @_Z5gettyv() : () -> !u32i
+// CHECK:     cir.store{{.*}} %1, %0 : !u32i, !cir.ptr<!u32i>
+// CHECK:     %2 = cir.cast(integral, %1 : !u32i), !s32i
+// CHECK:     %3 = cir.const #cir.int<0> : !s32i
+// CHECK:     %4 = cir.cmp(lt, %2, %3) : !s32i, !cir.bool
+// CHECK:     cir.if %4 {
+
+// CHECK: [[SourceLocationB:#loc[0-9]+]] = loc("{{.*}}binassign.cpp":8:8)
+// CHECK: [[SourceLocationA:#loc[0-9]+]] = loc("{{.*}}binassign.cpp":8:3)
+// CHECK: [[SourceLocation]] = loc(fused[[[SourceLocationA]], [[SourceLocationB]]])
diff --git a/clang/test/CIR/CodeGen/bswap.cpp b/clang/test/CIR/CodeGen/bswap.cpp
new file mode 100644
index 0000000000000..3473b64ac7228
--- /dev/null
+++ b/clang/test/CIR/CodeGen/bswap.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+using u16 = unsigned short;
+using u32 = unsigned int;
+using u64 = unsigned long long;
+
+u16 bswap_u16(u16 x) {
+  return __builtin_bswap16(x);
+}
+
+// CHECK: cir.func dso_local @_Z9bswap_u16t
+// CHECK:   %{{.+}} = cir.byte_swap %{{.+}} : !u16i
+// CHECK: }
+
+u32 bswap_u32(u32 x) {
+  return __builtin_bswap32(x);
+}
+
+// CHECK: cir.func dso_local @_Z9bswap_u32j
+// CHECK:   %{{.+}} = cir.byte_swap %{{.+}} : !u32i
+// CHECK: }
+
+u64 bswap_u64(u64 x) {
+  return __builtin_bswap64(x);
+}
+
+// CHECK: cir.func dso_local @_Z9bswap_u64y
+// CHECK:   %{{.+}} = cir.byte_swap %{{.+}} : !u64i
+// CHECK: }
diff --git a/clang/test/CIR/CodeGen/c89-implicit-int.c b/clang/test/CIR/CodeGen/c89-implicit-int.c
new file mode 100644
index 0000000000000..4e2392c44a802
--- /dev/null
+++ b/clang/test/CIR/CodeGen/c89-implicit-int.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c89 -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+// Implicit int return type.
+test = 0;
+// CHECK: cir.global external @test = #cir.int<0> : !s32i
+func (void) {
+// CHECK: cir.func dso_local @func() -> !s32i
+  return 0;
+}
diff --git a/clang/test/CIR/CodeGen/comma.cpp b/clang/test/CIR/CodeGen/comma.cpp
new file mode 100644
index 0000000000000..e10be4ac02288
--- /dev/null
+++ b/clang/test/CIR/CodeGen/comma.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+int c0() {
+    int a = 1;
+    int b = 2;
+    return b + 1, a;
+}
+
+// CHECK: cir.func dso_local @_Z2c0v() -> !s32i
+// CHECK: %[[#RET:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
+// CHECK: %[[#A:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
+// CHECK: %[[#B:]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
+// CHECK: %[[#LOADED_B:]] = cir.load{{.*}} %[[#B]] : !cir.ptr<!s32i>, !s32i
+// CHECK: %[[#]] = cir.binop(add, %[[#LOADED_B]], %[[#]]) nsw : !s32i
+// CHECK: %[[#LOADED_A:]] = cir.load{{.*}} %[[#A]] : !cir.ptr<!s32i>, !s32i
+// CHECK: cir.store{{.*}} %[[#LOADED_A]], %[[#RET]] : !s32i, !cir.ptr<!s32i>
+
+int &foo1();
+int &foo2();
+
+void c1() {
+    int &x = (foo1(), foo2());
+}
+
+// CHECK: cir.func dso_local @_Z2c1v()
+// CHECK: %0 = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
+// CHECK: %1 = cir.call @_Z4foo1v() : () -> !cir.ptr<!s32i>
+// CHECK: %2 = cir.call @_Z4foo2v() : () -> !cir.ptr<!s32i>
+// CHECK: cir.store{{.*}} %2, %0 : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
diff --git a/clang/test/CIR/CodeGen/complex-cast.c b/clang/test/CIR/CodeGen/complex-cast.c
new file mode 100644
index 0000000000000..5212625694447
--- /dev/null
+++ b/clang/test/CIR/CodeGen/complex-cast.c
@@ -0,0 +1,264 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -mmlir --mlir-print-ir-before=cir-lowering-prepare -o %t.cir %s 2>&1 | FileCheck --check-prefixes=CIR-BEFORE,CHECK %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -mmlir --mlir-print-ir-after=cir-lowering-prepare -o %t.cir %s 2>&1 | FileCheck --check-prefixes=CIR-AFTER,CHECK %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --input-file=%t.ll --check-prefixes=LLVM,CHECK %s
+
+#include <stdbool.h>
+
+volatile double _Complex cd;
+volatile float _Complex cf;
+volatile int _Complex ci;
+volatile short _Complex cs;
+volatile double sd;
+volatile int si;
+volatile bool b;
+
+void scalar_to_complex() {
+  cd = sd;
+  ci = si;
+  cd = si;
+  ci = sd;
+}
+
+// CHECK-LABEL: @scalar_to_complex()
+
+// CIR-BEFORE: %{{.+}} = cir.cast(float_to_complex, %{{.+}} : !cir.double), !cir.complex<!cir.double>
+
+//      CIR-AFTER: %[[#REAL:]] = cir.load volatile{{.*}}  %{{.+}} : !cir.ptr<!cir.double>, !cir.double
+// CIR-AFTER-NEXT: %[[#IMAG:]] = cir.const #cir.fp<0.000000e+00> : !cir.double
+// CIR-AFTER-NEXT: %{{.+}} = cir.complex.create %[[#REAL]], %[[#IMAG]] : !cir.double -> !cir.complex<!cir.double>
+
+// CIR-BEFORE: %{{.+}} = cir.cast(int_to_complex, %{{.+}} : !s32i), !cir.complex<!s32i>
+
+//      CIR-AFTER: %[[#REAL:]] = cir.load volatile{{.*}}  %{{.+}} : !cir.ptr<!s32i>, !s32i
+// CIR-AFTER-NEXT: %[[#IMAG:]] = cir.const #cir.int<0> : !s32i
+// CIR-AFTER-NEXT: %{{.+}} = cir.complex.create %[[#REAL]], %[[#IMAG]] : !s32i -> !cir.complex<!s32i>
+
+//      CIR-BEFORE: %[[#A:]] = cir.cast(int_to_float, %{{.+}} : !s32i), !cir.double
+// CIR-BEFORE-NEXT: %{{.+}} = cir.cast(float_to_complex, %[[#A]] : !cir.double), !cir.complex<!cir.double>
+
+//      CIR-AFTER: %[[#A:]] = cir.load volatile{{.*}}  %{{.+}} : !cir.ptr<!s32i>, !s32i
+// CIR-AFTER-NEXT: %[[#REAL:]] = cir.cast(int_to_float, %[[#A]] : !s32i), !cir.double
+// CIR-AFTER-NEXT: %[[#IMAG:]] = cir.const #cir.fp<0.000000e+00> : !cir.double
+// CIR-AFTER-NEXT: %{{.+}} = cir.complex.create %[[#REAL]], %[[#IMAG]] : !cir.double -> !cir.complex<!cir.double>
+
+//      CIR-BEFORE: %[[#A:]] = cir.cast(float_to_int, %{{.+}} : !cir.double), !s32i
+// CIR-BEFORE-NEXT: %{{.+}} = cir.cast(int_to_complex, %[[#A]] : !s32i), !cir.complex<!s32i>
+
+//      CIR-AFTER: %[[#A:]] = cir.load volatile{{.*}}  %{{.+}} : !cir.ptr<!cir.double>, !cir.double
+// CIR-AFTER-NEXT: %[[#REAL:]] = cir.cast(float_to_int, %[[#A]] : !cir.double), !s32i
+// CIR-AFTER-NEXT: %[[#IMAG:]] = cir.const #cir.int<0> : !s32i
+// CIR-AFTER-NEXT: %{{.+}} = cir.complex.create %[[#REAL]], %[[#IMAG]] : !s32i -> !cir.complex<!s32i>
+
+//      LLVM: %[[#REAL:]] = load volatile double, ptr @sd, align 8
+// LLVM-NEXT: %[[#A:]] = insertvalue { double, double } {{.*}}, double %[[#REAL]], 0
+// LLVM-NEXT: %{{.+}} = insertvalue { double, double } %[[#A]], double 0.000000e+00, 1
+
+//      LLVM: %[[#REAL:]] = load volatile i32, ptr @si, align 4
+// LLVM-NEXT: %[[#A:]] = insertvalue { i32, i32 } {{.*}}, i32 %[[#REAL]], 0
+// LLVM-NEXT: %{{.+}} = insertvalue { i32, i32 } %[[#A]], i32 0, 1
+
+//      LLVM: %[[#A:]] = load volatile i32, ptr @si, align 4
+// LLVM-NEXT: %[[#REAL:]] = sitofp i32 %[[#A]] to double
+// LLVM-NEXT: %[[#B:]] = insertvalue { double, double } {{.*}}, double %[[#REAL]], 0
+// LLVM-NEXT: %{{.+}} = insertvalue { double, double } %[[#B]], double 0.000000e+00, 1
+
+//      LLVM: %[[#A:]] = load volatile double, ptr @sd, align 8
+// LLVM-NEXT: %[[#REAL:]] = fptosi double %[[#A]] to i32
+// LLVM-NEXT: %[[#B:]] = insertvalue { i32, i32 } {{.*}}, i32 %[[#REAL]], 0
+// LLVM-NEXT: %{{.+}} = insertvalue { i32, i32 } %[[#B]], i32 0, 1
+
+// CHECK: }
+
+void scalar_to_complex_explicit() {
+  cd = (double _Complex)sd;
+  ci = (int _Complex)si;
+  cd = (double _Complex)si;
+  ci = (int _Complex)sd;
+}
+
+// CHECK-LABEL: @scalar_to_complex_explicit()
+
+// CIR-BEFORE: %{{.+}} = cir.cast(float_to_complex, %{{.+}} : !cir.double), !cir.complex<!cir.double>
+
+//      CIR-AFTER: %[[#IMAG:]] = cir.const #cir.fp<0.000000e+00> : !cir.double
+// CIR-AFTER-NEXT: %{{.+}} = cir.complex.create %{{.+}}, %[[#IMAG]] : !cir.double -> !cir.complex<!cir.double>
+
+//      LLVM: %[[#A:]] = insertvalue { double, double } {{.*}}, double %{{.+}}, 0
+// LLVM-NEXT: %{{.+}} = insertvalue { double, double } %[[#A]], double 0.000000e+00, 1
+
+// CIR-BEFORE: %{{.+}} = cir.cast(int_to_complex, %{{.+}} : !s32i), !cir.complex<!s32i>
+
+//      CIR-AFTER: %[[#IMAG:]] = cir.const #cir.int<0> : !s32i
+// CIR-AFTER-NEXT: %{{.+}} = cir.complex.create %{{.+}}, %[[#IMAG]] : !s32i -> !cir.complex<!s32i>
+
+//      LLVM: %[[#A:]] = insertvalue { i32, i32 } {{.*}}, i32 %{{.+}}, 0
+// LLVM-NEXT: %{{.+}} = insertvalue { i32, i32 } %[[#A]], i32 0, 1
+
+//      CIR-BEFORE: %[[#A:]] = cir.cast(int_to_float, %{{.+}} : !s32i), !cir.double
+// CIR-BEFORE-NEXT: %{{.+}} = cir.cast(float_to_complex, %[[#A]] : !cir.double), !cir.complex<!cir.double>
+
+//      CIR-AFTER: %[[#REAL:]] = cir.cast(int_to_float, %11 : !s32i), !cir.double
+// CIR-AFTER-NEXT: %[[#IMAG:]] = cir.const #cir.fp<0.000000e+00> : !cir.double
+// CIR-AFTER-NEXT: %{{.+}} = cir.complex.create %[[#REAL]], %[[#IMAG]] : !cir.double -> !cir.complex<!cir.double>
+
+//      LLVM: %[[#REAL:]] = sitofp i32 %{{.+}} to double
+// LLVM-NEXT: %[[#A:]] = insertvalue { double, double } {{.*}}, double %[[#REAL]], 0
+// LLVM-NEXT: %{{.+}} = insertvalue { double, double } %[[#A]], double 0.000000e+00, 1
+
+//      CIR-BEFORE: %[[#A:]] = cir.cast(float_to_int, %{{.+}} : !cir.double), !s32i
+// CIR-BEFORE-NEXT: %{{.+}} = cir.cast(int_to_complex, %[[#A]] : !s32i), !cir.complex<!s32i>
+
+//      CIR-AFTER: %[[#REAL:]] = cir.cast(float_to_int, %{{.+}} : !cir.double), !s32i
+// CIR-AFTER-NEXT: %[[#IMAG:]] = cir.const #cir.int<0> : !s32i
+// CIR-AFTER-NEXT: %{{.+}} = cir.complex.create %[[#REAL]], %[[#IMAG]] : !s32i -> !cir.complex<!s32i>
+
+//      LLVM: %[[#REAL:]] = fptosi double %{{.+}} to i32
+// LLVM-NEXT: %[[#A:]] = insertvalue { i32, i32 } {{.*}}, i32 %[[#REAL]], 0
+// LLVM-NEXT: %{{.+}} = insertvalue { i32, i32 } %[[#A]], i32 0, 1
+
+// CHECK: }
+
+void complex_to_scalar() {
+  sd = (double)cd;
+  si = (int)ci;
+  sd = (double)ci;
+  si = (int)cd;
+}
+
+// CHECK-LABEL: @complex_to_scalar()
+
+// CIR-BEFORE: %{{.+}} = cir.cast(float_complex_to_real, %{{.+}} : !cir.complex<!cir.double>), !cir.double
+
+// CIR-AFTER: %{{.+}} = cir.complex.real %{{.+}} : !cir.complex<!cir.double> -> !cir.double
+
+// LLVM: %{{.+}} = extractvalue { double, double } %{{.+}}, 0
+
+// CIR-BEFORE: %{{.+}} = cir.cast(int_complex_to_real, %{{.+}} : !cir.complex<!s32i>), !s32i
+
+// CIR-AFTER: %{{.+}} = cir.complex.real %{{.+}} : !cir.complex<!s32i> -> !s32i
+
+// LLVM: %{{.+}} = extractvalue { i32, i32 } %{{.+}}, 0
+
+//      CIR-BEFORE: %[[#A:]] = cir.cast(int_complex_to_real, %{{.+}} : !cir.complex<!s32i>), !s32i
+// CIR-BEFORE-NEXT: %{{.+}} = cir.cast(int_to_float, %[[#A]] : !s32i), !cir.double
+
+//      CIR-AFTER: %[[#A:]] = cir.complex.real %{{.+}} : !cir.complex<!s32i> -> !s32i
+// CIR-AFTER-NEXT: %{{.+}} = cir.cast(int_to_float, %[[#A]] : !s32i), !cir.double
+
+//      LLVM: %[[#A:]] = extractvalue { i32, i32 } %{{.+}}, 0
+// LLVM-NEXT: %{{.+}} = sitofp i32 %[[#A]] to double
+
+//      CIR-BEFORE: %[[#A:]] = cir.cast(float_complex_to_real, %{{.+}} : !cir.complex<!cir.double>), !cir.double
+// CIR-BEFORE-NEXT: %{{.+}} = cir.cast(float_to_int, %[[#A]] : !cir.double), !s32i
+
+//      CIR-AFTER: %[[#A:]] = cir.complex.real %{{.+}} : !cir.complex<!cir.double> -> !cir.double
+// CIR-AFTER-NEXT: %{{.+}} = cir.cast(float_to_int, %[[#A]] : !cir.double), !s32i
+
+//      LLVM: %[[#A:]] = extractvalue { double, double } %{{.+}}, 0
+// LLVM-NEXT: %{{.+}} = fptosi double %[[#A]] to i32
+
+// CHECK: }
+
+void complex_to_bool() {
+  b = (bool)cd;
+  b = (bool)ci;
+}
+
+// CHECK-LABEL: @complex_to_bool()
+
+// CIR-BEFORE: %{{.+}} = cir.cast(float_complex_to_bool, %{{.+}} : !cir.complex<!cir.double>), !cir.bool
+
+//      CIR-AFTER: %[[#REAL:]] = cir.complex.real %{{.+}} : !cir.complex<!cir.double> -> !cir.double
+// CIR-AFTER-NEXT: %[[#IMAG:]] = cir.complex.imag %{{.+}} : !cir.complex<!cir.double> -> !cir.double
+// CIR-AFTER-NEXT: %[[#RB:]] = cir.cast(float_to_bool, %[[#REAL]] : !cir.double), !cir.bool
+// CIR-AFTER-NEXT: %[[#IB:]] = cir.cast(float_to_bool, %[[#IMAG]] : !cir.double), !cir.bool
+// CIR-AFTER-NEXT: %[[#A:]] = cir.const #true
+// CIR-AFTER-NEXT: %{{.+}} = cir.select if %[[#RB]] then %[[#A]] else %[[#IB]] : (!cir.bool, !cir.bool, !cir.bool) -> !cir.bool
+
+//      LLVM:   %[[#REAL:]] = extractvalue { double, double } %{{.+}}, 0
+// LLVM-NEXT:   %[[#IMAG:]] = extractvalue { double, double } %{{.+}}, 1
+// LLVM-NEXT:   %[[#RB:]] = fcmp une double %[[#REAL]], 0.000000e+00
+// LLVM-NEXT:   %[[#IB:]] = fcmp une double %[[#IMAG]], 0.000000e+00
+// LLVM-NEXT:   %{{.+}} = or i1 %[[#RB]], %[[#IB]]
+
+// CIR-BEFORE: %{{.+}} = cir.cast(int_complex_to_bool, %{{.+}} : !cir.complex<!s32i>), !cir.bool
+
+//      CIR-AFTER: %[[#REAL:]] = cir.complex.real %{{.+}} : !cir.complex<!s32i> -> !s32i
+// CIR-AFTER-NEXT: %[[#IMAG:]] = cir.complex.imag %{{.+}} : !cir.complex<!s32i> -> !s32i
+// CIR-AFTER-NEXT: %[[#RB:]] = cir.cast(int_to_bool, %[[#REAL]] : !s32i), !cir.bool
+// CIR-AFTER-NEXT: %[[#IB:]] = cir.cast(int_to_bool, %[[#IMAG]] : !s32i), !cir.bool
+// CIR-AFTER-NEXT: %[[#A:]] = cir.const #true
+// CIR-AFTER-NEXT: %{{.+}} = cir.select if %[[#RB]] then %[[#A]] else %[[#IB]] : (!cir.bool, !cir.bool, !cir.bool) -> !cir.bool
+
+//      LLVM:   %[[#REAL:]] = extractvalue { i32, i32 } %{{.+}}, 0
+// LLVM-NEXT:   %[[#IMAG:]] = extractvalue { i32, i32 } %{{.+}}, 1
+// LLVM-NEXT:   %[[#RB:]] = icmp ne i32 %[[#REAL]], 0
+// LLVM-NEXT:   %[[#IB:]] = icmp ne i32 %[[#IMAG]], 0
+// LLVM-NEXT:   %{{.+}} = or i1 %[[#RB]], %[[#IB]]
+
+// CHECK: }
+
+struct CX {
+  double real;
+  double imag;
+};
+
+void lvalue_to_rvalue_bitcast() {
+   struct CX a;
+   double _Complex b = __builtin_bit_cast(double _Complex, a);
+}
+
+// CHECK-LABEL: @lvalue_to_rvalue_bitcast()
+
+// CIR-BEFORE: %{{.+}} = cir.cast(bitcast, %{{.+}} : !cir.ptr<!rec_CX>), !cir.ptr<!cir.complex<!cir.double>>
+
+// CIR-AFTER: %{{.+}} = cir.cast(bitcast, %{{.+}} : !cir.ptr<!rec_CX>), !cir.ptr<!cir.complex<!cir.double>>
+
+// LLVM: %[[PTR_ADDR:.*]] = alloca %struct.CX, i64 1, align 8
+// LLVM: %[[COMPLEX_ADDR:.*]] = alloca { double, double }, i64 1, align 8
+// LLVM: %[[PTR_TO_COMPLEX:.*]] = load { double, double }, ptr %[[PTR_ADDR]], align 8
+// LLVM: store { double, double } %[[PTR_TO_COMPLEX]], ptr %[[COMPLEX_ADDR]], align 8
+
+// CHECK: }
+
+void complex_to_complex_cast() {
+  cd = cf;
+  ci = cs;
+}
+
+// CIR-BEFORE: %[[TMP:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
+// CIR-BEFORE: %[[FP_COMPLEX:.*]] = cir.cast(float_complex, %[[TMP]] : !cir.complex<!cir.float>), !cir.complex<!cir.double>
+
+// CIR-AFTER: %[[#REAL:]] = cir.complex.real %{{.*}} : !cir.complex<!cir.float> -> !cir.float
+// CIR-AFTER: %[[#IMAG:]] = cir.complex.imag %{{.*}} : !cir.complex<!cir.float> -> !cir.float
+// CIR-AFTER: %[[#REAL_FP_CAST:]] = cir.cast(floating, %[[#REAL]] : !cir.float), !cir.double
+// CIR-AFTER: %[[#IMAG_FP_CAST:]] = cir.cast(floating, %[[#IMAG]] : !cir.float), !cir.double
+// CIR-AFTER: %{{.*}} = cir.complex.create %[[#REAL_FP_CAST]], %[[#IMAG_FP_CAST]] : !cir.double -> !cir.complex<!cir.double>
+
+// LLVM: %[[#REAL:]] = extractvalue { float, float } %{{.*}}, 0
+// LLVM: %[[#IMAG:]] = extractvalue { float, float } %{{.*}}, 1
+// LLVM: %[[#REAL_FP_CAST:]] = fpext float %[[#REAL]] to double
+// LLVM: %[[#IMAG_FP_CAST:]] = fpext float %[[#IMAG]] to double
+// LLVM: %[[TMP:.*]] = insertvalue { double, double } {{.*}}, double %[[#REAL_FP_CAST]], 0
+// LLVM: %{{.*}} = insertvalue { double, double } %[[TMP]], double %[[#IMAG_FP_CAST]], 1
+
+// CIR-BEFORE: %[[TMP:.*]] = cir.load{{.*}} %{{.*}} : !cir.ptr<!cir.complex<!s16i>>, !cir.complex<!s16i>
+// CIR-BEFORE: %[[INT_COMPLEX:.*]] = cir.cast(int_complex, %[[TMP]] : !cir.complex<!s16i>), !cir.complex<!s32i>
+
+// CIR-AFTER: %[[#REAL:]] = cir.complex.real %{{.*}} : !cir.complex<!s16i> -> !s16i
+// CIR-AFTER: %[[#IMAG:]] = cir.complex.imag %{{.*}} : !cir.complex<!s16i> -> !s16i
+// CIR-AFTER: %[[#REAL_INT_CAST:]] = cir.cast(integral, %[[#REAL]] : !s16i), !s32i
+// CIR-AFTER: %[[#IMAG_INT_CAST:]] = cir.cast(integral, %[[#IMAG]] : !s16i), !s32i
+// CIR-AFTER: %{{.*}} = cir.complex.create %[[#REAL_INT_CAST]], %[[#IMAG_INT_CAST]] : !s32i -> !cir.complex<!s32i>
+
+// LLVM: %[[#REAL:]] = extractvalue { i16, i16 } %{{.*}}, 0
+// LLVM: %[[#IMAG:]] = extractvalue { i16, i16 } %{{.*}}, 1
+// LLVM: %[[#REAL_INT_CAST:]] = sext i16 %[[#REAL]] to i32
+// LLVM: %[[#IMAG_INT_CAST:]] = sext i16 %[[#IMAG]] to i32
+// LLVM: %[[TMP:.*]] = insertvalue { i32, i32 } {{.*}}, i32 %[[#REAL_INT_CAST]], 0
+// LLVM: %{{.*}} = insertvalue { i32, i32 } %[[TMP]], i32 %[[#IMAG_INT_CAST]], 1
+
+void promotion() {
+  cd = cf + cf;
+}
diff --git a/clang/test/CIR/CodeGen/compound-literal-empty.c b/clang/test/CIR/CodeGen/compound-literal-empty.c
new file mode 100644
index 0000000000000..b0007d96b4cb2
--- /dev/null
+++ b/clang/test/CIR/CodeGen/compound-literal-empty.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple aar...
[truncated]

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.

Thanks for working on this!

Copy link
Contributor

@Andres-Salamanca Andres-Salamanca left a comment

Choose a reason for hiding this comment

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

Great work!

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: This is my preference, but I don’t think the # is needed here a plain %[[RET:.*]] should work fine. Curious what others think. If you don’t want to use the %, I also sometimes write it as [[RET:%.*]].

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't like the # matches because they prevent the pattern names from being re-used in other ways later in the test. I also strongly prefer %[[RET:.*]] over [[RET:%.*]] for several reasons: (1) it's easier to see at a glance that the leading % marks this as a value, (2) it's easy to miss the fact that the % is part of the pattern being matched because at a glance :%.* just looks like a bunch of non-alphanumeric symbols and my brain tends to mash them all together as some arbitrary regular expression, and (3) when you have checks that involve labels, the % isn't always part of what you're matching, so you can end up with a mix of some patterns that include the % and some that don't, which further hurts readability.

Copy link
Member

@AmrDeveloper AmrDeveloper left a comment

Choose a reason for hiding this comment

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

Thanks for working on this!

Copy link
Member

Choose a reason for hiding this comment

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

Is this file testing something?

Copy link
Author

Choose a reason for hiding this comment

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

This was a placeholder I added early on to validate the test infra, but it's no longer necessary. I will Remove now. Thank you.

Comment on lines +3 to +4
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-llvm -pic-is-pie -pic-level 1 %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-llvm -pic-is-pie -pic-level 1 %s -o %t-cir.ll
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-llvm -pic-is-pie -pic-level 1 %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG

This is the kind of change I was suggesting for tests that have LLVM IR checks. You would also need to add OGCG checks, which should be very close to the existing LLVM checks. The point is to find differences between the LLVM IR generated when we go through CIR compared to the LLVM IR generated when we are not using CIR.

As I mentioned before, it's probably best to remove tests that need this kind of update and make that a follow-up PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

In this case, the entire point of the test seems to be to verify that we are generating the expected linkage, preemption specifiers, and visibility when compiling with -pic-is-pie -pic-level 1. In order to be sure that CIR stays in sync with the non-CIR codegen path, we need checks here.

The correct OGCG check in this case will be

// OGCG: define dso_local noundef i32 @main()

This shows that in the CIR path, we missed the noundef return attribute. That's expected right now, but we want to have checks in place so we are alerted if the OGCG output changes.

Copy link
Contributor

Choose a reason for hiding this comment

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

This test is missing a newline at the end of the file. Depending on the configuration of your editor, you may be able to fix that just by opening and saving the file.

Comment on lines 9 to 11
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// CIR-NEXT: %2 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
// CIR-NEXT: %3 = cir.const #cir.int<2> : !s32i
// CIR-NEXT: cir.store %3, %2 : !s32i, !cir.ptr<!s32i>
// CIR-NEXT: %[[X:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
// CIR-NEXT: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i
// CIR-NEXT: cir.store{{.*}} %[[TWO]], %[[X]]

To make tests less brittle, we generally replace value identifiers like %2 with a pattern-match variable as shown above. Also, when I ran this test locally, it failed for me because the cir.store line I was seeing looked like this:

cir.store align(4) %3, %2 : !s32i, !cir.ptr<!s32i>

Since this test isn't intended to verify the alignment or the types in this store, I suggest simplifying it as above. The {{.*}} after cir.store means that the test will pass with or without an explicit alignment specifier. I've also removed the type checks, as they are essentially just noise in this test, which is intended to verify correct handling of the if constexpr expression.

Please go through and update any tests that have literal value specifiers (e.g. %2) in this way. It's probably a good idea to make these changes in a separate PR.

Copy link
Author

Choose a reason for hiding this comment

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

I learned a lot of thing. Thank you. I’ve done exactly what the issue described just moved the tests. I just moved the passed tests. But I think I did not the enough thing. I will close the PR, thanks. #156747

Copy link
Contributor

Choose a reason for hiding this comment

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

@bursot Am I understanding you comment correctly to say that you have decided you do not have time to continue working on this to complete the suggested changes? If so, I completely understand. What you have done already is a valuable contribution. If you would like to just wrap this up and commit the tests that don't require any modifications, I can comment on which tests I would like to have removed from this PR, and we can just merge the remaining changes.

Either way, please leave the PR open. If you do not have time to continue working on it, someone else can pick it up starting from what you have done.

Copy link
Author

Choose a reason for hiding this comment

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

Thank you for your guidance! I’m still new to this, so I wanted to make sure I followed the issue correctly. I’ll leave the PR open as you suggested. I have time but I did not feel to enough myself for your suggestions. Probably I will ask to much help from you 😅

Copy link
Author

@ghost ghost Sep 10, 2025

Choose a reason for hiding this comment

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

I’d appreciate it if you could indicate which tests you would like to have removed from this PR. Thanks for your kindess.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm happy to help as long as you are willing and able to put in the effort to keep learning. I'll leave it up to you to decide how far and how fast you want to go with that. An incremental approach is probably best. Let's get this PR wrapped up with the tests that don't need changes, and then maybe you can pick just one test to update in the ways discussed here. If you take your time and work through a few tests, I think you'll find that you can quickly get the hang of it.

Of course, a big part of that will be learning to read LLVM IR and MLIR. but if you imagine yourself being involved with the LLVM project in the future, it will be worth the effort.

Copy link
Author

Choose a reason for hiding this comment

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

I really appreciate it. I’ll follow your suggestion and first wrap up the PR with the tests that don’t need changes. Then I can try updating one test at a time as discussed. I’m excited to learn LLVM IR and MLIR, and I’ll take it step by step. Could you please indicate which tests you would like to have removed from this PR? I’m looking forward to learning a lot from you.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've just commented on the files to remove. Unfortunately, I will be on vacation after today until September 19. @AmrDeveloper Can you help to see this PR through and merge it after the tests that require updates have been removed?

@bursot In case you haven't already seen it, here is a reference that documents how the FileCheck pattern matching works: https://llvm.org/docs/CommandGuide/FileCheck.html You'll need to use that information for the next steps.

Copy link
Member

Choose a reason for hiding this comment

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

Sure, happy to help

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs value identifier pattern matching.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs value identifier pattern matching.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs value identifier pattern matching.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs value identifier pattern matching.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs value identifier pattern matching.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs value identifier pattern matching.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs value identifier pattern matching.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs OGCG checks added.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs OGCG checks added.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this file. It needs OGCG checks added, and it's probably not adding anything to existing tests.

Comment on lines +10 to +15
Copy link
Contributor

Choose a reason for hiding this comment

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

This is, for example, what you would do when erasing #
For adding the LLVM and OGCG, here is an example:
https://godbolt.org/z/z5zPP85G5
As you can see there, we can compare the output of CIR → LLVM against the classic codegen.

Also, in your build, you can check the tests under:
llvm-project/build/tools/clang/test/CIR/CodeGen/Output
to see the output.

Suggested change
// CHECK: %[[#RET:]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["__retval"]
// CHECK: %[[#A:]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]
// CHECK: %[[#BEFORE_A:]] = cir.load{{.*}} %[[#A]]
// CHECK: %[[#AFTER_A:]] = cir.unary(inc, %[[#BEFORE_A]])
// CHECK: cir.store{{.*}} %[[#AFTER_A]], %[[#A]]
// CHECK: cir.store{{.*}} %[[#AFTER_A]], %[[#RET]]
// CIR: %[[RET:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["__retval"]
// CIR: %[[A:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["a", init]
// CIR: %[[BEFORE_A:.*]] = cir.load{{.*}} %[[A]]
// CIR: %[[AFTER_A:.*]] = cir.unary(inc, %[[BEFORE_A]])
// CIR: cir.store{{.*}} %[[AFTER_A]], %[[A]]
// CIR: cir.store{{.*}} %[[AFTER_A]], %[[RET]]
// LLVM: ...
// OGCG: ...

Comment on lines +1 to +2
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-llvm %s -o %t-cir.ll
// RUN: FileCheck -input-file=%t-cir.ll %s --check-prefix=LLVM
// RUN: %clang_cc1 -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

Same as : #157333 (comment)

Copy link
Member

Choose a reason for hiding this comment

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

Hello @Andres-Salamanca,

Please check this comment from @andykaylor #157333 (comment)

The idea is to handle this in an incremental way, so anything that requires OGCG will be removed from now, and later they can be modified one by one

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh sorry, I missed that

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR

Use your editor to change // CHECK// CIR.

Comment on lines +2 to +4
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: FileCheck --input-file=%t.cir %s
// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cpp.cir
// RUN: FileCheck --input-file=%t.cpp.cir --check-prefix=CHECK-CPP %s
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cpp.cir
// RUN: FileCheck --input-file=%t.cpp.cir --check-prefix=CIR-CPP %s

Copy link
Member

Choose a reason for hiding this comment

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

Can you please check this, you can do it by search & replace in your editor @bursot

Copy link
Member

@AmrDeveloper AmrDeveloper left a comment

Choose a reason for hiding this comment

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

Thanks for removing other files. Can you please check those nits

For comments related to updating pattern matching, for example, to be similar to other tests %[[NAME: REGEX]]. If you want to do it, I can guide you more; if not, we can delay it later

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// CHECK: [[ALLOC_X:%.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["x", init] {alignment = 1 : i64}
// CHECK: [[ALLOC_X:%.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["x", init]

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// CIR: cir.global "private" external dso_local @var : !s32i {alignment = 4 : i64}
// CIR: cir.global "private" external dso_local @var : !s32i

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// CHECK: [[FNPTR_ALLOC:%.*]] = cir.alloca !cir.ptr<!cir.func<(...)>>, !cir.ptr<!cir.ptr<!cir.func<(...)>>>, ["func"] {alignment = 8 : i64}
// CHECK: [[FNPTR_ALLOC:%.*]] = cir.alloca !cir.ptr<!cir.func<(...)>>, !cir.ptr<!cir.ptr<!cir.func<(...)>>>, ["func"]

Comment on lines +2 to +4
Copy link
Member

Choose a reason for hiding this comment

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

Can you please check this, you can do it by search & replace in your editor @bursot

Comment on lines +11 to +14
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// CIR: cir.global external @i = #cir.fp<0.000000e+00> : !cir.long_double<!cir.f128> {alignment = 16 : i64} loc({{.*}})
// CIR-LABEL: cir.func dso_local @t2(%arg0: !cir.long_double<!cir.f128> loc({{.*}})) -> !cir.long_double<!cir.f128>
// CIR-NEXT: %[[#I2:]] = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["i2", init] {alignment = 16 : i64}
// CIR-NEXT: %[[#RETVAL:]] = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["__retval"] {alignment = 16 : i64}
// CIR: cir.global external @i = #cir.fp<0.000000e+00> : !cir.long_double<!cir.f128>
// CIR-LABEL: cir.func dso_local @t2(%arg0: !cir.long_double<!cir.f128> loc({{.*}})) -> !cir.long_double<!cir.f128>
// CIR-NEXT: %[[#I2:]] = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["i2", init]
// CIR-NEXT: %[[#RETVAL:]] = cir.alloca !cir.long_double<!cir.f128>, !cir.ptr<!cir.long_double<!cir.f128>>, ["__retval"]

@ghost
Copy link
Author

ghost commented Sep 11, 2025

Thanks for removing other files. Can you please check those nits

For comments related to updating pattern matching, for example, to be similar to other tests %[[NAME: REGEX]]. If you want to do it, I can guide you more; if not, we can delay it later

Sure. I'd like to try updating the pattern matching now. Your guidance would be very helpful. I want to learn more!

@AmrDeveloper
Copy link
Member

AmrDeveloper commented Sep 11, 2025

Thanks for removing other files. Can you please check those nits
For comments related to updating pattern matching, for example, to be similar to other tests %[[NAME: REGEX]]. If you want to do it, I can guide you more; if not, we can delay it later

Sure. I'd like to try updating the pattern matching now. Your guidance would be very helpful. I want to learn more!

Thank you for updating the nits.

So, for updating the pattern matching, we want to make it similar to other tests.

1 - Varables for example %1, %a, lets capture them and keep % outside, for example

[[A:%.*]] should be converted to %[[A:.*]], and when you use it, it will be %[[A]].

2 - We don't use the prefix # in variable names, for example

// CHECK: %[[#C:]] = cir.const #cir.int<1> : !s32i

Should be converted to,

// CHECK: %[[C:.*]] = cir.const #cir.int<1> : !s32i

And also, when you capture a variable, let's use regex :.* unless you want to capture a specific pattern like a number or alphabet only

And when you check that this variable is used, it will be %[[C]], not `%[[#C]]

Let's do it step by step in the current tests, and if you are confused about any pattern, please share it and let's discuss it in the comments.

Copy link
Member

Choose a reason for hiding this comment

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

This is an example of a name that contains # and should be converted to

Suggested change
// CHECK: %[[#C:]] = cir.const #cir.int<1> : !s32i
// CHECK: %[[C:.*]] = cir.const #cir.int<1> : !s32i

And when it used

// CHECK: cir.store{{.*}} %[[C]], %{{.+}} : !s32i, !cir.ptr<!s32i>

Copy link
Author

Choose a reason for hiding this comment

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

Got it, thanks for the clarification.

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// CHECK: [[ALLOC_X:%.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["x", init]
// CHECK: %[[ALLOC_X:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["x", init]

@AmrDeveloper
Copy link
Member

I added suggestions for two different patterns with the correct code. Please check the same pattern, and feel free to put any pattern that it's confusing so we can discuss it

@ghost
Copy link
Author

ghost commented Sep 11, 2025

I added suggestions for two different patterns with the correct code. Please check the same pattern, and feel free to put any pattern that it's confusing so we can discuss it

Please could you look the last commits. Is those true.

@AmrDeveloper
Copy link
Member

I added suggestions for two different patterns with the correct code. Please check the same pattern, and feel free to put any pattern that it's confusing so we can discuss it

Please could you look the last commits. Is those true.

Yes, they are very good 💯

@AmrDeveloper
Copy link
Member

Locally, you can run the lit test to check only one file, for example

bin/llvm-lit -sv <file_path>

Or you can run a group of tests by target, for example

ninja check-clang-cir-codegen

@ghost
Copy link
Author

ghost commented Sep 11, 2025

Locally, you can run the lit test to check only one file, for example

bin/llvm-lit -sv <file_path>

Or you can run a group of tests by target, for example

ninja check-clang-cir-codegen

Thanks again. I’ve learned so much from you, and I’m sorry for bothering you. I checked again and I think all files are okay.

@AmrDeveloper
Copy link
Member

AmrDeveloper commented Sep 11, 2025

I think now all files are updated and ready, except

clang/test/CIR/CodeGen/inc-dec.cpp
clang/test/CIR/CodeGen/no-proto-fun-ptr.c
clang/test/CIR/CodeGen/null-arithmatic-expression.c
clang/test/CIR/CodeGen/types-IEEE-quad.c
clang/test/CIR/CodeGen/unary.c

They contain the two patterns [[#....]] and [[%....]]. If any file is not clear, feel free to mention it, and I will add suggestions

@ghost
Copy link
Author

ghost commented Sep 11, 2025

I think now all files are updated and ready, except

clang/test/CIR/CodeGen/inc-dec.cpp clang/test/CIR/CodeGen/no-proto-fun-ptr.c clang/test/CIR/CodeGen/null-arithmatic-expression.c clang/test/CIR/CodeGen/types-IEEE-quad.c clang/test/CIR/CodeGen/unary.c

They contain the two patterns [[#....]] and [[%....]]. If any file is not clear, feel free to mention it, and I will add suggestions

I also did them too before but They weren't clean so I was confused. I added the changes. I hope they are okay 😅

Copy link
Member

@AmrDeveloper AmrDeveloper left a comment

Choose a reason for hiding this comment

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

LGTM, Great work @bursot, just one nit and we are ready.

Once @Andres-Salamanca accept it and CI green I will merge it

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// CHECK: %[[ALLOC:.*]] = cir.alloca !cir.ptr<!cir.func<()>>, !cir.ptr<!cir.ptr<!cir.func<()>>>, ["fun", init] {alignment = 8 : i64}
// CHECK: %[[ALLOC:.*]] = cir.alloca !cir.ptr<!cir.func<()>>, !cir.ptr<!cir.ptr<!cir.func<()>>>, ["fun", init]

We just forgot this :D

Copy link
Contributor

@Andres-Salamanca Andres-Salamanca left a comment

Choose a reason for hiding this comment

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

Most of my review comments are about adding --check-prefix=CIR. This is important because it helps us distinguish the output of ClangIR from the classic codegen.

When you pass the flag -fclangir -emit-cir, it means the ClangIR pipeline is being used. By adding --check-prefix=CIR and using // CIR: in the checks, we make it explicit which pipeline the test is validating, avoiding confusion with the default // CHECK: comments.

In future PRs, this becomes even more important because we will compare the outputs of:

-fclangir -emit-llvm → generates LLVM IR using the ClangIR pipeline
-emit-llvm → generates LLVM IR using the classic LLVM pipeline

Having clear prefixes ensures we can properly differentiate and validate results across both pipelines.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// CHECK: cir.func dso_local @t0(%arg0: !s32i loc({{.*}})) -> !s32i
// CIR: cir.func dso_local @t0(%arg0: !s32i loc({{.*}})) -> !s32i

When you add --check-prefix=CIR to your FileCheck command, it means the tool will only look for check lines that use the CIR: prefix.

For example, if your test has a comment like:

// CIR: cir.func dso_local @t0(%arg0: !s32i loc({{.*}})) -> !s32i

FileCheck will expect to match against this line.

If your file doesn't contains CIR: ones, you’ll likely see an error such as:

error: no check strings found with prefix 'CIR:'

To fix this, you need to replace your existing CHECK: comments with CIR: (or whichever prefix you’re using).

Copy link
Author

Choose a reason for hiding this comment

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

Thank you for your review!

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file might still need an update.

Comment on lines +4 to +14
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// CHECK: _Z23unreachable_after_breaki
void unreachable_after_break(int a) {
switch(a) {
case 0:
break;
break;
int x = 1;
}
// cir.switch
// cir.case(equal, [#cir.int<0> : !s32i]) {
// cir.break
void unreachable_after_break(int a) {
switch(a) {
case 0:
break;
break;
int x = 1;
}
// CIR: _Z23unreachable_after_breaki
// CIR: cir.switch
// CIR: cir.case(equal, [#cir.int<0> : !s32i]) {
// CIR: cir.break

This file doesn’t contain the FileCheck directives for the corresponding IR. Please add them by using // CIR: in the comments, and don’t forget to include --check-prefix=CIR in the RUN command.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: FileCheck --input-file=%t.cir %s
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR

Use your editor to change // CHECK// CIR.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file might still need an update.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: FileCheck --input-file=%t.cir %s
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR

Use your editor to change // CHECK// CIR.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file might still need an update.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: FileCheck --input-file=%t.cir %s
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR

Use your editor to change // CHECK// CIR.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file might still need an update.

Comment on lines +1 to +2
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -Wno-unused-value -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR

Use your editor to change // CHECK// CIR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: FileCheck --input-file=%t.cir %s
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR

Use your editor to change // CHECK// CIR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: FileCheck --input-file=%t.cir %s
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR

Use your editor to change // CHECK// CIR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: FileCheck --input-file=%t.cir %s
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR

Use your editor to change // CHECK// CIR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s --check-prefix=CIR

Use your editor to change // CHECK// CIR.

@ghost ghost requested a review from Andres-Salamanca September 12, 2025 11:16
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// CHECK: cir.func {{.*@foo}}
// CIR: cir.func {{.*@foo}}

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// CHECK: cir.func dso_local @{{.+}}test
// CIR: cir.func dso_local @{{.+}}test

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file might still need an update.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file might still need an update.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file might still need an update.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this file might still need an update.

Copy link
Author

@ghost ghost Sep 12, 2025

Choose a reason for hiding this comment

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

@Andres-Salamanca Is these need to change CHECK-CIR. Some of them is written in LLVM IR because, Should I convert?.
clang/test/CIR/Lowering/nested-switch.cpp
clang/test/CIR/Lowering/switch-while.c
clang/test/CIR/hello.c
clang/test/CIR/CodeGen/std-array.cpp
clang/test/CIR/CodeGen/spelling-locations.cpp
clang/test/CIR/CodeGen/literals.c
clang/test/CIR/CodeGen/literals.cpp
clang/test/CIR/CodeGen/c89-implicit-int.c

Copy link
Author

Choose a reason for hiding this comment

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

@AmrDeveloper
Clang.CIR/CodeGen/std-array.cpp
Clang.CIR/CodeGen/switch-unreachable-after-break.cpp
Clang.CIR/CodeGen/types.c
Clang.CIR/CodeGen/std-array.cpp
Clang.CIR/CodeGen/switch-unreachable-after-break.cpp
Clang.CIR/CodeGen/types.c
these are not passed.

Copy link
Member

Choose a reason for hiding this comment

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

Can you rebase with branch with main and run ninja check-clang-cir locally

@ghost ghost requested a review from Andres-Salamanca September 12, 2025 13:55
Copy link
Contributor

@Andres-Salamanca Andres-Salamanca left a comment

Choose a reason for hiding this comment

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

LGTM. in the case of the Lowering/ folder I didn’t ask you to change those since they go directly to LLVM IR, but if you want you can use --check-prefix=LLVM for that folder.
And for example in spelling-locations.cpp, I don’t think we need to compare those to LLVM IR. @AmrDeveloper what do you think?

@AmrDeveloper
Copy link
Member

LGTM. in the case of the Lowering/ folder I didn’t ask you to change those since they go directly to LLVM IR, but if you want you can use --check-prefix=LLVM for that folder. And for example in spelling-locations.cpp, I don’t think we need to compare those to LLVM IR. @AmrDeveloper what do you think?

I think for lowering/ and other tests that will not require other changes we can keep them now, if later we need to update them to test IR then we can modify them

@ghost ghost force-pushed the cir-upstream-test-porting branch from 536ac72 to f23886d Compare September 12, 2025 18:00
@ghost ghost closed this by deleting the head repository Sep 12, 2025
This pull request was closed.
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