brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.4 KiB · 01277a3 Raw
114 lines · cpp
1// 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.cir2// RUN: FileCheck --input-file=%t-before.cir %s --check-prefix=CIR-BEFORE-LPP3// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR4// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll5// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM6// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll7// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG8 9// This duplicates a test case in global-init.cpp, but having it by itself10// forces the __cxa_atexit function to be emitted for this case, which was11// broken in the original implementation.12 13struct ArrayDtor {14  ~ArrayDtor();15};16 17ArrayDtor arrDtor[16];18 19// CIR-BEFORE-LPP:      cir.global external @arrDtor = #cir.zero : !cir.array<!rec_ArrayDtor x 16>20// CIR-BEFORE-LPP-SAME:   dtor {21// CIR-BEFORE-LPP:          %[[THIS:.*]] = cir.get_global @arrDtor : !cir.ptr<!cir.array<!rec_ArrayDtor x 16>>22// CIR-BEFORE-LPP:          cir.array.dtor %[[THIS]] : !cir.ptr<!cir.array<!rec_ArrayDtor x 16>> {23// CIR-BEFORE-LPP:          ^bb0(%[[ELEM:.*]]: !cir.ptr<!rec_ArrayDtor>):24// CIR-BEFORE-LPP:            cir.call @_ZN9ArrayDtorD1Ev(%[[ELEM]]) nothrow : (!cir.ptr<!rec_ArrayDtor>) -> ()25// CIR-BEFORE-LPP:            cir.yield26// CIR-BEFORE-LPP:          }27// CIR-BEFORE-LPP:        }28 29// CIR: cir.global external @arrDtor = #cir.zero : !cir.array<!rec_ArrayDtor x 16> {alignment = 16 : i64}30// CIR: cir.func internal private @__cxx_global_array_dtor(%[[ARR_ARG:.*]]: !cir.ptr<!void> {{.*}}) {31// CIR:   %[[CONST15:.*]] = cir.const #cir.int<15> : !u64i32// CIR:   %[[BEGIN:.*]] = cir.cast array_to_ptrdecay %[[ARR_ARG]] : !cir.ptr<!void> -> !cir.ptr<!rec_ArrayDtor>33// CIR:   %[[END:.*]] = cir.ptr_stride %[[BEGIN]], %[[CONST15]] : (!cir.ptr<!rec_ArrayDtor>, !u64i) -> !cir.ptr<!rec_ArrayDtor>34// CIR:   %[[CUR_ADDR:.*]] = cir.alloca !cir.ptr<!rec_ArrayDtor>, !cir.ptr<!cir.ptr<!rec_ArrayDtor>>, ["__array_idx"]35// CIR:   cir.store %[[END]], %[[CUR_ADDR]] : !cir.ptr<!rec_ArrayDtor>, !cir.ptr<!cir.ptr<!rec_ArrayDtor>>36// CIR:   cir.do {37// CIR:     %[[CUR:.*]] = cir.load %[[CUR_ADDR]] : !cir.ptr<!cir.ptr<!rec_ArrayDtor>>, !cir.ptr<!rec_ArrayDtor>38// CIR:     cir.call @_ZN9ArrayDtorD1Ev(%[[CUR]]) nothrow : (!cir.ptr<!rec_ArrayDtor>) -> ()39// CIR:     %[[NEG_ONE:.*]] = cir.const #cir.int<-1> : !s64i40// CIR:     %[[NEXT:.*]] = cir.ptr_stride %[[CUR]], %[[NEG_ONE]] : (!cir.ptr<!rec_ArrayDtor>, !s64i) -> !cir.ptr<!rec_ArrayDtor>41// CIR:     cir.store %[[NEXT]], %[[CUR_ADDR]] : !cir.ptr<!rec_ArrayDtor>, !cir.ptr<!cir.ptr<!rec_ArrayDtor>>42// CIR:     cir.yield43// CIR:   } while {44// CIR:     %[[CUR:.*]] = cir.load %[[CUR_ADDR]] : !cir.ptr<!cir.ptr<!rec_ArrayDtor>>, !cir.ptr<!rec_ArrayDtor>45// CIR:     %[[CMP:.*]] = cir.cmp(ne, %[[CUR]], %[[BEGIN]]) : !cir.ptr<!rec_ArrayDtor>, !cir.bool46// CIR:     cir.condition(%[[CMP]])47// CIR:   }48// CIR:   cir.return49// CIR: }50//51// CIR: cir.func internal private @__cxx_global_var_init() {52// CIR:   %[[ARR:.*]] = cir.get_global @arrDtor : !cir.ptr<!cir.array<!rec_ArrayDtor x 16>>53// CIR:   %[[DTOR:.*]] = cir.get_global @__cxx_global_array_dtor : !cir.ptr<!cir.func<(!cir.ptr<!void>)>>54// CIR:   %[[DTOR_CAST:.*]] = cir.cast bitcast %[[DTOR]] : !cir.ptr<!cir.func<(!cir.ptr<!void>)>> -> !cir.ptr<!cir.func<(!cir.ptr<!void>)>>55// CIR:   %[[ARR_CAST:.*]] = cir.cast bitcast %[[ARR]] : !cir.ptr<!cir.array<!rec_ArrayDtor x 16>> -> !cir.ptr<!void>56// CIR:   %[[HANDLE:.*]] = cir.get_global @__dso_handle : !cir.ptr<i8>57// CIR:   cir.call @__cxa_atexit(%[[DTOR_CAST]], %[[ARR_CAST]], %[[HANDLE]]) : (!cir.ptr<!cir.func<(!cir.ptr<!void>)>>, !cir.ptr<!void>, !cir.ptr<i8>) -> ()58 59// LLVM: define internal void @__cxx_global_array_dtor(ptr %[[ARR_ARG:.*]]) {60// LLVM:   %[[BEGIN:.*]] = getelementptr %struct.ArrayDtor, ptr %[[ARR_ARG]], i32 061// LLVM:   %[[END:.*]] = getelementptr %struct.ArrayDtor, ptr %[[BEGIN]], i64 1562// LLVM:   %[[CUR_ADDR:.*]] = alloca ptr63// LLVM:   store ptr %[[END]], ptr %[[CUR_ADDR]]64// LLVM:   br label %[[LOOP_BODY:.*]]65// LLVM: [[LOOP_COND:.*]]:66// LLVM:   %[[CUR:.*]] = load ptr, ptr %[[CUR_ADDR]]67// LLVM:   %[[CMP:.*]] = icmp ne ptr %[[CUR]], %[[BEGIN]]68// LLVM:   br i1 %[[CMP]], label %[[LOOP_BODY]], label %[[LOOP_END:.*]]69// LLVM: [[LOOP_BODY]]:70// LLVM:   %[[CUR:.*]] = load ptr, ptr %[[CUR_ADDR]]71// LLVM:   call void @_ZN9ArrayDtorD1Ev(ptr %[[CUR]]) #072// LLVM:   %[[PREV:.*]] = getelementptr %struct.ArrayDtor, ptr %[[CUR]], i64 -173// LLVM:   store ptr %[[PREV]], ptr %[[CUR_ADDR]]74// LLVM:   br label %[[LOOP_COND]]75// LLVM: [[LOOP_END]]:76// LLVM:   ret void77// LLVM: }78//79// LLVM: define internal void @__cxx_global_var_init() {80// LLVM:   call void @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr @arrDtor, ptr @__dso_handle)81 82// Note: OGCG defines these functions in reverse order of CIR->LLVM.83// Note also: OGCG doesn't pass the address of the array to the destructor function.84//            Instead, it uses the global directly in the helper function.85 86// OGCG: define internal void @__cxx_global_var_init() {{.*}} section ".text.startup" {87// OGCG:   call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle)88 89// OGCG: define internal void @__cxx_global_array_dtor(ptr noundef %[[ARG:.*]]) {{.*}} section ".text.startup" {90// OGCG: entry:91// OGCG:   %[[UNUSED_ADDR:.*]] = alloca ptr92// OGCG:   store ptr %[[ARG]], ptr %[[UNUSED_ADDR]]93// OGCG:   br label %[[LOOP_BODY:.*]]94// OGCG: [[LOOP_BODY]]:95// OGCG:   %[[PREV:.*]] = phi ptr [ getelementptr inbounds (%struct.ArrayDtor, ptr @arrDtor, i64 16), %entry ], [ %[[CUR:.*]], %[[LOOP_BODY]] ]96// OGCG:   %[[CUR]] = getelementptr inbounds %struct.ArrayDtor, ptr %[[PREV]], i64 -197// OGCG:   call void @_ZN9ArrayDtorD1Ev(ptr noundef nonnull align 1 dereferenceable(1) %[[CUR]])98// OGCG:   %[[DONE:.*]] = icmp eq ptr %[[CUR]], @arrDtor99// OGCG:   br i1 %[[DONE]], label %[[LOOP_END:.*]], label %[[LOOP_BODY]]100// OGCG: [[LOOP_END]]:101// OGCG:   ret void102// OGCG: }103 104// Common init function for all globals with default priority105 106// CIR: cir.func private @_GLOBAL__sub_I_[[FILENAME:.*]]() {107// CIR:   cir.call @__cxx_global_var_init() : () -> ()108 109// LLVM: define void @_GLOBAL__sub_I_[[FILENAME:.*]]()110// LLVM:   call void @__cxx_global_var_init()111 112// OGCG: define internal void @_GLOBAL__sub_I_[[FILENAME:.*]]() {{.*}} section ".text.startup" {113// OGCG:   call void @__cxx_global_var_init()114