diff options
Diffstat (limited to 'clang/test/CIR')
-rw-r--r-- | clang/test/CIR/CodeGen/cast.cpp | 33 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/complex.cpp | 46 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/constant-inits.cpp | 88 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/dtors.cpp | 37 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/global-init.cpp | 29 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/new.cpp | 53 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/throws.cpp | 44 | ||||
-rw-r--r-- | clang/test/CIR/CodeGenOpenACC/private-clause-array-recipes-int.cpp | 4 | ||||
-rw-r--r-- | clang/test/CIR/IR/dynamic-cast.cir | 59 | ||||
-rw-r--r-- | clang/test/CIR/IR/invalid-dyn-cast.cir | 43 |
10 files changed, 429 insertions, 7 deletions
diff --git a/clang/test/CIR/CodeGen/cast.cpp b/clang/test/CIR/CodeGen/cast.cpp index 7afa955..844d4df 100644 --- a/clang/test/CIR/CodeGen/cast.cpp +++ b/clang/test/CIR/CodeGen/cast.cpp @@ -131,3 +131,36 @@ void bitcast() { // LLVM: %[[D_VEC:.*]] = load <2 x double>, ptr {{.*}}, align 16 // LLVM: %[[I_VEC:.*]] = bitcast <2 x double> %[[D_VEC]] to <4 x i32> + +void f(long int start) { + void *p = (void*)start; +} +// CIR: %[[L:.*]] = cir.load {{.*}} : !cir.ptr<!s64i>, !s64i +// CIR: %[[MID:.*]] = cir.cast integral %[[L]] : !s64i -> !u64i +// CIR: cir.cast int_to_ptr %[[MID]] : !u64i -> !cir.ptr<!void> + +// LLVM-LABEL: define{{.*}} void @_Z1fl(i64 %0) +// LLVM: %[[ADDR:.*]] = alloca i64, i64 1, align 8 +// LLVM: %[[PADDR:.*]] = alloca ptr, i64 1, align 8 +// LLVM: store i64 %0, ptr %[[ADDR]], align 8 +// LLVM: %[[L:.*]] = load i64, ptr %[[ADDR]], align 8 +// LLVM: %[[PTR:.*]] = inttoptr i64 %[[L]] to ptr +// LLVM: store ptr %[[PTR]], ptr %[[PADDR]], align 8 +// LLVM: ret void + +struct A { int x; }; + +void int_cast(long ptr) { + ((A *)ptr)->x = 0; +} +// CIR: cir.cast int_to_ptr {{.*}} : !u64i -> !cir.ptr<!rec_A> +// LLVM: inttoptr {{.*}} to ptr + +void null_cast(long) { + *(int *)0 = 0; + ((A *)0)->x = 0; +} +// CIR: %[[NULLPTR:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!s32i> +// CIR: cir.store{{.*}} %{{.*}}, %[[NULLPTR]] : !s32i, !cir.ptr<!s32i> +// CIR: %[[NULLPTR_A:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!rec_A> +// CIR: %[[A_X:.*]] = cir.get_member %[[NULLPTR_A]][0] {name = "x"} : !cir.ptr<!rec_A> -> !cir.ptr<!s32i> diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index 73c05b3..083d438 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -1359,3 +1359,49 @@ void complex_type_argument() { // OGCG: store float %[[A_IMAG]], ptr %[[ARG_IMAG_PTR]], align 4 // OGCG: %[[TMP_ARG:.*]] = load <2 x float>, ptr %[[ARG_ADDR]], align 4 // OGCG: call void @_Z22complex_type_parameterCf(<2 x float> noundef %[[TMP_ARG]]) + +void real_on_scalar_bool() { + bool a; + bool b = __real__ a; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["a"] +// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["b", init] +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.bool>, !cir.bool +// CIR: %[[A_REAL:.*]] = cir.complex.real %[[TMP_A]] : !cir.bool -> !cir.bool +// CIR: cir.store{{.*}} %[[A_REAL]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool> + +// LLVM: %[[A_ADDR:.*]] = alloca i8, i64 1, align 1 +// LLVM: %[[B_ADDR:.*]] = alloca i8, i64 1, align 1 +// LLVM: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1 +// LLVM: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1 +// LLVM: %[[TMP_A_I8:.*]] = zext i1 %[[TMP_A_I1]] to i8 +// LLVM: store i8 %[[TMP_A_I8]], ptr %[[B_ADDR]], align 1 + +// OGCG: %[[A_ADDR:.*]] = alloca i8, align 1 +// OGCG: %[[B_ADDR:.*]] = alloca i8, align 1 +// OGCG: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1 +// OGCG: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1 +// OGCG: %[[TMP_A_I8:.*]] = zext i1 %[[TMP_A_I1]] to i8 +// OGCG: store i8 %[[TMP_A_I8]], ptr %[[B_ADDR]], align 1 + +void imag_on_scalar_bool() { + bool a; + bool b = __imag__ a; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["a"] +// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["b", init] +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.bool>, !cir.bool +// CIR: %[[A_IMAG:.*]] = cir.complex.imag %[[TMP_A]] : !cir.bool -> !cir.bool +// CIR: cir.store{{.*}} %[[A_IMAG]], %[[B_ADDR]] : !cir.bool, !cir.ptr<!cir.bool> + +// LLVM: %[[A_ADDR:.*]] = alloca i8, i64 1, align 1 +// LLVM: %[[B_ADDR:.*]] = alloca i8, i64 1, align 1 +// LLVM: %[[TMP_A:.*]] = load i8, ptr %[[A_ADDR]], align 1 +// LLVM: %[[TMP_A_I1:.*]] = trunc i8 %[[TMP_A]] to i1 +// LLVM: store i8 0, ptr %[[B_ADDR]], align 1 + +// OGCG: %[[A_ADDR:.*]] = alloca i8, align 1 +// OGCG: %[[B_ADDR:.*]] = alloca i8, align 1 +// OGCG: store i8 0, ptr %[[B_ADDR]], align 1 diff --git a/clang/test/CIR/CodeGen/constant-inits.cpp b/clang/test/CIR/CodeGen/constant-inits.cpp index c9153c91..d5a7bb9 100644 --- a/clang/test/CIR/CodeGen/constant-inits.cpp +++ b/clang/test/CIR/CodeGen/constant-inits.cpp @@ -30,6 +30,41 @@ struct simple { int a, b; }; +// Byte-aligned bitfields +struct byte_aligned_bitfields { + unsigned int a : 8; + unsigned int b : 8; + unsigned int c : 16; +}; + +struct signed_byte_aligned_bitfields { + int x : 8; + int y : 8; +}; + +struct single_byte_bitfield { + unsigned char a : 8; +}; + +// Partial bitfields (sub-byte) +struct partial_bitfields { + unsigned int a : 3; + unsigned int b : 5; + unsigned int c : 8; +}; + +struct signed_partial_bitfields { + int x : 4; + int y : 4; +}; + +struct mixed_partial_bitfields { + unsigned char a : 1; + unsigned char b : 1; + unsigned char c : 1; + unsigned char d : 5; +}; + void function() { constexpr static empty e; @@ -54,8 +89,22 @@ void function() { constexpr static simple simple_array[] { s, {1111, 2222}, s }; + + // Byte-aligned bitfield tests + constexpr static byte_aligned_bitfields ba_bf1 = {0xFF, 0xAA, 0x1234}; + constexpr static signed_byte_aligned_bitfields ba_bf2 = {-1, 127}; + constexpr static single_byte_bitfield ba_bf3 = {42}; + + // Partial bitfield tests + constexpr static partial_bitfields p_bf1 = {1, 2, 3}; + constexpr static signed_partial_bitfields p_bf2 = {-1, 7}; + constexpr static mixed_partial_bitfields p_bf3 = {1, 0, 1, 15}; } +// Anonymous struct type definitions for bitfields +// CIR-DAG: !rec_anon_struct = !cir.record<struct {!u8i, !u8i, !u8i, !u8i}> +// CIR-DAG: !rec_anon_struct1 = !cir.record<struct {!u8i, !u8i, !cir.array<!u8i x 2>}> + // CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE1e = #cir.zero : !rec_empty // CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE1s = #cir.const_record<{#cir.int<0> : !s32i, #cir.int<-1> : !s32i}> : !rec_simple // CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE2p1 = #cir.const_record<{#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.const_array<[#cir.int<99> : !s8i, #cir.int<88> : !s8i, #cir.int<77> : !s8i]> : !cir.array<!s8i x 3>, #cir.int<40> : !s32i}> : !rec_Point @@ -83,6 +132,33 @@ void function() { // CIR-DAG-SAME: #cir.zero : !rec_packed_and_aligned // CIR-DAG-SAME: ]> : !cir.array<!rec_packed_and_aligned x 2> +// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE6ba_bf1 = #cir.const_record<{ +// CIR-DAG-SAME: #cir.int<255> : !u8i, +// CIR-DAG-SAME: #cir.int<170> : !u8i, +// CIR-DAG-SAME: #cir.int<52> : !u8i, +// CIR-DAG-SAME: #cir.int<18> : !u8i +// CIR-DAG-SAME: }> : !rec_anon_struct +// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE6ba_bf2 = #cir.const_record<{ +// CIR-DAG-SAME: #cir.int<255> : !u8i, +// CIR-DAG-SAME: #cir.int<127> : !u8i, +// CIR-DAG-SAME: #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 2> +// CIR-DAG-SAME: }> : !rec_anon_struct1 +// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE6ba_bf3 = #cir.const_record<{ +// CIR-DAG-SAME: #cir.int<42> : !u8i +// CIR-DAG-SAME: }> : !rec_single_byte_bitfield +// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5p_bf1 = #cir.const_record<{ +// CIR-DAG-SAME: #cir.int<17> : !u8i, +// CIR-DAG-SAME: #cir.int<3> : !u8i, +// CIR-DAG-SAME: #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 2> +// CIR-DAG-SAME: }> : !rec_anon_struct1 +// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5p_bf2 = #cir.const_record<{ +// CIR-DAG-SAME: #cir.int<127> : !u8i, +// CIR-DAG-SAME: #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, #cir.zero : !u8i]> : !cir.array<!u8i x 3> +// CIR-DAG-SAME: }> : !rec_signed_partial_bitfields +// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5p_bf3 = #cir.const_record<{ +// CIR-DAG-SAME: #cir.int<125> : !u8i +// CIR-DAG-SAME: }> : !rec_mixed_partial_bitfields + // CIR-LABEL: cir.func dso_local @_Z8functionv() // CIR: cir.return @@ -96,6 +172,12 @@ void function() { // LLVM-DAG: @_ZZ8functionvE3paa = internal global %struct.packed_and_aligned <{ i16 1, i8 2, float 3.000000e+00, i8 0 }> // LLVM-DAG: @_ZZ8functionvE5array = internal global [2 x %struct.Point] [%struct.Point { i32 123, i32 456, [3 x i8] c"\0B\16!", i32 789 }, %struct.Point { i32 10, i32 20, [3 x i8] zeroinitializer, i32 40 }] // LLVM-DAG: @_ZZ8functionvE9paa_array = internal global [2 x %struct.packed_and_aligned] [%struct.packed_and_aligned <{ i16 1, i8 2, float 3.000000e+00, i8 0 }>, %struct.packed_and_aligned zeroinitializer] +// LLVM-DAG: @_ZZ8functionvE6ba_bf1 = internal global { i8, i8, i8, i8 } { i8 -1, i8 -86, i8 52, i8 18 } +// LLVM-DAG: @_ZZ8functionvE6ba_bf2 = internal global { i8, i8, [2 x i8] } { i8 -1, i8 127, [2 x i8] zeroinitializer } +// LLVM-DAG: @_ZZ8functionvE6ba_bf3 = internal global %struct.single_byte_bitfield { i8 42 } +// LLVM-DAG: @_ZZ8functionvE5p_bf1 = internal global { i8, i8, [2 x i8] } { i8 17, i8 3, [2 x i8] zeroinitializer } +// LLVM-DAG: @_ZZ8functionvE5p_bf2 = internal global %struct.signed_partial_bitfields { i8 127, [3 x i8] zeroinitializer } +// LLVM-DAG: @_ZZ8functionvE5p_bf3 = internal global %struct.mixed_partial_bitfields { i8 125 } // LLVM-LABEL: define{{.*}} void @_Z8functionv // LLVM: ret void @@ -110,6 +192,12 @@ void function() { // OGCG-DAG: @_ZZ8functionvE3paa = internal constant %struct.packed_and_aligned <{ i16 1, i8 2, float 3.000000e+00, i8 undef }> // OGCG-DAG: @_ZZ8functionvE5array = internal constant [2 x %struct.Point] [%struct.Point { i32 123, i32 456, [3 x i8] c"\0B\16!", i32 789 }, %struct.Point { i32 10, i32 20, [3 x i8] zeroinitializer, i32 40 }] // OGCG-DAG: @_ZZ8functionvE9paa_array = internal constant [2 x %struct.packed_and_aligned] [%struct.packed_and_aligned <{ i16 1, i8 2, float 3.000000e+00, i8 undef }>, %struct.packed_and_aligned <{ i16 0, i8 0, float 0.000000e+00, i8 undef }>] +// OGCG-DAG: @_ZZ8functionvE6ba_bf1 = internal constant { i8, i8, i8, i8 } { i8 -1, i8 -86, i8 52, i8 18 } +// OGCG-DAG: @_ZZ8functionvE6ba_bf2 = internal constant { i8, i8, [2 x i8] } { i8 -1, i8 127, [2 x i8] undef } +// OGCG-DAG: @_ZZ8functionvE6ba_bf3 = internal constant %struct.single_byte_bitfield { i8 42 } +// OGCG-DAG: @_ZZ8functionvE5p_bf1 = internal constant { i8, i8, [2 x i8] } { i8 17, i8 3, [2 x i8] undef } +// OGCG-DAG: @_ZZ8functionvE5p_bf2 = internal constant %struct.signed_partial_bitfields { i8 127, [3 x i8] undef } +// OGCG-DAG: @_ZZ8functionvE5p_bf3 = internal constant %struct.mixed_partial_bitfields { i8 125 } // OGCG-LABEL: define{{.*}} void @_Z8functionv // OGCG: ret void diff --git a/clang/test/CIR/CodeGen/dtors.cpp b/clang/test/CIR/CodeGen/dtors.cpp index 66554b7..49952a7 100644 --- a/clang/test/CIR/CodeGen/dtors.cpp +++ b/clang/test/CIR/CodeGen/dtors.cpp @@ -171,3 +171,40 @@ bool test_temp_and() { return make_temp(1) && make_temp(2); } // OGCG: br label %[[CLEANUP_DONE]] // OGCG: [[CLEANUP_DONE]]: // OGCG: call void @_ZN1BD2Ev(ptr {{.*}} %[[REF_TMP0]]) + +struct C { + ~C(); +}; + +struct D { + int n; + C c; + ~D() {} +}; + +// CIR: cir.func {{.*}} @_ZN1DD2Ev +// CIR: %[[C:.*]] = cir.get_member %{{.*}}[1] {name = "c"} +// CIR: cir.call @_ZN1CD1Ev(%[[C]]) + +// LLVM: define {{.*}} void @_ZN1DD2Ev +// LLVM: %[[C:.*]] = getelementptr %struct.D, ptr %{{.*}}, i32 0, i32 1 +// LLVM: call void @_ZN1CD1Ev(ptr %[[C]]) + +// This destructor is defined after the calling function in OGCG. + +void test_nested_dtor() { + D d; +} + +// CIR: cir.func{{.*}} @_Z16test_nested_dtorv() +// CIR: cir.call @_ZN1DD2Ev(%{{.*}}) + +// LLVM: define {{.*}} void @_Z16test_nested_dtorv() +// LLVM: call void @_ZN1DD2Ev(ptr %{{.*}}) + +// OGCG: define {{.*}} void @_Z16test_nested_dtorv() +// OGCG: call void @_ZN1DD2Ev(ptr {{.*}} %{{.*}}) + +// OGCG: define {{.*}} void @_ZN1DD2Ev +// OGCG: %[[C:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i64 4 +// OGCG: call void @_ZN1CD1Ev(ptr {{.*}} %[[C]]) diff --git a/clang/test/CIR/CodeGen/global-init.cpp b/clang/test/CIR/CodeGen/global-init.cpp index 0c19e68..2afb5a5 100644 --- a/clang/test/CIR/CodeGen/global-init.cpp +++ b/clang/test/CIR/CodeGen/global-init.cpp @@ -1,9 +1,10 @@ // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -mmlir --mlir-print-ir-before=cir-lowering-prepare %s -o %t.cir 2> %t-before.cir // RUN: FileCheck --input-file=%t-before.cir %s --check-prefix=CIR-BEFORE-LPP // RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR - -// Note: The LoweringPrepare work isn't yet complete. We still need to create -// the global ctor list attribute. +// RUN: %clang_cc1 -std=c++17 -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 +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG struct NeedsCtor { NeedsCtor(); @@ -15,6 +16,9 @@ NeedsCtor needsCtor; // CIR-BEFORE-LPP: %[[THIS:.*]] = cir.get_global @needsCtor : !cir.ptr<!rec_NeedsCtor> // CIR-BEFORE-LPP: cir.call @_ZN9NeedsCtorC1Ev(%[[THIS]]) : (!cir.ptr<!rec_NeedsCtor>) -> () +// CIR: module @{{.*}} attributes { +// CIR-SAME: cir.global_ctors = [#cir.global_ctor<"_GLOBAL__sub_I_[[FILENAME:.*]]", 65535>] + // CIR: cir.global external @needsCtor = #cir.zero : !rec_NeedsCtor // CIR: cir.func internal private @__cxx_global_var_init() { // CIR: %0 = cir.get_global @needsCtor : !cir.ptr<!rec_NeedsCtor> @@ -24,3 +28,22 @@ NeedsCtor needsCtor; // CIR: cir.call @__cxx_global_var_init() : () -> () // CIR: cir.return // CIR: } + +// LLVM: @needsCtor = global %struct.NeedsCtor zeroinitializer, align 1 +// LLVM: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I_[[FILENAME:.*]], ptr null }] +// LLVM: declare void @_ZN9NeedsCtorC1Ev(ptr) + +// LLVM: define internal void @__cxx_global_var_init() +// LLVM: call void @_ZN9NeedsCtorC1Ev(ptr @needsCtor) + +// LLVM: define void @_GLOBAL__sub_I_[[FILENAME]]() +// LLVM: call void @__cxx_global_var_init() + +// OGCG: @needsCtor = global %struct.NeedsCtor zeroinitializer, align 1 +// OGCG: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I_[[FILENAME:.*]], ptr null }] + +// OGCG: define internal void @__cxx_global_var_init() {{.*}} section ".text.startup" { +// OGCG: call void @_ZN9NeedsCtorC1Ev(ptr noundef nonnull align 1 dereferenceable(1) @needsCtor) + +// OGCG: define internal void @_GLOBAL__sub_I_[[FILENAME]]() {{.*}} section ".text.startup" { +// OGCG: call void @__cxx_global_var_init() diff --git a/clang/test/CIR/CodeGen/new.cpp b/clang/test/CIR/CodeGen/new.cpp index 3dcf7af..000ea5b 100644 --- a/clang/test/CIR/CodeGen/new.cpp +++ b/clang/test/CIR/CodeGen/new.cpp @@ -180,3 +180,56 @@ void test_new_with_complex_type() { // OGCG: store float 1.000000e+00, ptr %[[COMPLEX_REAL_PTR]], align 8 // OGCG: store float 2.000000e+00, ptr %[[COMPLEX_IMAG_PTR]], align 4 // OGCG: store ptr %[[NEW_COMPLEX]], ptr %[[A_ADDR]], align 8 + +void t_new_constant_size() { + auto p = new double[16]; +} + +// In this test, NUM_ELEMENTS isn't used because no cookie is needed and there +// are no constructor calls needed. + +// CHECK: cir.func{{.*}} @_Z19t_new_constant_sizev() +// CHECK: %[[P_ADDR:.*]] = cir.alloca !cir.ptr<!cir.double>, !cir.ptr<!cir.ptr<!cir.double>>, ["p", init] {alignment = 8 : i64} +// CHECK: %[[#NUM_ELEMENTS:]] = cir.const #cir.int<16> : !u64i +// CHECK: %[[#ALLOCATION_SIZE:]] = cir.const #cir.int<128> : !u64i +// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[#ALLOCATION_SIZE]]) : (!u64i) -> !cir.ptr<!void> +// CHECK: %[[TYPED_PTR:.*]] = cir.cast bitcast %[[RAW_PTR]] : !cir.ptr<!void> -> !cir.ptr<!cir.double> +// CHECK: cir.store align(8) %[[TYPED_PTR]], %[[P_ADDR]] : !cir.ptr<!cir.double>, !cir.ptr<!cir.ptr<!cir.double>> +// CHECK: cir.return +// CHECK: } + +// LLVM: define{{.*}} void @_Z19t_new_constant_sizev +// LLVM: %[[P_ADDR:.*]] = alloca ptr, i64 1, align 8 +// LLVM: %[[CALL:.*]] = call ptr @_Znam(i64 128) +// LLVM: store ptr %[[CALL]], ptr %[[P_ADDR]], align 8 + +// OGCG: define{{.*}} void @_Z19t_new_constant_sizev +// OGCG: %[[P_ADDR:.*]] = alloca ptr, align 8 +// OGCG: %[[CALL:.*]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 128) +// OGCG: store ptr %[[CALL]], ptr %[[P_ADDR]], align 8 + + +void t_new_multidim_constant_size() { + auto p = new double[2][3][4]; +} + +// As above, NUM_ELEMENTS isn't used. + +// CHECK: cir.func{{.*}} @_Z28t_new_multidim_constant_sizev() +// CHECK: %[[P_ADDR:.*]] = cir.alloca !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>, !cir.ptr<!cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>>, ["p", init] {alignment = 8 : i64} +// CHECK: %[[#NUM_ELEMENTS:]] = cir.const #cir.int<24> : !u64i +// CHECK: %[[#ALLOCATION_SIZE:]] = cir.const #cir.int<192> : !u64i +// CHECK: %[[RAW_PTR:.*]] = cir.call @_Znam(%[[#ALLOCATION_SIZE]]) : (!u64i) -> !cir.ptr<!void> +// CHECK: %[[TYPED_PTR:.*]] = cir.cast bitcast %[[RAW_PTR]] : !cir.ptr<!void> -> !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>> +// CHECK: cir.store align(8) %[[TYPED_PTR]], %[[P_ADDR]] : !cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>, !cir.ptr<!cir.ptr<!cir.array<!cir.array<!cir.double x 4> x 3>>> +// CHECK: } + +// LLVM: define{{.*}} void @_Z28t_new_multidim_constant_sizev +// LLVM: %[[P_ADDR:.*]] = alloca ptr, i64 1, align 8 +// LLVM: %[[CALL:.*]] = call ptr @_Znam(i64 192) +// LLVM: store ptr %[[CALL]], ptr %[[P_ADDR]], align 8 + +// OGCG: define{{.*}} void @_Z28t_new_multidim_constant_sizev +// OGCG: %[[P_ADDR:.*]] = alloca ptr, align 8 +// OGCG: %[[CALL:.*]] = call noalias noundef nonnull ptr @_Znam(i64 noundef 192) +// OGCG: store ptr %[[CALL]], ptr %[[P_ADDR]], align 8 diff --git a/clang/test/CIR/CodeGen/throws.cpp b/clang/test/CIR/CodeGen/throws.cpp index 0122f30..ff6aa62 100644 --- a/clang/test/CIR/CodeGen/throws.cpp +++ b/clang/test/CIR/CodeGen/throws.cpp @@ -5,7 +5,7 @@ // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG -void foo() { +void rethrow() { throw; } @@ -18,7 +18,7 @@ void foo() { // OGCG: call void @__cxa_rethrow() // OGCG: unreachable -int foo1(int a, int b) { +int rethrow_from_block(int a, int b) { if (b == 0) throw; return a / b; @@ -83,3 +83,43 @@ int foo1(int a, int b) { // OGCG: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4 // OGCG: %[[DIV_A_B:.*]] = sdiv i32 %[[TMP_A]], %[[TMP_B]] // OGCG: ret i32 %[[DIV_A_B]] + +void throw_scalar() { + throw 1; +} + +// CIR: %[[EXCEPTION_ADDR:.*]] = cir.alloc.exception 4 -> !cir.ptr<!s32i> +// CIR: %[[EXCEPTION_VALUE:.*]] = cir.const #cir.int<1> : !s32i +// CIR: cir.store{{.*}} %[[EXCEPTION_VALUE]], %[[EXCEPTION_ADDR]] : !s32i, !cir.ptr<!s32i> +// CIR: cir.throw %[[EXCEPTION_ADDR]] : !cir.ptr<!s32i>, @_ZTIi +// CIR: cir.unreachable + +// LLVM: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 4) +// LLVM: store i32 1, ptr %[[EXCEPTION_ADDR]], align 16 +// LLVM: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTIi, ptr null) +// LLVM: unreachable + +// OGCG: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 4) +// OGCG: store i32 1, ptr %[[EXCEPTION_ADDR]], align 16 +// OGCG: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTIi, ptr null) +// OGCG: unreachable + +void paren_expr() { (throw 0, 1 + 2); } + +// CIR: %[[EXCEPTION_ADDR:.*]] = cir.alloc.exception 4 -> !cir.ptr<!s32i> +// CIR: %[[EXCEPTION_VALUE:.*]] = cir.const #cir.int<0> : !s32i +// CIR: cir.store{{.*}} %[[EXCEPTION_VALUE]], %[[EXCEPTION_ADDR]] : !s32i, !cir.ptr<!s32i> +// CIR: cir.throw %[[EXCEPTION_ADDR]] : !cir.ptr<!s32i>, @_ZTIi +// CIR: cir.unreachable +// CIR: ^bb1: +// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i +// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i +// CIR: %[[ADD:.*]] = cir.binop(add, %[[CONST_1]], %[[CONST_2]]) nsw : !s32i + +// LLVM: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 4) +// LLVM: store i32 0, ptr %[[EXCEPTION_ADDR]], align 16 +// LLVM: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTIi, ptr null) + +// OGCG: %[[EXCEPTION_ADDR:.*]] = call ptr @__cxa_allocate_exception(i64 4) +// OGCG: store i32 0, ptr %[[EXCEPTION_ADDR]], align 16 +// OGCG: call void @__cxa_throw(ptr %[[EXCEPTION_ADDR]], ptr @_ZTIi, ptr null) diff --git a/clang/test/CIR/CodeGenOpenACC/private-clause-array-recipes-int.cpp b/clang/test/CIR/CodeGenOpenACC/private-clause-array-recipes-int.cpp index e83e548..74cb567 100644 --- a/clang/test/CIR/CodeGenOpenACC/private-clause-array-recipes-int.cpp +++ b/clang/test/CIR/CodeGenOpenACC/private-clause-array-recipes-int.cpp @@ -21,7 +21,7 @@ void do_things(unsigned A, unsigned B) { ; T TwoArr[5][5]; -#pragma acc parallel private(TwoArr[B][B]) +#pragma acc parallel private(TwoArr[A:B][A:B]) // CHECK-NEXT: acc.private.recipe @privatization__Bcnt2__ZTSA5_A5_i : !cir.ptr<!cir.array<!cir.array<!s32i x 5> x 5>> init { // CHECK-NEXT: ^bb0(%arg0: !cir.ptr<!cir.array<!cir.array<!s32i x 5> x 5>> {{.*}}, %[[BOUND1:.*]]: !acc.data_bounds_ty {{.*}}, %[[BOUND2:.*]]: !acc.data_bounds_ty {{.*}}): // CHECK-NEXT: %[[TL_ALLOCA:.*]] = cir.alloca !cir.array<!cir.array<!s32i x 5> x 5>, !cir.ptr<!cir.array<!cir.array<!s32i x 5> x 5>>, ["openacc.private.init"] {alignment = 4 : i64} @@ -30,7 +30,7 @@ void do_things(unsigned A, unsigned B) { ; #pragma acc parallel private(TwoArr[B][A:B]) ; -#pragma acc parallel private(TwoArr[A:B][A:B]) +#pragma acc parallel private(TwoArr[B][B]) ; #pragma acc parallel private(TwoArr) // CHECK-NEXT: acc.private.recipe @privatization__ZTSA5_A5_i : !cir.ptr<!cir.array<!cir.array<!s32i x 5> x 5>> init { diff --git a/clang/test/CIR/IR/dynamic-cast.cir b/clang/test/CIR/IR/dynamic-cast.cir new file mode 100644 index 0000000..283f11e --- /dev/null +++ b/clang/test/CIR/IR/dynamic-cast.cir @@ -0,0 +1,59 @@ +// RUN: cir-opt --verify-roundtrip %s | FileCheck %s + +!s64i = !cir.int<s, 64> +!u8i = !cir.int<u, 8> +!void = !cir.void + +!rec_Base = !cir.record<struct "Base" {!cir.vptr}> +!rec_Derived = !cir.record<struct "Derived" {!rec_Base}> + +#dyn_cast_info__ZTI4Base__ZTI7Derived = #cir.dyn_cast_info<src_rtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, dest_rtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, runtime_func = @__dynamic_cast, bad_cast_func = @__cxa_bad_cast, offset_hint = #cir.int<0> : !s64i> + +// CHECK: #dyn_cast_info__ZTI4Base__ZTI7Derived = #cir.dyn_cast_info<src_rtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, dest_rtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, runtime_func = @__dynamic_cast, bad_cast_func = @__cxa_bad_cast, offset_hint = #cir.int<0> : !s64i> + +module { + cir.global "private" constant external @_ZTI4Base : !cir.ptr<!u8i> + cir.global "private" constant external @_ZTI7Derived : !cir.ptr<!u8i> + cir.func private @__dynamic_cast(!cir.ptr<!void>, !cir.ptr<!u8i>, !cir.ptr<!u8i>, !s64i) -> !cir.ptr<!void> + cir.func private @__cxa_bad_cast() + + cir.func @test_ptr_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!rec_Derived> { + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived + cir.return %0 : !cir.ptr<!rec_Derived> + } + + // CHECK: cir.func @test_ptr_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!rec_Derived> { + // CHECK: %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived + // CHECK: cir.return %0 : !cir.ptr<!rec_Derived> + // CHECK: } + + cir.func @test_ref_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!rec_Derived> { + %0 = cir.dyn_cast ref %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived + cir.return %0 : !cir.ptr<!rec_Derived> + } + + // CHECK: cir.func @test_ref_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!rec_Derived> { + // CHECK: %0 = cir.dyn_cast ref %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived + // CHECK: cir.return %0 : !cir.ptr<!rec_Derived> + // CHECK: } + + cir.func dso_local @test_cast_to_void(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!void> { + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!void> + cir.return %0 : !cir.ptr<!void> + } + + // CHECK: cir.func dso_local @test_cast_to_void(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!void> { + // CHECK: %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!void> + // CHECK: cir.return %0 : !cir.ptr<!void> + // CHECK: } + + cir.func dso_local @test_relative_layout_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!void> { + %0 = cir.dyn_cast ptr relative_layout %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!void> + cir.return %0 : !cir.ptr<!void> + } + + // CHECK: cir.func dso_local @test_relative_layout_cast(%arg0: !cir.ptr<!rec_Base>) -> !cir.ptr<!void> { + // CHECK: %0 = cir.dyn_cast ptr relative_layout %arg0 : !cir.ptr<!rec_Base> -> !cir.ptr<!void> + // CHECK: cir.return %0 : !cir.ptr<!void> + // CHECK: } +} diff --git a/clang/test/CIR/IR/invalid-dyn-cast.cir b/clang/test/CIR/IR/invalid-dyn-cast.cir new file mode 100644 index 0000000..65c7fc1 --- /dev/null +++ b/clang/test/CIR/IR/invalid-dyn-cast.cir @@ -0,0 +1,43 @@ +// RUN: cir-opt %s -verify-diagnostics -split-input-file + +!s64i = !cir.int<s, 64> +!s8i = !cir.int<s, 8> +!u32i = !cir.int<u, 32> +!u8i = !cir.int<u, 8> +!void = !cir.void + +!Base = !cir.record<struct "Base" {!cir.ptr<!cir.ptr<!cir.func<() -> !cir.int<u, 32>>>>}> +!Derived = !cir.record<struct "Derived" {!cir.record<struct "Base" {!cir.ptr<!cir.ptr<!cir.func<() -> !cir.int<u, 32>>>>}>}> + +module { + cir.global "private" constant external @_ZTI4Base : !cir.ptr<!u32i> + cir.global "private" constant external @_ZTI7Derived : !cir.ptr<!u8i> + cir.func private @__dynamic_cast(!cir.ptr<!void>, !cir.ptr<!u8i>, !cir.ptr<!u8i>, !s64i) -> !cir.ptr<!void> + cir.func private @__cxa_bad_cast() + cir.func @test(%arg0 : !cir.ptr<!Base>) { + // expected-error@+1 {{srcRtti must be an RTTI pointer}} + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!Base> -> !cir.ptr<!Derived> #cir.dyn_cast_info<src_rtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u32i>, dest_rtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>, runtime_func = @__dynamic_cast, bad_cast_func = @__cxa_bad_cast, offset_hint = #cir.int<0> : !s64i> + } +} + +// ----- + +!s64i = !cir.int<s, 64> +!s8i = !cir.int<s, 8> +!u32i = !cir.int<u, 32> +!u8i = !cir.int<u, 8> +!void = !cir.void + +!Base = !cir.record<struct "Base" {!cir.ptr<!cir.ptr<!cir.func<() -> !cir.int<u, 32>>>>}> +!Derived = !cir.record<struct "Derived" {!cir.record<struct "Base" {!cir.ptr<!cir.ptr<!cir.func<() -> !cir.int<u, 32>>>>}>}> + +module { + cir.global "private" constant external @_ZTI4Base : !cir.ptr<!u8i> + cir.global "private" constant external @_ZTI7Derived : !cir.ptr<!u32i> + cir.func private @__dynamic_cast(!cir.ptr<!void>, !cir.ptr<!u8i>, !cir.ptr<!u8i>, !s64i) -> !cir.ptr<!void> + cir.func private @__cxa_bad_cast() + cir.func @test(%arg0 : !cir.ptr<!Base>) { + // expected-error@+1 {{destRtti must be an RTTI pointer}} + %0 = cir.dyn_cast ptr %arg0 : !cir.ptr<!Base> -> !cir.ptr<!Derived> #cir.dyn_cast_info<src_rtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>, dest_rtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u32i>, runtime_func = @__dynamic_cast, bad_cast_func = @__cxa_bad_cast, offset_hint = #cir.int<0> : !s64i> + } +} |