brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · 5d010d2 Raw
160 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-cir -mmlir --mlir-print-ir-before=cir-lowering-prepare %s -o %t.cir 2> %t.before.log2// RUN: FileCheck %s --input-file=%t.before.log -check-prefix=CIR-BEFORE3// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-cir -mmlir --mlir-print-ir-after=cir-lowering-prepare %s -o %t.cir 2> %t.after.log4// RUN: FileCheck %s --input-file=%t.after.log -check-prefix=CIR-AFTER5// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-llvm %s -o %t-cir.ll6// RUN: FileCheck %s --input-file=%t-cir.ll -check-prefix=LLVM7// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -emit-llvm %s -o %t.ll8// RUN: FileCheck %s --input-file=%t.ll -check-prefix=OGCG9 10struct Base {11  virtual ~Base();12};13 14struct Derived : Base {};15 16// CIR-BEFORE-DAG: !rec_Base = !cir.record17// CIR-BEFORE-DAG: !rec_Derived = !cir.record18// CIR-BEFORE-DAG: #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>19 20Derived *ptr_cast(Base *b) {21  return dynamic_cast<Derived *>(b);22}23 24// CIR-BEFORE: cir.func dso_local @_Z8ptr_castP4Base25// CIR-BEFORE:   %{{.+}} = cir.dyn_cast ptr %{{.+}} : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived26// CIR-BEFORE: }27 28//      CIR-AFTER: cir.func dso_local @_Z8ptr_castP4Base29//      CIR-AFTER:   %[[SRC:.*]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!rec_Base>>, !cir.ptr<!rec_Base>30// CIR-AFTER-NEXT:   %[[SRC_IS_NOT_NULL:.*]] = cir.cast ptr_to_bool %[[SRC]] : !cir.ptr<!rec_Base> -> !cir.bool31// CIR-AFTER-NEXT:   %{{.+}} = cir.ternary(%[[SRC_IS_NOT_NULL]], true {32// CIR-AFTER-NEXT:     %[[SRC_VOID_PTR:.*]] = cir.cast bitcast %[[SRC]] : !cir.ptr<!rec_Base> -> !cir.ptr<!void>33// CIR-AFTER-NEXT:     %[[BASE_RTTI:.*]] = cir.const #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>34// CIR-AFTER-NEXT:     %[[DERIVED_RTTI:.*]] = cir.const #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>35// CIR-AFTER-NEXT:     %[[HINT:.*]] = cir.const #cir.int<0> : !s64i36// CIR-AFTER-NEXT:     %[[RT_CALL_RET:.*]] = cir.call @__dynamic_cast(%[[SRC_VOID_PTR]], %[[BASE_RTTI]], %[[DERIVED_RTTI]], %[[HINT]]) : (!cir.ptr<!void>, !cir.ptr<!u8i>, !cir.ptr<!u8i>, !s64i) -> !cir.ptr<!void>37// CIR-AFTER-NEXT:     %[[CASTED:.*]] = cir.cast bitcast %[[RT_CALL_RET]] : !cir.ptr<!void> -> !cir.ptr<!rec_Derived>38// CIR-AFTER-NEXT:     cir.yield %[[CASTED]] : !cir.ptr<!rec_Derived>39// CIR-AFTER-NEXT:   }, false {40// CIR-AFTER-NEXT:     %[[NULL_PTR:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!rec_Derived>41// CIR-AFTER-NEXT:     cir.yield %[[NULL_PTR]] : !cir.ptr<!rec_Derived>42// CIR-AFTER-NEXT:   }) : (!cir.bool) -> !cir.ptr<!rec_Derived>43//      CIR-AFTER: }44 45// LLVM: define {{.*}} @_Z8ptr_castP4Base46// LLVM:   %[[IS_NOT_NULL:.*]] = icmp ne ptr %[[PTR:.*]], null47// LLVM:   br i1 %[[IS_NOT_NULL]], label %[[NOT_NULL:.*]], label %[[NULL:.*]]48// LLVM: [[NOT_NULL]]:49// LLVM:   %[[RESULT:.*]] = call ptr @__dynamic_cast(ptr %[[PTR]], ptr @_ZTI4Base, ptr @_ZTI7Derived, i64 0)50// LLVM:   br label %[[DONE:.*]]51// LLVM: [[NULL]]:52// LLVM:   br label %[[DONE]]53// LLVM: [[DONE]]:54// LLVM:   %[[RET:.*]] = phi ptr [ null, %[[NULL]] ], [ %[[RESULT]], %[[NOT_NULL]] ]55 56// OGCG: define {{.*}} @_Z8ptr_castP4Base57// OGCG:   %[[IS_NULL:.*]] = icmp eq ptr %[[PTR:.*]], null58// OGCG:   br i1 %[[IS_NULL]], label %[[NULL:.*]], label %[[NOT_NULL:.*]]59// OGCG: [[NOT_NULL]]:60// OGCG:   %[[RESULT:.*]] = call ptr @__dynamic_cast(ptr %[[PTR]], ptr @_ZTI4Base, ptr @_ZTI7Derived, i64 0)61// OGCG:   br label %[[DONE:.*]]62// OGCG: [[NULL]]:63// OGCG:   br label %[[DONE]]64// OGCG: [[DONE]]:65// OGCG:   %[[RET:.*]] = phi ptr [ %[[RESULT]], %[[NOT_NULL]] ], [ null, %[[NULL]] ]66 67 68Derived &ref_cast(Base &b) {69  return dynamic_cast<Derived &>(b);70}71 72// CIR-BEFORE: cir.func dso_local @_Z8ref_castR4Base73// CIR-BEFORE:   %{{.+}} = cir.dyn_cast ref %{{.+}} : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived> #dyn_cast_info__ZTI4Base__ZTI7Derived74// CIR-BEFORE: }75 76//      CIR-AFTER: cir.func dso_local @_Z8ref_castR4Base77//      CIR-AFTER:   %[[SRC_VOID_PTR:.*]] = cir.cast bitcast %{{.+}} : !cir.ptr<!rec_Base> -> !cir.ptr<!void>78// CIR-AFTER-NEXT:   %[[SRC_RTTI:.*]] = cir.const #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>79// CIR-AFTER-NEXT:   %[[DEST_RTTI:.*]] = cir.const #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>80// CIR-AFTER-NEXT:   %[[OFFSET_HINT:.*]] = cir.const #cir.int<0> : !s64i81// CIR-AFTER-NEXT:   %[[CASTED_PTR:.*]] = cir.call @__dynamic_cast(%[[SRC_VOID_PTR]], %[[SRC_RTTI]], %[[DEST_RTTI]], %[[OFFSET_HINT]]) : (!cir.ptr<!void>, !cir.ptr<!u8i>, !cir.ptr<!u8i>, !s64i) -> !cir.ptr<!void>82// CIR-AFTER-NEXT:   %[[NULL_PTR:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>83// CIR-AFTER-NEXT:   %[[CASTED_PTR_IS_NULL:.*]] = cir.cmp(eq, %[[CASTED_PTR]], %[[NULL_PTR]]) : !cir.ptr<!void>, !cir.bool84// CIR-AFTER-NEXT:   cir.if %[[CASTED_PTR_IS_NULL]] {85// CIR-AFTER-NEXT:     cir.call @__cxa_bad_cast() : () -> ()86// CIR-AFTER-NEXT:     cir.unreachable87// CIR-AFTER-NEXT:   }88// CIR-AFTER-NEXT:   %{{.+}} = cir.cast bitcast %[[CASTED_PTR]] : !cir.ptr<!void> -> !cir.ptr<!rec_Derived>89//      CIR-AFTER: }90 91// LLVM: define {{.*}} ptr @_Z8ref_castR4Base92// LLVM:   %[[RESULT:.*]] = call ptr @__dynamic_cast(ptr %{{.*}}, ptr @_ZTI4Base, ptr @_ZTI7Derived, i64 0)93// LLVM:   %[[IS_NULL:.*]] = icmp eq ptr %[[RESULT]], null94// LLVM:   br i1 %[[IS_NULL]], label %[[BAD_CAST:.*]], label %[[DONE:.*]]95// LLVM: [[BAD_CAST]]:96// LLVM:   call void @__cxa_bad_cast()97 98// OGCG: define {{.*}} ptr @_Z8ref_castR4Base99// OGCG:   %[[RESULT:.*]] = call ptr @__dynamic_cast(ptr %0, ptr @_ZTI4Base, ptr @_ZTI7Derived, i64 0)100// OGCG:   %[[IS_NULL:.*]] = icmp eq ptr %[[RESULT]], null101// OGCG:   br i1 %[[IS_NULL]], label %[[BAD_CAST:.*]], label %[[DONE:.*]]102// OGCG: [[BAD_CAST]]:103// OGCG:   call void @__cxa_bad_cast()104 105void *ptr_cast_to_complete(Base *ptr) {106  return dynamic_cast<void *>(ptr);107}108 109// CIR-BEFORE: cir.func dso_local @_Z20ptr_cast_to_completeP4Base110// CIR-BEFORE:   %{{.+}} = cir.dyn_cast ptr %{{.+}} : !cir.ptr<!rec_Base> -> !cir.ptr<!void>111// CIR-BEFORE: }112 113//      CIR-AFTER: cir.func dso_local @_Z20ptr_cast_to_completeP4Base114//      CIR-AFTER:   %[[SRC:.*]] = cir.load{{.*}} %{{.+}} : !cir.ptr<!cir.ptr<!rec_Base>>, !cir.ptr<!rec_Base>115// CIR-AFTER-NEXT:   %[[SRC_IS_NOT_NULL:.*]] = cir.cast ptr_to_bool %[[SRC]] : !cir.ptr<!rec_Base> -> !cir.bool116// CIR-AFTER-NEXT:   %{{.+}} = cir.ternary(%[[SRC_IS_NOT_NULL]], true {117// CIR-AFTER-NEXT:     %[[VPTR_PTR:.*]] = cir.vtable.get_vptr %[[SRC]] : !cir.ptr<!rec_Base> -> !cir.ptr<!cir.vptr>118// CIR-AFTER-NEXT:     %[[VPTR:.*]] = cir.load %[[VPTR_PTR]] : !cir.ptr<!cir.vptr>, !cir.vptr119// CIR-AFTER-NEXT:     %[[ELEM_PTR:.*]] = cir.cast bitcast %[[VPTR]] : !cir.vptr -> !cir.ptr<!s64i>120// CIR-AFTER-NEXT:     %[[MINUS_TWO:.*]] = cir.const #cir.int<-2> : !s64i121// CIR-AFTER-NEXT:     %[[BASE_OFFSET_PTR:.*]] = cir.ptr_stride %[[ELEM_PTR]], %[[MINUS_TWO]] : (!cir.ptr<!s64i>, !s64i) -> !cir.ptr<!s64i>122// CIR-AFTER-NEXT:     %[[BASE_OFFSET:.*]] = cir.load{{.*}} %[[BASE_OFFSET_PTR]] : !cir.ptr<!s64i>, !s64i123// CIR-AFTER-NEXT:     %[[SRC_BYTES_PTR:.*]] = cir.cast bitcast %[[SRC]] : !cir.ptr<!rec_Base> -> !cir.ptr<!u8i>124// CIR-AFTER-NEXT:     %[[DST_BYTES_PTR:.*]] = cir.ptr_stride %[[SRC_BYTES_PTR]], %[[BASE_OFFSET]] : (!cir.ptr<!u8i>, !s64i) -> !cir.ptr<!u8i>125// CIR-AFTER-NEXT:     %[[CASTED_PTR:.*]] = cir.cast bitcast %[[DST_BYTES_PTR]] : !cir.ptr<!u8i> -> !cir.ptr<!void>126// CIR-AFTER-NEXT:     cir.yield %[[CASTED_PTR]] : !cir.ptr<!void>127// CIR-AFTER-NEXT:   }, false {128// CIR-AFTER-NEXT:     %[[NULL_PTR:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>129// CIR-AFTER-NEXT:     cir.yield %[[NULL_PTR]] : !cir.ptr<!void>130// CIR-AFTER-NEXT:   }) : (!cir.bool) -> !cir.ptr<!void>131//      CIR-AFTER: }132 133// LLVM: define {{.*}} @_Z20ptr_cast_to_completeP4Base134// LLVM:   %[[IS_NOT_NULL:.*]] = icmp ne ptr %[[PTR:.*]], null135// LLVM:   br i1 %[[IS_NOT_NULL]], label %[[NOT_NULL:.*]], label %[[NULL:.*]]136// LLVM: [[NOT_NULL]]:137// LLVM:   %[[VPTR:.*]] = load ptr, ptr %[[PTR]]138// LLVM:   %[[BASE_OFFSET_PTR:.*]] = getelementptr i64, ptr %7, i64 -2139// LLVM:   %[[BASE_OFFSET:.*]] = load i64, ptr %[[BASE_OFFSET_PTR]]140// LLVM:   %[[RESULT:.*]] = getelementptr i8, ptr %[[PTR]], i64 %[[BASE_OFFSET]]141// LLVM:   br label %[[DONE:.*]]142// LLVM: [[NULL]]:143// LLVM:   br label %[[DONE]]144// LLVM: [[DONE]]:145// LLVM:   %[[RET:.*]] = phi ptr [ null, %[[NULL]] ], [ %[[RESULT]], %[[NOT_NULL]] ]146 147// OGCG: define {{.*}} @_Z20ptr_cast_to_completeP4Base148// OGCG:   %[[IS_NULL:.*]] = icmp eq ptr %[[PTR:.*]], null149// OGCG:   br i1 %[[IS_NULL]], label %[[NULL:.*]], label %[[NOT_NULL:.*]]150// OGCG: [[NOT_NULL]]:151// OGCG:   %[[VPTR:.*]] = load ptr, ptr %[[PTR]]152// OGCG:   %[[BASE_OFFSET_PTR:.*]] = getelementptr inbounds i64, ptr %[[VPTR]], i64 -2153// OGCG:   %[[BASE_OFFSET:.*]] = load i64, ptr %[[BASE_OFFSET_PTR]]154// OGCG:   %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 %[[BASE_OFFSET]]155// OGCG:   br label %[[DONE:.*]]156// OGCG: [[NULL]]:157// OGCG:   br label %[[DONE]]158// OGCG: [[DONE]]:159// OGCG:   %[[RET:.*]] = phi ptr [ %[[RESULT]], %[[NOT_NULL]] ], [ null, %[[NULL]] ]160