// 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 -check-prefix=CIR // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll // RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM,LLVMCIR // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM,OGCG template struct IsChar { constexpr operator bool() const { return false; } }; template<> struct IsChar { constexpr operator bool() const { return true; } }; template concept SameAsChar = (bool)IsInt(); // LLVM-DAG: [[STRUCT_A:%.*]] = type { i8, double } // CIR-DAG: ![[STRUCT_A:.*]] = !cir.struct<"A" {!s8i, !cir.double}> struct A { char i; double j; template operator T() const { return i; }; }; // LLVM-DAG: [[STRUCT_B:%.*]] = type { [[STRUCT_A]], i32 } // CIR-DAG: ![[STRUCT_B:.*]] = !cir.struct<"B" {![[STRUCT_A]], !s32i}> struct B { A a; int b; }; // LLVM-DAG: [[STRUCT_C:%.*]] = type <{ [[STRUCT_B]], [[STRUCT_A]], i32, [4 x i8] }> // CIR-DAG: ![[STRUCT_C:.*]] = !cir.struct<"C" packed padded {![[STRUCT_B]], ![[STRUCT_A]], !s32i, !cir.array}> struct C : public B, public A { int c; }; // LLVM-DAG: [[STRUCT_D:%.*]] = type { [[STRUCT_A]], [[STRUCT_A]], i8, [[STRUCT_A]] } // CIR-DAG: ![[STRUCT_D:.*]] = !cir.struct<"D" {![[STRUCT_A]], ![[STRUCT_A]], !u8i, ![[STRUCT_A]]}> struct D { A a; A b = A{2, 2.0}; unsigned : 2; A c; }; // LLVM-DAG: [[STRUCT_E:%.*]] = type { i32, ptr } // CIR-DAG: ![[STRUCT_E:.*]] = !cir.struct<"E" {!s32i, !cir.ptr}> struct E { int a; const char* fn = __builtin_FUNCTION(); ~E() {}; }; // CIR-DAG: ![[STRUCT_F:.*]] = !cir.struct<"F" padded {!u8i}> struct F { F (int i = 1); F (const F &f) = delete; F (F &&f) = default; }; // LLVM-DAG: [[STRUCT_G:%.*]] = type <{ i32, [4 x i8] }> // CIR-DAG: ![[STRUCT_G:.*]] = !cir.struct<"G" packed padded {!s32i, !cir.array}> struct G { int a; F f; }; // LLVM-DAG: [[UNION_U:%.*]] = type { [[STRUCT_A]] } // LLVM-DAG: [[STR:@.*]] = private {{.*}}constant [6 x i8] {{.*}}foo18{{.*}}, align 1 // CIR-DAG: ![[UNION_U:.*]] = !cir.union<"U" {!u8i, ![[STRUCT_A]], !s8i}> union U { unsigned : 1; A a; char b; }; namespace gh61145 { // LLVM-DAG: [[STRUCT_VEC:%.*Vec.*]] = type { i8 } // CIR-DAG: ![[STRUCT_VEC:.*]] = !cir.struct<"gh61145::Vec" padded {!u8i}> struct Vec { Vec(); Vec(Vec&&); ~Vec(); }; // LLVM-DAG: [[STRUCT_S1:%.*]] = type { i8 } // CIR-DAG: ![[STRUCT_S1:.*]] = !cir.struct<"gh61145::S1" padded {!u8i}> struct S1 { Vec v; }; // LLVM-DAG: [[STRUCT_S2:%.*]] = type { i8, i8 } // CIR-DAG: ![[STRUCT_S2:.*]] = !cir.struct<"gh61145::S2" padded {!u8i, !s8i}> struct S2 { Vec v; char c; }; } namespace gh62266 { // LLVM-DAG: [[STRUCT_H:%.*H.*]] = type { i32, i32 } // CIR-DAG: ![[STRUCT_H:.*]] = !cir.struct<"gh62266::H<2>" {!s32i, !s32i}> template struct H { int i; int j = J; }; } namespace gh61567 { // LLVM-DAG: [[STRUCT_I:%.*I.*]] = type { i32, ptr } // CIR-DAG: ![[STRUCT_I:.*]] = !cir.struct<"gh61567::I" {!s32i, !cir.ptr}> struct I { int a; int&& r = 2; }; } // LLVM-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.000000e+00 }, align 8 // CIR-DAG: cir.global "private" constant internal dso_local @_ZL2a1 = #cir.const_record<{#cir.int<3> : !s8i, #cir.fp<2.000000e+00> : !cir.double}> : ![[STRUCT_A]] {alignment = 8 : i64} constexpr A a1(3.1, 2.0); // LLVM-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.000000e+00 }, align 8 // CIR-DAG: cir.global "private" constant internal dso_local @_ZL2a2 = #cir.const_record<{#cir.int<99> : !s8i, #cir.fp<0.000000e+00> : !cir.double}> : ![[STRUCT_A]] {alignment = 8 : i64} constexpr auto a2 = static_cast('c'); // LLVM-DAG: [[B1:@.*b1.*]] = internal constant [[STRUCT_B]] { [[STRUCT_A]] { i8 99, double 0.000000e+00 }, i32 0 }, align 8 // CIR-DAG: cir.global "private" constant internal dso_local @_ZL2b1 = #cir.const_record<{#cir.const_record<{#cir.int<99> : !s8i, #cir.fp<0.000000e+00> : !cir.double}> : ![[STRUCT_A]], #cir.int<0> : !s32i}> : ![[STRUCT_B]] {alignment = 8 : i64} constexpr B b1(A('c')); // LLVM-DAG: [[C1:@.*c1.*]] = internal constant { [[STRUCT_A]], i32, [4 x i8], i8, double, i32 } { [[STRUCT_A]] { i8 99, double 0.000000e+00 }, i32 0, [4 x i8] {{.*}}, i8 3, double 2.000000e+00, i32 0 }, align // CIR-DAG: cir.global "private" constant internal dso_local @_ZL2c1 = #cir.const_record<{#cir.const_record<{#cir.int<99> : !s8i, #cir.fp<0.000000e+00> : !cir.double}> : ![[STRUCT_A]], #cir.int<0> : !s32i, #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array, #cir.int<3> : !s8i, #cir.fp<2.000000e+00> : !cir.double, #cir.int<0> : !s32i}> constexpr C c1(b1, a1); // LLVM-DAG: [[U1:@.*]] = internal constant {{.*}} { [[STRUCT_A]] { i8 1, double 1.000000e+00 } }, align 8 // CIR-DAG: cir.global "private" constant internal dso_local @_ZL2u1 = #cir.const_record<{#cir.const_record<{#cir.int<1> : !s8i, #cir.fp<1.000000e+00> : !cir.double}> : ![[STRUCT_A]]}> : !{{.*}}{alignment = 8 : i64} constexpr U u1(A(1, 1)); // LLVM-DAG: [[D1:@.*d1.*]] = internal constant { [[STRUCT_A]], [[STRUCT_A]], [8 x i8], [[STRUCT_A]] } { [[STRUCT_A]] { i8 2, double 2.000000e+00 }, [[STRUCT_A]] { i8 2, double 2.000000e+00 }, [8 x i8] {{.*}}, [[STRUCT_A]] zeroinitializer }, align 8 // CIR-DAG: cir.global "private" constant internal dso_local @_ZL2d1 = #cir.const_record<{#cir.const_record<{#cir.int<2> : !s8i, #cir.fp<2.000000e+00> : !cir.double}> : ![[STRUCT_A]], #cir.const_record<{#cir.int<2> : !s8i, #cir.fp<2.000000e+00> : !cir.double}> : ![[STRUCT_A]], #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array, #cir.zero : ![[STRUCT_A]]}> constexpr D d1(A(2, 2)); // LLVM-DAG: [[ARR1:@.*arr1.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 0], align 4 // CIR-DAG: cir.global "private" constant internal dso_local @_ZL4arr1 = #cir.const_array<[#cir.int<1> : !s32i, #cir.int<2> : !s32i, #cir.int<0> : !s32i]> : !cir.array {alignment = 4 : i64} constexpr int arr1[3](1, 2); // LLVM-DAG: [[ARR4:@.*arr4.*]] = internal constant [1 x i32] [i32 1], align 4 // CIR-DAG: cir.global "private" constant internal dso_local @_ZL4arr4 = #cir.const_array<[#cir.int<1> : !s32i]> : !cir.array {alignment = 4 : i64} constexpr int arr4[](1); // LLVM-DAG: [[ARR5:@.*arr5.*]] = internal constant [2 x i32] [i32 2, i32 0], align 4 // CIR-DAG: cir.global "private" constant internal dso_local @_ZL4arr5 = #cir.const_array<[#cir.int<2> : !s32i, #cir.int<0> : !s32i]> : !cir.array {alignment = 4 : i64} constexpr int arr5[2](2); // LLVM: define dso_local {{.*}} @{{.*foo1.*}} // LLVM: [[RETVAL:%.*]] = alloca [[STRUCT_A]] // LLVM-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[RETVAL]], ptr {{.*}}[[A1]], i64 16, i1 false) // LLVM-NEXT: [[TMP_0:%.*]] = load {{.*}}, ptr [[RETVAL]], align 8 // LLVM-NEXT: ret {{.*}}[[TMP_0]] // CIR-LABEL: cir.func {{.*}}@_Z4foo1v() // CIR: %[[A_ALLOCA:.*]] = cir.alloca ![[STRUCT_A]], !cir.ptr, ["__retval"] {alignment = 8 : i64} // CIR: %[[GET_A1:.*]] = cir.get_global @_ZL2a1 : !cir.ptr // CIR: cir.copy %[[GET_A1]] to %[[A_ALLOCA]] : !cir.ptr A foo1() { return a1; } // LLVM: define dso_local {{.*}}@{{.*foo2.*}} // LLVM: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}, ptr {{.*}}[[B1]], i64 24, i1 false) // CIR: cir.func {{.*}}@_Z4foo2v() // CIR: %[[B_ALLOCA:.*]] = cir.alloca ![[STRUCT_B]], !cir.ptr, ["__retval"] {alignment = 8 : i64} // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZL2b1 : !cir.ptr // CIR: cir.copy %[[GET_GLOB]] to %[[B_ALLOCA]] : !cir.ptr B foo2() { return b1; } // LLVM: define dso_local {{.*}}@{{.*foo3.*}} // LLVM: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}, ptr {{.*}}[[C1]], i64 48, i1 false) // CIR: cir.func {{.*}}@_Z4foo3v() // CIR: %[[C_ALLOCA:.*]] = cir.alloca ![[STRUCT_C]], !cir.ptr, ["__retval"] {alignment = 8 : i64} // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZL2c1 // CIR: %[[GLOB_CAST:.*]] = cir.cast bitcast %[[GET_GLOB]] : !cir.ptr -> !cir.ptr // CIR: cir.copy %[[GLOB_CAST]] to %[[C_ALLOCA]] : !cir.ptr C foo3() { return c1; } // LLVM: define dso_local void @{{.*foo4.*}} // LLVM-DAG: [[C2:%.*]] = alloca [[STRUCT_C]] // LLVM-DAG: [[REF_TMP:%.*]] = alloca [[STRUCT_B]] // LLVM-DAG: [[REF_TMP_1:%.*]] = alloca [[STRUCT_A]] // LLVM: [[A:%.*]] = getelementptr {{.*}}[[STRUCT_B]], ptr [[REF_TMP]], i32 0, i32 0 // LLVM-NEXT: [[I:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[A]], i32 0, i32 0 // LLVM-NEXT: store i8 1, ptr [[I]], align 8 // LLVM-NEXT: [[J:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[A]], i32 0, i32 1 // LLVM-NEXT: store double 1.000000e+00, ptr [[J]], align 8 // LLVM-NEXT: [[B:%.*]] = getelementptr {{.*}}[[STRUCT_B]], ptr [[REF_TMP]], i32 0, i32 1 // LLVM-NEXT: store i32 1, ptr [[B]], align 8 // LLVM-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[C2]], ptr {{.*}}[[REF_TMP]], i64 24, i1 false) // LLVM-NEXT: [[TMP_0:%.*]] = getelementptr {{.*}}i8, ptr [[C2]], i{{.*}} 24 // LLVM-NEXT: [[I2:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[REF_TMP_1]], i32 0, i32 0 // LLVM-NEXT: store i8 97, ptr [[I2]], align 8 // LLVM-NEXT: [[J3:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[REF_TMP_1]], i32 0, i32 1 // LLVM-NEXT: store double 0.000000e+00, ptr [[J3]], align 8 // LLVM-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[TMP_0]], ptr {{.*}}[[REF_TMP_1]], i64 16, i1 false) // LLVM-NEXT: [[C:%.*]] = getelementptr {{.*}}[[STRUCT_C]], ptr [[C2]], i32 0, i32 2 // LLVM-NEXT: store i32 2, ptr [[C]] // LLVM: ret void // CIR-LABEL: cir.func {{.*}}@_Z4foo4v() // CIR: %[[C2_ALLOCA:.*]] = cir.alloca ![[STRUCT_C]], !cir.ptr, ["c2", init] // CIR: %[[B_TMP:.*]] = cir.alloca ![[STRUCT_B]], !cir.ptr, ["ref.tmp0"] // CIR: %[[A_TMP:.*]] = cir.alloca ![[STRUCT_A]], !cir.ptr, ["ref.tmp1"] // CIR: %[[C_BASE:.*]] = cir.base_class_addr %[[C2_ALLOCA]] : !cir.ptr nonnull [0] -> !cir.ptr // CIR: %[[GET_A:.*]] = cir.get_member %[[B_TMP]][0] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: %[[GET_I:.*]] = cir.get_member %[[GET_A]][0] {name = "i"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s8i // CIR: cir.store{{.*}} %[[ONE:.*]], %[[GET_I]] : !s8i, !cir.ptr // CIR: %[[GET_J:.*]] = cir.get_member %[[GET_A]][1] {name = "j"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: %[[ONE_F:.*]] = cir.cast int_to_float %[[ONE]] : !s32i -> !cir.double // CIR: cir.store{{.*}} %[[ONE_F]], %[[GET_J]] : !cir.double, !cir.ptr // CIR: %[[GET_B:.*]] = cir.get_member %[[B_TMP]][1] {name = "b"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: cir.store{{.*}} %[[ONE]], %[[GET_B]] : !s32i, !cir.ptr // CIR: cir.copy %[[B_TMP]] to %[[C_BASE]] : !cir.ptr // CIR: %[[C_BASE_A:.*]] = cir.base_class_addr %[[C2_ALLOCA]] : !cir.ptr nonnull [24] -> !cir.ptr // CIR: %[[GET_I:.*]] = cir.get_member %[[A_TMP]][0] {name = "i"} : !cir.ptr -> !cir.ptr // CIR: %[[NINETYSEVEN:.*]] = cir.const #cir.int<97> : !s8i // CIR: cir.store{{.*}} %[[NINETYSEVEN]], %[[GET_I]] : !s8i, !cir.ptr // CIR: %[[GET_J:.*]] = cir.get_member %[[A_TMP]][1] {name = "j"} : !cir.ptr -> !cir.ptr // CIR: %[[ZERO_F:.*]] = cir.const #cir.fp<0 // CIR: cir.store{{.*}} %[[ZERO_F]], %[[GET_J]] : !cir.double, !cir.ptr // CIR: cir.copy %[[A_TMP]] to %[[C_BASE_A]] : !cir.ptr // CIR: %[[GET_C:.*]] = cir.get_member %[[C2_ALLOCA]][2] {name = "c"} : !cir.ptr -> !cir.ptr // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i // CIR: cir.store{{.*}} %[[TWO]], %[[GET_C]] : !s32i, !cir.ptr void foo4() { C c2(B(A(1, 1), 1), A('a'), 2); } // LLVM: define dso_local {{.*}}@{{.*foo5.*}} // LLVM: [[RETVAL:%.*]] = alloca [[UNION_U]] // LLVM-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[RETVAL]], ptr {{.*}}[[U1]], i64 16, i1 false) // CIR-LABEL: cir.func no_inline dso_local @_Z4foo5v() // CIR: %[[RET:.*]] = cir.alloca ![[UNION_U]], !cir.ptr, ["__retval"] {alignment = 8 : i64} // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZL2u1 : !cir.ptr // CIR: %[[GLOB_TO_U:.*]] = cir.cast bitcast %[[GET_GLOB]] : !cir.ptr -> !cir.ptr // CIR: cir.copy %[[GLOB_TO_U]] to %[[RET]] : !cir.ptr U foo5() { return u1; } // LLVM: define dso_local {{.*}}@{{.*foo6.*}} // LLVM-DAG: [[RETVAL:%.*]] = alloca [[UNION_U]] // LLVM-DAG: [[A:%.*]] = alloca [[STRUCT_A]] // LLVM: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[RETVAL]], ptr {{.*}}[[A]], i64 16, i1 false) // CIR-LABEL: cir.func no_inline dso_local @_Z4foo61A( // CIR: %[[A_ALLOCA:.*]] = cir.alloca ![[STRUCT_A]], !cir.ptr, ["a", init] {alignment = 8 : i64} // CIR: %[[RET_ALLOCA:.*]] = cir.alloca ![[UNION_U]], !cir.ptr, ["__retval"] {alignment = 8 : i64} // CIR: %[[GET_A:.*]] = cir.get_member %[[RET_ALLOCA:.*]][1] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: cir.copy %[[A_ALLOCA]] to %[[GET_A:.*]] : !cir.ptr U foo6(A a) { return U(a); } // LLVM: define dso_local void @{{.*foo7.*}} // LLVM: [[D:%.*]] = alloca [[STRUCT_D]] // LLVM-NEXT: [[A:%.*]] = getelementptr {{.*}}[[STRUCT_D]], ptr [[D]], i32 0, i32 0 // LLVM-NEXT: [[I:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[A]], i32 0, i32 0 // LLVM-NEXT: store i8 1, ptr [[I]], align 8 // LLVM-NEXT: [[J:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[A]], i32 0, i32 1 // LLVM-NEXT: store double 1.000000e+00, ptr [[J]], align 8 // LLVM-NEXT: [[B:%.*]] = getelementptr {{.*}}[[STRUCT_D]], ptr [[D]], i32 0, i32 1 // LLVM-NEXT: [[I1:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[B]], i32 0, i32 0 // LLVM-NEXT: store i8 11, ptr [[I1]], align 8 // LLVM-NEXT: [[J2:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[B]], i32 0, i32 1 // LLVM-NEXT: store double 1.100000e+01, ptr [[J2]], align 8 // LLVM-NEXT: [[C:%.*]] = getelementptr {{.*}}[[STRUCT_D]], ptr [[D]], i32 0, i32 3 // LLVM-NEXT: [[I3:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[C]], i32 0, i32 0 // LLVM-NEXT: store i8 111, ptr [[I3]], align 8 // LLVM-NEXT: [[J4:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[C]], i32 0, i32 1 // LLVM-NEXT: store double 1.110000e+02, ptr [[J4]], align 8 // LLVM-NEXT: ret void // CIR-LABEL; cir.func no_inline dso_local @_Z4foo7v() // CIR: %[[D_ALLOCA:.*]] = cir.alloca ![[STRUCT_D]], !cir.ptr, ["d", init] {alignment = 8 : i64} // CIR: %[[GET_A:.*]] = cir.get_member %[[D_ALLOCA]][0] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: %[[GET_I:.*]] = cir.get_member %[[GET_A]][0] {name = "i"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s8i // CIR: cir.store align(8) %[[ONE]], %[[GET_I]] : !s8i, !cir.ptr // CIR: %[[GET_J:.*]] = cir.get_member %[[GET_A]][1] {name = "j"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: %[[ONE_F:.*]] = cir.cast int_to_float %[[ONE]] : !s32i -> !cir.double // CIR: cir.store align(8) %[[ONE_F]], %[[GET_J]] : !cir.double, !cir.ptr // CIR: %[[GET_B:.*]] = cir.get_member %[[D_ALLOCA]][1] {name = "b"} : !cir.ptr -> !cir.ptr // CIR: %[[GET_I:.*]] = cir.get_member %[[GET_B]][0] {name = "i"} : !cir.ptr -> !cir.ptr // CIR: %[[ELEVEN:.*]] = cir.const #cir.int<11> : !s8i // CIR: cir.store align(8) %[[ELEVEN]], %[[GET_I]] : !s8i, !cir.ptr // CIR: %[[GET_J:.*]] = cir.get_member %[[GET_B]][1] {name = "j"} : !cir.ptr -> !cir.ptr // CIR: %[[ELEVEN:.*]] = cir.const #cir.int<11> : !s32i // CIR: %[[ELEVEN_F:.*]] = cir.cast int_to_float %[[ELEVEN]] : !s32i -> !cir.double // CIR: cir.store align(8) %[[ELEVEN_F]], %[[GET_J]] : !cir.double, !cir.ptr // CIR: %[[GET_C:.*]] = cir.get_member %[[D_ALLOCA]][3] {name = "c"} : !cir.ptr -> !cir.ptr // CIR: %[[GET_I:.*]] = cir.get_member %[[GET_C]][0] {name = "i"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE_ELEVEN:.*]] = cir.const #cir.int<111> : !s8i // CIR: cir.store align(8) %[[ONE_ELEVEN]], %[[GET_I]] : !s8i, !cir.ptr // CIR: %[[GET_J:.*]] = cir.get_member %[[GET_C]][1] {name = "j"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE_ELEVEN:.*]] = cir.const #cir.int<111> : !s32i // CIR: %[[ONE_ELEVEN_F:.*]] = cir.cast int_to_float %[[ONE_ELEVEN]] : !s32i -> !cir.double // CIR: cir.store align(8) %[[ONE_ELEVEN_F]], %[[GET_J]] : !cir.double, !cir.ptr void foo7() { D d(A(1, 1), A(11, 11), A(111, 111)); } // LLVM: dso_local {{.*}}@{{.*foo8.*}}( // LLVM: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}, ptr {{.*}}[[D1]], i64 56, i1 false) // CIR-LABEL: cir.func no_inline dso_local @_Z4foo8v() // CIR: %[[RET_ALLOCA:.*]] = cir.alloca ![[STRUCT_D]], !cir.ptr, ["__retval"] {alignment = 8 : i64} // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZL2d1 : // CIR: %[[GLOB_CAST:.*]] = cir.cast bitcast %[[GET_GLOB]] : !cir.ptr -> !cir.ptr // CIR: cir.copy %[[GLOB_CAST]] to %[[RET_ALLOCA]] : !cir.ptr D foo8() { return d1; } // LLVM: define dso_local void @{{.*foo9.*}} // LLVM: [[D:%.*]] = alloca [[STRUCT_D]] // LLVM-NEXT: [[A:%.*]] = getelementptr {{.*}}[[STRUCT_D]], ptr [[D]], i32 0, i32 0 // LLVM-NEXT: [[I]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[A]], i32 0, i32 0 // LLVM-NEXT: store i8 1, ptr [[I]], align 8 // LLVM-NEXT: [[J:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[A]], i32 0, i32 1 // LLVM-NEXT: store double 1.000000e+00, ptr [[J]], align 8 // LLVM-NEXT: [[B:%.*]] = getelementptr {{.*}}[[STRUCT_D]], ptr [[D]], i32 0, i32 1 // LLVM-NEXT: [[I1:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[B]], i32 0, i32 0 // LLVM-NEXT: store i8 2, ptr [[I1]], align 8 // LLVM-NEXT: [[J2:%.*]] = getelementptr {{.*}}[[STRUCT_A]], ptr [[B]], i32 0, i32 1 // LLVM-NEXT: store double 2.000000e+00, ptr [[J2]], align 8 // LLVM-NEXT: [[C:%.*]] = getelementptr {{.*}}[[STRUCT_D]], ptr [[D]], i32 0, i32 3 // CIR-LABEL: cir.func no_inline dso_local @_Z4foo9v() // CIR: %[[D_ALLOCA:.*]] = cir.alloca ![[STRUCT_D]], !cir.ptr, ["d", init] {alignment = 8 : i64} // CIR: %[[GET_A:.*]] = cir.get_member %[[D_ALLOCA]][0] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: %[[GET_I:.*]] = cir.get_member %[[GET_A]][0] {name = "i"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s8i // CIR: cir.store align(8) %[[ONE]], %[[GET_I]] : !s8i, !cir.ptr // CIR: %[[GET_J:.*]] = cir.get_member %[[GET_A]][1] {name = "j"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: %[[ONE_F:.*]] = cir.cast int_to_float %[[ONE]] : !s32i -> !cir.double // CIR: cir.store align(8) %[[ONE_F]], %[[GET_J]] : !cir.double, !cir.ptr // CIR: %[[GET_B:.*]] = cir.get_member %[[D_ALLOCA]][1] {name = "b"} : !cir.ptr -> !cir.ptr // CIR: %[[GET_I:.*]] = cir.get_member %[[GET_B]][0] {name = "i"} : !cir.ptr -> !cir.ptr // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s8i // CIR: cir.store align(8) %[[TWO]], %[[GET_I]] : !s8i, !cir.ptr // CIR: %[[GET_J:.*]] = cir.get_member %[[GET_B]][1] {name = "j"} : !cir.ptr -> !cir.ptr // CIR: %[[FP_2:.*]] = cir.const #cir.fp<2 // CIR: cir.store align(8) %[[FP_2]], %[[GET_J]] : !cir.double, !cir.ptr // CIR: %[[GET_C:.*]] = cir.get_member %[[D_ALLOCA]][3] {name = "c"} : !cir.ptr -> !cir.ptr // CIR: %[[ZERO:.*]] = cir.const #cir.zero : ![[STRUCT_A]] // CIR: cir.store align(8) %[[ZERO]], %[[GET_C]] : ![[STRUCT_A]], !cir.ptr void foo9() { D d(A(1, 1)); } // LLVM: define dso_local noundef ptr @{{.*foo10.*}}() // FIXME: CIR lowering has an extra load here. // CIR-LABEL: cir.func no_inline dso_local @_Z5foo10v() // CIR: %[[RET_ALLOCA:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["__retval"] {alignment = 8 : i64} // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZL4arr1 : !cir.ptr> // CIR: %[[GLOB_DECAY:.*]] = cir.cast array_to_ptrdecay %[[GET_GLOB]] : !cir.ptr> -> !cir.ptr // CIR: cir.store %[[GLOB_DECAY]], %[[RET_ALLOCA]] : !cir.ptr, !cir.ptr> const int* foo10() { return arr1; } // LLVM: define dso_local void @{{.*foo11.*}} // LLVM: [[A_ADDR:%.*]] = alloca i32 // LLVM-NEXT: [[B_ADDR:%.*]] = alloca i32 // LLVM-NEXT: [[ARR_2:%.*]] = alloca [4 x i32] // LLVM: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4 // FIXME: CIR does an additional GEP here to decay the type. // LLVM: store i32 [[TMP_0]], ptr {{.*}}, align 4 // LLVM-NEXT: [[ARRINIT_ELEM:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 1 // LLVM-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4 // FXIME: CIR calculates this via offset from the above ARRINIT_ELEM, not the 0th element. // LLVM-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEM]], align 4 // LLVM: [[ARRINIT_START:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 {{.*}} // LLVM: [[ARRINIT_END:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 4 // LLVM-NEXT: br label [[ARRINIT_BODY:%.*]] // LLVM: [[ARRINIT_DONE:%.*]] = icmp {{.*}} ptr // LLVM-NEXT: br i1 [[ARRINIT_DONE]], label // LLVM: ret void // CIR-LABEL: cir.func no_inline dso_local @_Z5foo11ii // CIR: %[[A_ALLOCA:.*]] = cir.alloca !s32i, !cir.ptr, ["a", init] {alignment = 4 : i64} // CIR: %[[B_ALLOCA:.*]] = cir.alloca !s32i, !cir.ptr, ["b", init] {alignment = 4 : i64} // CIR: %[[ARR2_ALLOCA:.*]] = cir.alloca !cir.array, !cir.ptr>, ["arr2", init] {alignment = 16 : i64} // CIR: %[[ARR_ITR:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["arrayinit.temp", init] {alignment = 8 : i64} // CIR: %[[ARR2_DECAY:.*]] = cir.cast array_to_ptrdecay %[[ARR2_ALLOCA]] : !cir.ptr> -> !cir.ptr // CIR: %[[A_LOAD:.*]] = cir.load align(4) %[[A_ALLOCA]] : !cir.ptr, !s32i // CIR: cir.store align(4) %[[A_LOAD]], %[[ARR2_DECAY]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[ELT1:.*]] = cir.ptr_stride %[[ARR2_DECAY]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: %[[B_LOAD:.*]] = cir.load align(4) %[[B_ALLOCA]] : !cir.ptr, !s32i // CIR: cir.store align(4) %[[B_LOAD]], %[[ELT1]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[ELT2:.*]] = cir.ptr_stride %[[ELT1]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: cir.store align(8) %[[ELT2]], %[[ARR_ITR]] : !cir.ptr, !cir.ptr> // CIR: %[[FOUR:.*]] = cir.const #cir.int<4> : !s64i // CIR: %[[END_ITR:.*]] = cir.ptr_stride %[[ARR2_DECAY]], %[[FOUR]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: cir.do { // CIR: %[[ARR_ITR_LOAD:.*]] = cir.load align(8) %[[ARR_ITR]] : !cir.ptr>, !cir.ptr // CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i // CIR: cir.store align(4) %[[ZERO]], %[[ARR_ITR_LOAD]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[NEXT_ITR:.*]] = cir.ptr_stride %[[ARR_ITR_LOAD]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: cir.store align(8) %[[NEXT_ITR]], %[[ARR_ITR]] : !cir.ptr, !cir.ptr> // CIR: cir.yield // CIR: } while { // CIR: %[[ARR_ITR_LOAD:.*]] = cir.load align(8) %[[ARR_ITR]] : !cir.ptr>, !cir.ptr // CIR: %[[DONE:.*]] = cir.cmp ne %[[ARR_ITR_LOAD]], %[[END_ITR]] : !cir.ptr // CIR: cir.condition(%[[DONE]]) // CIR: } void foo11(int a, int b) { int arr2[4](a, b); } // LLVM: define dso_local void @{{.*foo12.*}} // LLVM: [[A_ADDR:%.*]] = alloca i32 // LLVM-NEXT: [[B_ADDR:%.*]] = alloca i32 // LLVM-NEXT: [[ARR_3:%.*]] = alloca [2 x i32] // LLVM-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4 // LLVM-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4 // LLVM: [[TMP_0:%.*]] = load i32, ptr [[A_ADDR]], align 4 // LLVM-NEXT: store i32 [[TMP_0]], ptr {{.*}}, align 4 // LLVM-NEXT: [[ARRINIT_ELEMENT:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 1 // LLVM-NEXT: [[TMP_1:%.*]] = load i32, ptr [[B_ADDR]], align 4 // LLVM-NEXT: store i32 [[TMP_1]], ptr [[ARRINIT_ELEMENT]], align 4 // LLVM-NEXT: ret void // CIR-LABEL: cir.func no_inline dso_local @_Z5foo12ii // CIR: %[[A_ALLOCA:.*]] = cir.alloca !s32i, !cir.ptr, ["a", init] {alignment = 4 : i64} // CIR: %[[B_ALLOCA:.*]] = cir.alloca !s32i, !cir.ptr, ["b", init] {alignment = 4 : i64} // CIR: %[[ARR3_ALLOCA:.*]] = cir.alloca !cir.array, !cir.ptr>, ["arr3", init] {alignment = 4 : i64} // CIR: %[[ARR_DECAY:.*]] = cir.cast array_to_ptrdecay %[[ARR3_ALLOCA]] : !cir.ptr> -> !cir.ptr // CIR: %[[A_LOAD:.*]] = cir.load align(4) %[[A_ALLOCA]] : !cir.ptr, !s32i // CIR: cir.store align(4) %[[A_LOAD]], %[[ARR_DECAY]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[ELT_1:.*]] = cir.ptr_stride %[[ARR_DECAY]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: %[[B_LOAD:.*]] = cir.load align(4) %[[B_ALLOCA]] : !cir.ptr, !s32i // CIR: cir.store align(4) %[[B_LOAD]], %[[ELT_1]] : !s32i, !cir.ptr void foo12(int a, int b) { int arr3[](a, b); } // LLVM: define {{.*}}@{{.*foo13.*}} // LLVM: [[RETVAL:%.*]] = alloca [[STRUCT_A]] // LLVM-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}[[RETVAL]], ptr {{.*}}[[A2]], i64 16, i1 false) // LLVM-NEXT: [[TMP_0:%.*]] = load {{.*}}, ptr [[RETVAL]], align 8 // LLVM-NEXT: ret {{.*}}[[TMP_0]] // CIR-LABEL: cir.func no_inline dso_local @_Z5foo13v() // CIR: %[[RET_ALLOCA:.*]] = cir.alloca ![[STRUCT_A]], !cir.ptr, ["__retval"] {alignment = 8 : i64} // CIR; %[[GET_GLOB:.*]] = cir.get_global @_ZL2a2 : !cir.ptr // CIR; cir.copy %[[GET_GLOB]] to %[[RET_ALLOCA]] : !cir.ptr A foo13() { return a2; } // LLVM: define dso_local noundef ptr @{{.*foo14.*}}() // LLVM: ret ptr // CIR-LABEL: cir.func no_inline dso_local @_Z5foo14v() // CIR: %[[RET_ALLOCA:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["__retval"] {alignment = 8 : i64} // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZL4arr4 : !cir.ptr> // CIR: %[[GLOB_DECAY]] = cir.cast array_to_ptrdecay %[[GET_GLOB]] : !cir.ptr> -> !cir.ptr // CIR: cir.store %[[GLOB_DECAY]], %[[RET_ALLOCA]] : !cir.ptr, !cir.ptr> const int* foo14() { return arr4; } // LLVM: define dso_local noundef ptr @{{.*foo15.*}}() // LLVM: ret ptr // CIR-LABEL: cir.func {{.*}}@_Z5foo15v() // CIR: %[[RET_ALLOCA:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["__retval"] {alignment = 8 : i64} // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZL4arr5 : !cir.ptr> // CIR: %[[GLOB_DECAY:.*]] = cir.cast array_to_ptrdecay %[[GET_GLOB]] : !cir.ptr> -> !cir.ptr // CIR: cir.store %[[GLOB_DECAY]], %[[RET_ALLOCA]] : !cir.ptr, !cir.ptr> const int* foo15() { return arr5; } // LLVM: define dso_local void @{{.*foo16.*}} // LLVM-DAG: [[ARR_6:%.*]] = alloca ptr // LLVM-DAG: [[REF_TMP:%.*]] = alloca [1 x i32] // LLVM: store i32 3, ptr {{.*}}, align 4 // LLVM-NEXT: store ptr [[REF_TMP]], ptr [[ARR_6]], align 8 // LLVM-NEXT: ret void // CIR-LABEL: cir.func no_inline dso_local @_Z5foo16v() // CIR: %[[TEMP_ALLOCA:.*]] = cir.alloca !cir.array, !cir.ptr>, ["ref.tmp0"] {alignment = 4 : i64} // CIR: %[[ARR6_ALLOCA:.*]] = cir.alloca !cir.ptr>, !cir.ptr>>, ["arr6", init, const] {alignment = 8 : i64} // CIR: %[[TEMP_DECAY:.*]] = cir.cast array_to_ptrdecay %[[TEMP_ALLOCA]] : !cir.ptr> -> !cir.ptr // CIR: %[[THREE:.*]] = cir.const #cir.int<3> : !s32i // CIR: cir.store align(4) %[[THREE]], %[[TEMP_DECAY]] : !s32i, !cir.ptr // CIR: %[[TEMP_CAST:.*]] = cir.cast bitcast %[[TEMP_ALLOCA]] : !cir.ptr> -> !cir.ptr> // CIR: cir.store align(8) %[[TEMP_CAST]], %[[ARR6_ALLOCA]] : !cir.ptr>, !cir.ptr>> void foo16() { int (&&arr6)[] = static_cast(3); } // LLVM: define dso_local void @{{.*foo17.*}} // LLVM-DAG: [[ARR_7:%.*]] = alloca ptr // LLVM-DAG: [[REF_TMP:%.*]] = alloca [2 x i32] // LLVM: store i32 4, ptr {{.*}}, align 4 // LLVM-NEXT: [[ARRINIT_START:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 1 // LLVM: [[ARRINIT_END:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 2 // LLVM: br label // LLVM: [[ARRINIT_DONE:%.*]] = icmp {{.*}} ptr // LLVM-NEXT: br i1 [[ARRINIT_DONE]], label // LLVM: store ptr [[REF_TMP]], ptr [[ARR_7]], align 8 // LLVM: ret void // CIR-LABEL: cir.func no_inline dso_local @_Z5foo17v() // CIR: %[[ARR_TEMP:.*]] = cir.alloca !cir.array, !cir.ptr>, ["ref.tmp0"] {alignment = 4 : i64} // CIR: %[[ARR7_ALLOCA:.*]] = cir.alloca !cir.ptr>, !cir.ptr>>, ["arr7", init, const] {alignment = 8 : i64} // CIR: %[[ITR:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["arrayinit.temp", init] {alignment = 8 : i64} // CIR: %[[TEMP_LOAD:.*]] = cir.cast array_to_ptrdecay %[[ARR_TEMP]] : !cir.ptr> -> !cir.ptr // CIR: %[[FOUR:.*]] = cir.const #cir.int<4> : !s32i // CIR: cir.store align(4) %[[FOUR]], %[[TEMP_LOAD]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[ELT1:.*]] = cir.ptr_stride %[[TEMP_LOAD]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: cir.store align(8) %[[ELT1]], %[[ITR]] : !cir.ptr, !cir.ptr> // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s64i // CIR: %[[END_ITR:.*]] = cir.ptr_stride %[[TEMP_LOAD]], %[[TWO]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: cir.do { // CIR: %[[ITR_LOAD:.*]] = cir.load align(8) %[[ITR]] : !cir.ptr>, !cir.ptr // CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i // CIR: cir.store align(4) %[[ZERO]], %[[ITR_LOAD]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[NEXT_ITR:.*]] = cir.ptr_stride %[[ITR_LOAD]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: cir.store align(8) %[[NEXT_ITR]], %[[ITR]] : !cir.ptr, !cir.ptr> // CIR: cir.yield // CIR: } while { // CIR: %[[ITR_LOAD:.*]] = cir.load align(8) %[[ITR]] : !cir.ptr>, !cir.ptr // CIR: %[[COND:.*]] = cir.cmp ne %[[ITR_LOAD]], %[[END_ITR]] : !cir.ptr // CIR: cir.condition(%[[COND]]) // CIR: } // CIR: cir.store align(8) %[[ARR_TEMP]], %[[ARR7_ALLOCA]] : !cir.ptr>, !cir.ptr>> void foo17() { int (&&arr7)[2] = static_cast(4); } // LLVM: define dso_local void @{{.*foo18.*}} // LLVM: [[E:%.*]] = alloca [[STRUCT_E]] // LLVM-NEXT: [[A:%.*]] = getelementptr {{.*}}[[STRUCT_E]], ptr [[E]], i32 0, i32 0 // LLVM-NEXT: store i32 1, ptr [[A]], align 8 // LLVM-NEXT: [[FN:%.*]] = getelementptr {{.*}}[[STRUCT_E]], ptr [[E]], i32 0, i32 1 // LLVM-NEXT: store ptr [[STR]], ptr [[FN]], align 8 // LLVM: ret void // CIR: cir.func {{.*}}@_Z5foo18v() // CIR: %[[E_ALLOCA:.*]] = cir.alloca ![[STRUCT_E]], !cir.ptr, ["e", init] // CIR: %[[GET_A:.*]] = cir.get_member %[[E_ALLOCA]][0] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: cir.store{{.*}} %[[ONE]], %[[GET_A]] : !s32i, !cir.ptr // CIR: %[[GET_FN:.*]] = cir.get_member %[[E_ALLOCA]][1] {name = "fn"} : !cir.ptr -> !cir.ptr> // CIR: %[[GET_STR:.*]] = cir.const #cir.global_view<@ // CIR: cir.store{{.*}} %[[GET_STR]], %[[GET_FN]] : !cir.ptr, !cir.ptr> void foo18() { E e(1); } // LLVM: define dso_local void @{{.*foo19.*}} // LLVM: [[G:%.*]] = alloca [[STRUCT_G]] // LLVM-NEXT: [[A:%.*]] = getelementptr {{.*}}[[STRUCT_G]], ptr [[G]], i32 0, i32 0 // LLVM-NEXT: store i32 2, ptr [[A]], align 4 // LLVM-NEXT: [[F:%.*]] = getelementptr {{.*}}i8, ptr [[G]], i64 4 // LLVM-NEXT: call void @{{.*F.*}}(ptr noundef nonnull align 1 dereferenceable(1) [[F]], i32 noundef 1) // LLVM: ret void // CIR: cir.func no_inline dso_local @_Z5foo19v() attributes {{{.*}}nothrow} { // CIR: %[[G_ALLOCA:.*]] = cir.alloca ![[STRUCT_G]], !cir.ptr, ["g", init] // CIR: %[[GET_A:.*]] = cir.get_member %[[G_ALLOCA]][0] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i // CIR: cir.store{{.*}} %[[TWO]], %[[GET_A]] : !s32i, !cir.ptr // CIR: %[[G_TO_CHAR:.*]] = cir.cast bitcast %[[G_ALLOCA]] : !cir.ptr -> !cir.ptr // CIR: %[[FOUR:.*]] = cir.const #cir.int<4> : !u64i // CIR: %[[F_OFFSET:.*]] = cir.ptr_stride %[[G_TO_CHAR]], %[[FOUR]] : (!cir.ptr, !u64i) -> !cir.ptr // CIR: %[[F:.*]] = cir.cast bitcast %[[F_OFFSET]] : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: cir.call @_ZN1FC1Ei(%[[F]], %[[ONE]]) void foo19() { G g(2); } namespace gh61145 { // a.k.a. void make1<0>() // LLVM: define {{.*}} void @_ZN7gh611455make1ILi0EEEvv // LLVM-DAG: [[V:%.*]] = alloca [[STRUCT_VEC]] // LLVM-DAG: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_S1]] // a.k.a. Vec::Vec() // LLVM-NEXT: call void @_ZN7gh611453VecC1Ev(ptr {{.*}}[[V]]) // a.k.a. Vec::Vec(Vec&&) // LLVM: call void @_ZN7gh611453VecC1EOS0_(ptr {{.*}}[[AGG_TMP_ENSURED]], ptr {{.*}}[[V]]) // a.k.a. S1::~S1() // LLVM: call void @_ZN7gh611452S1D1Ev(ptr {{.*}}[[AGG_TMP_ENSURED]]) // a.k.a.Vec::~Vec() // LLVM: call void @_ZN7gh611453VecD1Ev(ptr {{.*}}[[V]]) // LLVM: ret void // CIR-LABEL: cir.func {{.*}}@_ZN7gh611455make1ILi0EEEvv() // CIR: %[[V_ALLOCA:.*]] = cir.alloca ![[STRUCT_VEC]], !cir.ptr, ["v", init] {alignment = 1 : i64} // CIR: %[[TMP_ALLOCA:.*]] = cir.alloca ![[STRUCT_S1]], !cir.ptr, ["agg.tmp.ensured"] // CIR: cir.call @_ZN7gh611453VecC1Ev(%[[V_ALLOCA]]) // CIR: %[[S1_TO_VEC:.*]] = cir.cast bitcast %[[TMP_ALLOCA]] : !cir.ptr -> !cir.ptr // CIR: cir.call @_ZN7gh611453VecC1EOS0_(%[[S1_TO_VEC]], %[[V_ALLOCA]]) // CIR: cir.call @_ZN7gh611452S1D1Ev( // CIR: cir.call @_ZN7gh611453VecD1Ev( template void make1() { Vec v; S1((Vec&&) v); } // a.k.a. void make2<0>() // LLVM: define {{.*}} void @_ZN7gh611455make2ILi0EEEvv // LLVM-DAG: [[V:%.*]] = alloca [[STRUCT_VEC]] // LLVM-DAG: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_S2]] // a.k.a. Vec::Vec() // LLVM: call void @_ZN7gh611453VecC1Ev(ptr {{.*}}[[V]]) // a.k.a. Vec::Vec(Vec&&) // LLVM: call void @_ZN7gh611453VecC1EOS0_(ptr {{.*}}[[AGG_TMP_ENSURED]], ptr {{.*}}[[V]]) // LLVM-NEXT: [[C:%.*]] = getelementptr {{.*}}[[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 // LLVM-NEXT: store i8 0, ptr [[C]], align 1 // a.k.a. S2::~S2() // LLVM: call void @_ZN7gh611452S2D1Ev(ptr {{.*}}[[AGG_TMP_ENSURED]]) // a.k.a. Vec::~Vec() // LLVM: call void @_ZN7gh611453VecD1Ev(ptr {{.*}}[[V]]) // LLVM: ret void // CIR-LABEL: cir.func {{.*}}@_ZN7gh611455make2ILi0EEEvv() // CIR: %[[V_ALLOCA:.*]] = cir.alloca ![[STRUCT_VEC]], !cir.ptr, ["v", init] {alignment = 1 : i64} // CIR: %[[TMP_ALLOCA:.*]] = cir.alloca ![[STRUCT_S2]], !cir.ptr, ["agg.tmp.ensured"] // CIR: cir.call @_ZN7gh611453VecC1Ev(%[[V_ALLOCA]]) // CIR: %[[S2_TO_VEC:.*]] = cir.cast bitcast %[[TMP_ALLOCA]] : !cir.ptr -> !cir.ptr // CIR: cir.call @_ZN7gh611453VecC1EOS0_(%[[S2_TO_VEC]], %[[V_ALLOCA]]) // CIR: %[[GET_C:.*]] = cir.get_member %[[TMP_ALLOCA]][1] {name = "c"} : !cir.ptr -> !cir.ptr // CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s8i // CIR: cir.store{{.*}} %[[ZERO]], %[[GET_C]] : !s8i, !cir.ptr template void make2() { Vec v; S2((Vec&&) v, 0); } void foo() { make1<0>(); make2<0>(); } } namespace gh62266 { // LLVM: define {{.*}} void {{.*foo20.*}} // LLVM: [[H:%.*]] = alloca [[STRUCT_H]] // LLVM-NEXT: [[I:%.*]] = getelementptr {{.*}}[[STRUCT_H]], ptr [[H]], i32 0, i32 0 // LLVM-NEXT: store i32 1, ptr [[I]], align 4 // LLVM-NEXT: [[J:%.*]] = getelementptr {{.*}}[[STRUCT_H]], ptr [[H]], i32 0, i32 1 // LLVM-NEXT: store i32 2, ptr [[J]], align 4 // LLVM-NEXT: ret void // CIR-LABEL: cir.func {{.*}}@_ZN7gh622665foo20Ev() // CIR: %[[TMP_ALLOCA:.*]] = cir.alloca ![[STRUCT_H]], !cir.ptr, ["h", init] // CIR: %[[GET_I:.*]] = cir.get_member %[[TMP_ALLOCA]][0] {name = "i"} : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: cir.store{{.*}} %[[ONE]], %[[GET_I]] : !s32i, !cir.ptr // CIR: %[[GET_J:.*]] = cir.get_member %[[TMP_ALLOCA]][1] {name = "j"} : !cir.ptr -> !cir.ptr // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i // CIR: cir.store{{.*}} %[[TWO]], %[[GET_J]] : !s32i, !cir.ptr // CIR: cir.return void foo20() { H<2> h(1); } } namespace gh61567 { int foo20(); // LLVM: define {{.*}} void @{{.*foo21.*}} { // LLVM: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]] // LLVM-NEXT: [[REF_TMP:%.*]] = alloca i32 // LLVM: [[A:%.*]] = getelementptr {{.*}}[[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0 // LLVM-NEXT: store i32 0, ptr [[A]], align 8 // LLVM-NEXT: [[R:%.*]] = getelementptr {{.*}}[[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1 // LLVM-NEXT: store i32 1, ptr [[REF_TMP]], align 4 // LLVM-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8 // LLVM: ret void // CIR-LABEL: cir.func {{.*}}@_ZN7gh615675foo21Ev() // CIR: %[[TMP_ALLOCA:.*]] = cir.alloca ![[STRUCT_I]], !cir.ptr, ["agg.tmp.ensured"] // CIR: %[[INT_TMP:.*]] = cir.alloca !s32i, !cir.ptr, ["ref.tmp0"] // CIR: %[[GET_A:.*]] = cir.get_member %[[TMP_ALLOCA]][0] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i // CIR: cir.store{{.*}} %[[ZERO]], %[[GET_A]] : !s32i, !cir.ptr // CIR: %[[GET_R:.*]] = cir.get_member %[[TMP_ALLOCA]][1] {name = "r"} : !cir.ptr -> !cir.ptr> // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: cir.store{{.*}} %[[ONE]], %[[INT_TMP]] : !s32i, !cir.ptr // CIR: cir.store{{.*}} %[[INT_TMP]], %[[GET_R]] : !cir.ptr, !cir.ptr> void foo21() { I(0, 1); } // LLVM: define {{.*}} void @{{.*foo22.*}} { // LLVM: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]] // LLVM-NEXT: [[REF_TMP:%.*]] = alloca i32 // LLVM: [[A:%.*]] = getelementptr {{.*}}[[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0 // LLVM-NEXT: store i32 0, ptr [[A]], align 8 // LLVM-NEXT: [[R:%.*]] = getelementptr {{.*}}[[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1 // LLVM-NEXT: [[CALL:%.*]] = call noundef i32 @{{.*foo20.*}} // LLVM-NEXT: store i32 [[CALL]], ptr [[REF_TMP]], align 4 // LLVM-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8 // LLVM: ret void // CIR-LABEL: cir.func {{.*}}@_ZN7gh615675foo22Ev() // CIR: %[[TMP_ALLOCA:.*]] = cir.alloca ![[STRUCT_I]], !cir.ptr, ["agg.tmp.ensured"] // CIR: %[[INT_TMP:.*]] = cir.alloca !s32i, !cir.ptr, ["ref.tmp0"] // CIR: %[[GET_A:.*]] = cir.get_member %[[TMP_ALLOCA]][0] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i // CIR: cir.store{{.*}} %[[ZERO]], %[[GET_A]] : !s32i, !cir.ptr // CIR: %[[GET_R:.*]] = cir.get_member %[[TMP_ALLOCA]][1] {name = "r"} : !cir.ptr -> !cir.ptr> // CIR: %[[GET_CALL:.*]] = cir.call @_ZN7gh615675foo20Ev() : () -> (!s32i {llvm.noundef}) // CIR: cir.store{{.*}} %[[GET_CALL]], %[[INT_TMP]] : !s32i, !cir.ptr // CIR: cir.store{{.*}} %[[INT_TMP]], %[[GET_R]] : !cir.ptr, !cir.ptr> void foo22() { I(0, foo20()); } // LLVM: define {{.*}} void @{{.*foo23.*}} // LLVM: [[I_ADDR:%.*]] = alloca i32 // LLVM-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]] // LLVM: [[A:%.*]] = getelementptr {{.*}}[[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0 // LLVM-NEXT: store i32 0, ptr [[A]], align 8 // LLVM-NEXT: [[R:%.*]] = getelementptr {{.*}}[[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1 // LLVM-NEXT: store ptr [[I_ADDR]], ptr [[R]], align 8 // LLVM-NEXT: ret void // CIR-LABEL: cir.func no_inline dso_local @_ZN7gh615675foo23Ei(%arg0: !s32i {llvm.noundef} // CIR: %[[I_ALLOCA:.*]] = cir.alloca !s32i, !cir.ptr, ["i", init] // CIR: %[[TMP_ALLOCA:.*]] = cir.alloca ![[STRUCT_I]], !cir.ptr, ["agg.tmp.ensured"] // CIR: %[[GET_A:.*]] = cir.get_member %[[TMP_ALLOCA]][0] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i // CIR: cir.store{{.*}} %[[ZERO]], %[[GET_A]] : !s32i, !cir.ptr // CIR: %[[GET_R:.*]] = cir.get_member %[[TMP_ALLOCA]][1] {name = "r"} : !cir.ptr -> !cir.ptr> // CIR: cir.store{{.*}} %[[I_ALLOCA]], %[[GET_R]] : !cir.ptr, !cir.ptr> void foo23(int i) { I(0, static_cast(i)); } // LLVM: define {{.*}} void @{{.*foo24.*}} { // LLVM: [[AGG_TMP_ENSURED:%.*]] = alloca [[STRUCT_I]] // LLVM-NEXT: [[REF_TMP:%.*]] = alloca i32 // LLVM-NEXT: [[A:%.*]] = getelementptr {{.*}}[[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0 // LLVM-NEXT: store i32 0, ptr [[A]], align 8 // LLVM-NEXT: [[R:%.*]] = getelementptr {{.*}}[[STRUCT_I]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 1 // LLVM-NEXT: store i32 2, ptr [[REF_TMP]], align 4 // LLVM-NEXT: store ptr [[REF_TMP]], ptr [[R]], align 8 // LLVM-NEXT: ret void // CIR-LABEL: cir.func {{.*}}@_ZN7gh615675foo24Ev() // CIR: %[[TMP_ALLOCA:.*]] = cir.alloca ![[STRUCT_I]], !cir.ptr, ["agg.tmp.ensured"] // CIR: %[[INT_TMP:.*]] = cir.alloca !s32i, !cir.ptr, ["ref.tmp0"] // CIR: %[[GET_A:.*]] = cir.get_member %[[TMP_ALLOCA:.*]][0] {name = "a"} : !cir.ptr -> !cir.ptr // CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i // CIR: cir.store{{.*}} %[[ZERO]], %[[GET_A]] : !s32i, !cir.ptr // CIR: %[[GET_R:.*]] = cir.get_member %[[TMP_ALLOCA:.*]][1] {name = "r"} : !cir.ptr -> !cir.ptr> // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i // CIR: cir.store{{.*}} %[[TWO]], %[[INT_TMP]] : !s32i, !cir.ptr // CIR: cir.store{{.*}} %[[INT_TMP]], %[[GET_R]] : !cir.ptr, !cir.ptr> void foo24() { I(0); } } namespace gh68198 { // LLVM: define {{.*}} void @{{.*foo25.*}} { // LLVM: [[ARR_8:%.*]] = alloca ptr // LLVM-NEXT: [[CALL_PTR:%.*]] = call {{.*}}nonnull ptr @_Znam(i64 noundef 8) // LLVM-NEXT: store i32 1, ptr [[CALL_PTR]], align 4 // LLVM-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr {{.*}}i32, ptr [[CALL_PTR]], i64 1 // LLVM-NEXT: store i32 2, ptr [[ARRAY_EXP_NEXT]], align 4 // LLVM-NEXT: [[ARRAY_EXP_NEXT1:%.*]] = getelementptr {{.*}}i32, ptr [[ARRAY_EXP_NEXT]], i64 1 // LLVM-NEXT: store ptr [[CALL_PTR]], ptr [[ARR_8]], align 8 // LLVM-NEXT: ret void // CIR-LABEL: cir.{{.*}}@_ZN7gh681985foo25Ev() // CIR: %[[ARR_ALLOCA:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["arr8", init] {alignment = 8 : i64} // CIR: %[[SIZE:.*]] = cir.const #cir.int<8> : !u64i // CIR: %[[ALLOC:.*]] = cir.call @_Znam(%[[SIZE]]) {allocsize = array, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr {llvm.nonnull, llvm.noundef}) // CIR: %[[ALLOC_TO_ARR:.*]] = cir.cast bitcast %[[ALLOC]] : !cir.ptr -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: cir.store{{.*}} %[[ONE]], %[[ALLOC_TO_ARR]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: %[[ELT1:.*]] = cir.ptr_stride %[[ALLOC_TO_ARR]], %[[ONE]] : (!cir.ptr, !s32i) -> !cir.ptr // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i // CIR: cir.store{{.*}} %[[TWO]], %[[ELT1]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: %[[ELT2:.*]] = cir.ptr_stride %[[ELT1]], %[[ONE]] : (!cir.ptr, !s32i) -> !cir.ptr // CIR: cir.store{{.*}} %[[ALLOC_TO_ARR]], %[[ARR_ALLOCA]] : !cir.ptr, !cir.ptr> void foo25() { int* arr8 = new int[](1, 2); } // LLVM: define {{.*}} void @{{.*foo26.*}} { // LLVM: [[ARR_10:%.*]] = alloca ptr // LLVM-NEXT: [[CALL_PTR]] = call {{.*}}nonnull ptr @_Znam(i64 noundef 16) // LLVM: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 1 // LLVM-NEXT: store i32 2, ptr [[ARRAYINIT_ELEMENT]], align 4 // LLVM-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr {{.*}}[2 x i32], ptr {{.*}}, i64 1 // LLVM: store i32 3, ptr {{.*}}, align 4 // LLVM-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 1 // LLVM-NEXT: store i32 4, ptr [[ARRAYINIT_ELEMENT2]], align 4 // LLVM-NEXT: [[ARRAY_EXP_NEXT3:%.*]] = getelementptr {{.*}}[2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 1 // LLVM-NEXT: store ptr [[CALL_PTR]], ptr [[ARR_10]], align 8 // LLVM-NEXT: ret void // CIR-LABEL: cir.{{.*}}@_ZN7gh681985foo26Ev() // CIR: %[[ARR_ALLOCA:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["arr9", init] {alignment = 8 : i64} // CIR: %[[SIZE:.*]] = cir.const #cir.int<16> : !u64i // CIR: %[[ALLOC:.*]] = cir.call @_Znam(%[[SIZE]]) {allocsize = array, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr {llvm.nonnull, llvm.noundef}) // CIR: %[[ALLOC_TO_ARR:.*]] = cir.cast bitcast %[[ALLOC]] : !cir.ptr -> !cir.ptr> // CIR: %[[ELT0_0:.*]] = cir.cast array_to_ptrdecay %[[ALLOC_TO_ARR]] : !cir.ptr> -> !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: cir.store{{.*}} %[[ONE]], %[[ELT0_0]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[ELT0_1:.*]] = cir.ptr_stride %[[ELT0_0]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: %[[TWO:.*]] = cir.const #cir.int<2> : !s32i // CIR: cir.store{{.*}} %[[TWO]], %[[ELT0_1]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: %[[ELT1:.*]] = cir.ptr_stride %[[ALLOC_TO_ARR]], %[[ONE]] : (!cir.ptr>, !s32i) -> !cir.ptr> // CIR: %[[ELT1_0:.*]] = cir.cast array_to_ptrdecay %[[ELT1]] : !cir.ptr> -> !cir.ptr // CIR: %[[THREE:.*]] = cir.const #cir.int<3> : !s32i // CIR: cir.store{{.*}} %[[THREE]], %[[ELT1_0]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[ELT1_1:.*]] = cir.ptr_stride %[[ELT1_0]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: %[[FOUR:.*]] = cir.const #cir.int<4> : !s32i // CIR: cir.store{{.*}} %[[FOUR]], %[[ELT1_1]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: %[[ELT2:.*]] = cir.ptr_stride %[[ELT1]], %[[ONE]] : (!cir.ptr>, !s32i) -> !cir.ptr> // CIR: %[[ARR_TO_VOID:.*]] = cir.cast bitcast %[[ALLOC_TO_ARR]] : !cir.ptr> -> !cir.ptr // CIR: cir.store{{.*}} %[[ARR_TO_VOID]], %[[ARR_ALLOCA]] : !cir.ptr, !cir.ptr> void foo26() { void* arr9 = new int[][2]({1, 2}, {3, 4}); } // LLVM: define {{.*}} void @{{.*foo27.*}} { // LLVM: [[ARR_10:%.*]] = alloca ptr // LLVM-NEXT: [[CALL_PTR]] = call {{.*}}nonnull {{.*}}@_Znam(i64 noundef 32) // LLVM: store i32 5, ptr {{.*}}, align 4 // LLVM-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 1 // LLVM-NEXT: store i32 6, ptr [[ARRAYINIT_ELEMENT]], align 4 // LLVM-NEXT: [[ARRAY_EXP_NEXT:%.*]] = getelementptr {{.*}}[2 x i32], ptr {{.*}}, i64 1 // LLVM: store i32 7, ptr {{.*}}, align 4 // LLVM-NEXT: [[ARRAYINIT_ELEMENT2:%.*]] = getelementptr {{.*}}i32, ptr {{.*}}, i64 1 // LLVM-NEXT: store i32 8, ptr [[ARRAYINIT_ELEMENT2]], align 4 // LLVM-NEXT: [[ARRAY_EXP_NEXT3:%.*]] = getelementptr {{.*}}[2 x i32], ptr [[ARRAY_EXP_NEXT]], i64 1 // LLVM-NEXT: call void @llvm.memset.p0.i64(ptr {{.*}}[[ARRAY_EXP_NEXT3]], i8 0, i64 16, i1 false) // LLVM-NEXT: store ptr [[CALL_PTR]], ptr [[ARR_10]], align 8 // LLVM-NEXT: ret void // CIR-LABEL: cir.{{.*}}@_ZN7gh681985foo27Ev() // CIR: %[[ARR_ALLOCA:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["arr10", init] {alignment = 8 : i64} // CIR: %[[SIZE:.*]] = cir.const #cir.int<32> : !u64i // CIR: %[[ALLOC:.*]] = cir.call @_Znam(%[[SIZE]]) {allocsize = array, builtin} : (!u64i {llvm.noundef}) -> (!cir.ptr {llvm.nonnull, llvm.noundef}) // CIR: %[[ALLOC_TO_ARR:.*]] = cir.cast bitcast %[[ALLOC]] : !cir.ptr -> !cir.ptr> // CIR: %[[ELT0_0:.*]] = cir.cast array_to_ptrdecay %[[ALLOC_TO_ARR]] : !cir.ptr> -> !cir.ptr // CIR: %[[FIVE:.*]] = cir.const #cir.int<5> : !s32i // CIR: cir.store{{.*}} %[[FIVE]], %[[ELT0_0]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[ELT0_1:.*]] = cir.ptr_stride %[[ELT0_0]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: %[[SIX:.*]] = cir.const #cir.int<6> : !s32i // CIR: cir.store{{.*}} %[[SIX]], %[[ELT0_1]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: %[[ELT1:.*]] = cir.ptr_stride %[[ALLOC_TO_ARR]], %[[ONE]] : (!cir.ptr>, !s32i) -> !cir.ptr> // CIR: %[[ELT1_0:.*]] = cir.cast array_to_ptrdecay %[[ELT1]] : !cir.ptr> -> !cir.ptr // CIR: %[[SEVEN:.*]] = cir.const #cir.int<7> : !s32i // CIR: cir.store{{.*}} %[[SEVEN]], %[[ELT1_0]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s64i // CIR: %[[ELT1_1:.*]] = cir.ptr_stride %[[ELT1_0]], %[[ONE]] : (!cir.ptr, !s64i) -> !cir.ptr // CIR: %[[EIGHT:.*]] = cir.const #cir.int<8> : !s32i // CIR: cir.store{{.*}} %[[EIGHT]], %[[ELT1_1]] : !s32i, !cir.ptr // CIR: %[[ONE:.*]] = cir.const #cir.int<1> : !s32i // CIR: %[[ELT2:.*]] = cir.ptr_stride %[[ELT1]], %[[ONE]] : (!cir.ptr>, !s32i) -> !cir.ptr> // CIR: %[[INIT_SIZE:.*]] = cir.const #cir.int<16> : !u64i // CIR: %[[ALLOC_DIFF:.*]] = cir.sub %[[SIZE]], %[[INIT_SIZE]] : !u64i // CIR: %[[ELT2_DECAY:.*]] = cir.cast bitcast %[[ELT2]] : !cir.ptr> -> !cir.ptr // CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !u8i // CIR: cir.libc.memset %[[ALLOC_DIFF]] bytes at %[[ELT2_DECAY]] to %[[ZERO]] : !cir.ptr, !u8i, !u64i // CIR: %[[ARR_TO_VOID:.*]] = cir.cast bitcast %[[ALLOC_TO_ARR]] : !cir.ptr> -> !cir.ptr // CIR: cir.store{{.*}} %[[ARR_TO_VOID]], %[[ARR_ALLOCA]] : !cir.ptr, !cir.ptr> void foo27() { void* arr10 = new int[4][2]({5, 6}, {7, 8}); } } namespace base_cleanup { struct Base { ~Base() {} int b; }; struct Derived : Base { int d; }; void base_cleanup() { Derived x{{1}, 2}; } // CIR-LABEL: cir.func {{.*}}@_ZN12base_cleanup7DerivedD2Ev( // CIR: cir.call @_ZN12base_cleanup4BaseD2Ev( // CIR-LABEL: cir.func {{.*}}@_ZN12base_cleanup12base_cleanupEv() // CIR: cir.cleanup.scope { // CIR: cir.yield // CIR: } cleanup normal { // CIR: cir.call @_ZN12base_cleanup7DerivedD1Ev( // CIR: cir.yield // CIR: } // These are emitted in the reverse order between OGCG/LLVM, else they are identical. // OGCG-LABEL: define {{.*}}@_ZN12base_cleanup12base_cleanupEv() // OGCG-NOT: define // OGCG: call void @_ZN12base_cleanup7DerivedD1Ev( // OGCG: } // LLVM-LABEL: define {{.*}}@_ZN12base_cleanup7DerivedD2Ev( // LLVM: call void @_ZN12base_cleanup4BaseD2Ev( // LLVMCIR-LABEL: define {{.*}}@_ZN12base_cleanup12base_cleanupEv() // LLVMCIR-NOT: define // LLVMCIR: call void @_ZN12base_cleanup7DerivedD1Ev( // LLVMCIR: } }