[Clang][CodeGen] Start migrating away from assuming the Default AS is 0 (#88182)
At the moment, Clang is rather liberal in assuming that 0 (and by extension unqualified) is always a safe default. This does not work for targets that actually use a different value for the default / generic AS (for example, the SPIRV that obtains from HIPSPV or SYCL). This patch is a first, fairly safe step towards trying to clear things up by querying a modules' default AS from the target, rather than assuming it's 0, alongside fixing a few places where things break / we encode the 0 == DefaultAS assumption. A bunch of existing tests are extended to check for non-zero default AS usage.
This commit is contained in:
parent
c587483da0
commit
10edb4991c
@ -1052,7 +1052,8 @@ static void emitWasmCatchPadBlock(CodeGenFunction &CGF,
|
||||
CGF.Builder.CreateStore(Exn, CGF.getExceptionSlot());
|
||||
llvm::CallInst *Selector = CGF.Builder.CreateCall(GetSelectorFn, CPI);
|
||||
|
||||
llvm::Function *TypeIDFn = CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
|
||||
llvm::Function *TypeIDFn =
|
||||
CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
|
||||
|
||||
// If there's only a single catch-all, branch directly to its handler.
|
||||
if (CatchScope.getNumHandlers() == 1 &&
|
||||
@ -1137,7 +1138,7 @@ static void emitCatchDispatchBlock(CodeGenFunction &CGF,
|
||||
|
||||
// Select the right handler.
|
||||
llvm::Function *llvm_eh_typeid_for =
|
||||
CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
|
||||
CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});
|
||||
llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();
|
||||
LangAS globAS = CGF.CGM.GetGlobalVarAddressSpace(nullptr);
|
||||
|
||||
|
||||
@ -2216,7 +2216,12 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
|
||||
}
|
||||
|
||||
llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
|
||||
llvm::Type *PtrTy = llvm::PointerType::getUnqual(getLLVMContext());
|
||||
// Ideally, we would like to use GlobalsInt8PtrTy here, however, we cannot,
|
||||
// primarily because the result of applying typeid is a value of type
|
||||
// type_info, which is declared & defined by the standard library
|
||||
// implementation and expects to operate on the generic (default) AS.
|
||||
// https://reviews.llvm.org/D157452 has more context, and a possible solution.
|
||||
llvm::Type *PtrTy = Int8PtrTy;
|
||||
LangAS GlobAS = CGM.GetGlobalVarAddressSpace(nullptr);
|
||||
|
||||
auto MaybeASCast = [=](auto &&TypeInfo) {
|
||||
|
||||
@ -368,7 +368,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
|
||||
IntTy = llvm::IntegerType::get(LLVMContext, C.getTargetInfo().getIntWidth());
|
||||
IntPtrTy = llvm::IntegerType::get(LLVMContext,
|
||||
C.getTargetInfo().getMaxPointerWidth());
|
||||
Int8PtrTy = llvm::PointerType::get(LLVMContext, 0);
|
||||
Int8PtrTy = llvm::PointerType::get(LLVMContext,
|
||||
C.getTargetAddressSpace(LangAS::Default));
|
||||
const llvm::DataLayout &DL = M.getDataLayout();
|
||||
AllocaInt8PtrTy =
|
||||
llvm::PointerType::get(LLVMContext, DL.getAllocaAddrSpace());
|
||||
|
||||
@ -51,7 +51,7 @@ struct CodeGenTypeCache {
|
||||
llvm::IntegerType *PtrDiffTy;
|
||||
};
|
||||
|
||||
/// void*, void** in address space 0
|
||||
/// void*, void** in the target's default address space (often 0)
|
||||
union {
|
||||
llvm::PointerType *UnqualPtrTy;
|
||||
llvm::PointerType *VoidPtrTy;
|
||||
|
||||
@ -1,24 +1,127 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --no-generate-body-for-unused-prefixes --version 4
|
||||
// RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
|
||||
|
||||
struct A { virtual void f(); };
|
||||
struct B : A { };
|
||||
|
||||
// CHECK: {{define.*@_Z1fP1A}}
|
||||
// CHECK-SAME: personality ptr @__gxx_personality_v0
|
||||
B fail;
|
||||
//.
|
||||
// CHECK: @_ZTV1B = linkonce_odr unnamed_addr addrspace(1) constant { [3 x ptr addrspace(1)] } { [3 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTI1B, ptr addrspace(1) addrspacecast (ptr @_ZN1A1fEv to ptr addrspace(1))] }, comdat, align 8
|
||||
// CHECK: @fail = addrspace(1) global { ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2) }, align 8
|
||||
// CHECK: @_ZTI1A = external addrspace(1) constant ptr addrspace(1)
|
||||
// CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external addrspace(1) global [0 x ptr addrspace(1)]
|
||||
// CHECK: @_ZTS1B = linkonce_odr addrspace(1) constant [3 x i8] c"1B\00", comdat, align 1
|
||||
// CHECK: @_ZTI1B = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1B, ptr addrspace(1) @_ZTI1A }, comdat, align 8
|
||||
// CHECK: @__oclc_ABI_version = weak_odr hidden local_unnamed_addr addrspace(4) constant i32 500
|
||||
//.
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZTV1B = linkonce_odr unnamed_addr addrspace(1) constant { [3 x ptr addrspace(1)] } { [3 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTI1B, ptr addrspace(1) addrspacecast (ptr @_ZN1A1fEv to ptr addrspace(1))] }, comdat, align 8
|
||||
// WITH-NONZERO-DEFAULT-AS: @fail = addrspace(1) global { ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2) }, align 8
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZTI1A = external addrspace(1) constant ptr addrspace(1)
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZTVN10__cxxabiv120__si_class_type_infoE = external addrspace(1) global [0 x ptr addrspace(1)]
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZTS1B = linkonce_odr addrspace(1) constant [3 x i8] c"1B\00", comdat, align 1
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZTI1B = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1B, ptr addrspace(1) @_ZTI1A }, comdat, align 8
|
||||
//.
|
||||
// CHECK-LABEL: define dso_local noundef nonnull align 8 dereferenceable(8) ptr @_Z1fP1A(
|
||||
// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 {
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: [[RETVAL:%.*]] = alloca ptr, align 8, addrspace(5)
|
||||
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8, addrspace(5)
|
||||
// CHECK-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8, addrspace(5)
|
||||
// CHECK-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4, addrspace(5)
|
||||
// CHECK-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr
|
||||
// CHECK-NEXT: [[A_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[A_ADDR]] to ptr
|
||||
// CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR_ASCAST]], align 8
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR_ASCAST]], align 8
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = call ptr @__dynamic_cast(ptr [[TMP0]], ptr addrspace(1) @_ZTI1A, ptr addrspace(1) @_ZTI1B, i64 0) #[[ATTR3:[0-9]+]]
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], null
|
||||
// CHECK-NEXT: br i1 [[TMP2]], label [[DYNAMIC_CAST_BAD_CAST:%.*]], label [[DYNAMIC_CAST_END:%.*]]
|
||||
// CHECK: dynamic_cast.bad_cast:
|
||||
// CHECK-NEXT: invoke void @__cxa_bad_cast() #[[ATTR4:[0-9]+]]
|
||||
// CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
|
||||
// CHECK: invoke.cont:
|
||||
// CHECK-NEXT: unreachable
|
||||
// CHECK: dynamic_cast.end:
|
||||
// CHECK-NEXT: br label [[TRY_CONT:%.*]]
|
||||
// CHECK: lpad:
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = landingpad { ptr, i32 }
|
||||
// CHECK-NEXT: catch ptr null
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0
|
||||
// CHECK-NEXT: store ptr [[TMP4]], ptr addrspace(5) [[EXN_SLOT]], align 8
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1
|
||||
// CHECK-NEXT: store i32 [[TMP5]], ptr addrspace(5) [[EHSELECTOR_SLOT]], align 4
|
||||
// CHECK-NEXT: br label [[CATCH:%.*]]
|
||||
// CHECK: catch:
|
||||
// CHECK-NEXT: [[EXN:%.*]] = load ptr, ptr addrspace(5) [[EXN_SLOT]], align 8
|
||||
// CHECK-NEXT: [[TMP6:%.*]] = call ptr @__cxa_begin_catch(ptr [[EXN]]) #[[ATTR3]]
|
||||
// CHECK-NEXT: call void @__cxa_end_catch()
|
||||
// CHECK-NEXT: br label [[TRY_CONT]]
|
||||
// CHECK: try.cont:
|
||||
// CHECK-NEXT: ret ptr addrspacecast (ptr addrspace(1) @fail to ptr)
|
||||
//
|
||||
// WITH-NONZERO-DEFAULT-AS-LABEL: define spir_func noundef align 8 dereferenceable(8) ptr addrspace(4) @_Z1fP1A(
|
||||
// WITH-NONZERO-DEFAULT-AS-SAME: ptr addrspace(4) noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 {
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: entry:
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[RETVAL:%.*]] = alloca ptr addrspace(4), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[A_ADDR:%.*]] = alloca ptr addrspace(4), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[EXN_SLOT:%.*]] = alloca ptr addrspace(4), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr [[RETVAL]] to ptr addrspace(4)
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[A_ADDR_ASCAST:%.*]] = addrspacecast ptr [[A_ADDR]] to ptr addrspace(4)
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: store ptr addrspace(4) [[A]], ptr addrspace(4) [[A_ADDR_ASCAST]], align 8
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[TMP0:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[A_ADDR_ASCAST]], align 8
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[TMP1:%.*]] = call spir_func ptr addrspace(4) @__dynamic_cast(ptr addrspace(4) [[TMP0]], ptr addrspace(1) @_ZTI1A, ptr addrspace(1) @_ZTI1B, i64 0) #[[ATTR3:[0-9]+]]
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[TMP2:%.*]] = icmp eq ptr addrspace(4) [[TMP1]], null
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: br i1 [[TMP2]], label [[DYNAMIC_CAST_BAD_CAST:%.*]], label [[DYNAMIC_CAST_END:%.*]]
|
||||
// WITH-NONZERO-DEFAULT-AS: dynamic_cast.bad_cast:
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: invoke spir_func void @__cxa_bad_cast() #[[ATTR4:[0-9]+]]
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
|
||||
// WITH-NONZERO-DEFAULT-AS: invoke.cont:
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: unreachable
|
||||
// WITH-NONZERO-DEFAULT-AS: dynamic_cast.end:
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: br label [[TRY_CONT:%.*]]
|
||||
// WITH-NONZERO-DEFAULT-AS: lpad:
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[TMP3:%.*]] = landingpad { ptr addrspace(4), i32 }
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: catch ptr addrspace(4) null
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[TMP4:%.*]] = extractvalue { ptr addrspace(4), i32 } [[TMP3]], 0
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: store ptr addrspace(4) [[TMP4]], ptr [[EXN_SLOT]], align 8
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[TMP5:%.*]] = extractvalue { ptr addrspace(4), i32 } [[TMP3]], 1
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: store i32 [[TMP5]], ptr [[EHSELECTOR_SLOT]], align 4
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: br label [[CATCH:%.*]]
|
||||
// WITH-NONZERO-DEFAULT-AS: catch:
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[EXN:%.*]] = load ptr addrspace(4), ptr [[EXN_SLOT]], align 8
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: [[TMP6:%.*]] = call spir_func ptr addrspace(4) @__cxa_begin_catch(ptr addrspace(4) [[EXN]]) #[[ATTR3]]
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: call spir_func void @__cxa_end_catch()
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: br label [[TRY_CONT]]
|
||||
// WITH-NONZERO-DEFAULT-AS: try.cont:
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: ret ptr addrspace(4) addrspacecast (ptr addrspace(1) @fail to ptr addrspace(4))
|
||||
//
|
||||
const B& f(A *a) {
|
||||
try {
|
||||
// CHECK: call ptr @__dynamic_cast
|
||||
// CHECK: br i1
|
||||
// CHECK: invoke void @__cxa_bad_cast() [[NR:#[0-9]+]]
|
||||
dynamic_cast<const B&>(*a);
|
||||
} catch (...) {
|
||||
// CHECK: landingpad { ptr, i32 }
|
||||
// CHECK-NEXT: catch ptr null
|
||||
}
|
||||
return fail;
|
||||
}
|
||||
|
||||
// CHECK: declare ptr @__dynamic_cast(ptr, ptr addrspace(1), ptr addrspace(1), i64) [[NUW_RO:#[0-9]+]]
|
||||
|
||||
// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read) }
|
||||
// CHECK: attributes [[NR]] = { noreturn }
|
||||
//.
|
||||
// CHECK: attributes #[[ATTR0]] = { mustprogress noinline optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
|
||||
// CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind willreturn memory(read) }
|
||||
// CHECK: attributes #[[ATTR2:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
|
||||
// CHECK: attributes #[[ATTR3]] = { nounwind }
|
||||
// CHECK: attributes #[[ATTR4]] = { noreturn }
|
||||
//.
|
||||
// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR0]] = { convergent mustprogress noinline norecurse nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
|
||||
// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR1:[0-9]+]] = { nounwind willreturn memory(read) }
|
||||
// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR2:[0-9]+]] = { convergent nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
|
||||
// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR3]] = { nounwind }
|
||||
// WITH-NONZERO-DEFAULT-AS: attributes #[[ATTR4]] = { noreturn }
|
||||
//.
|
||||
// CHECK: [[META0:![0-9]+]] = !{i32 1, !"amdhsa_code_object_version", i32 500}
|
||||
// CHECK: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
|
||||
// CHECK: [[META2:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
|
||||
//.
|
||||
// WITH-NONZERO-DEFAULT-AS: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
|
||||
// WITH-NONZERO-DEFAULT-AS: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
|
||||
//.
|
||||
|
||||
@ -81,7 +81,7 @@ namespace test5 {
|
||||
// CHECK: invoke void @__cxa_throw(ptr [[EXNOBJ]], ptr @_ZTIN5test51AE, ptr @_ZN5test51AD1Ev) [[NR]]
|
||||
// CHECK-NEXT: to label {{%.*}} unwind label %[[HANDLER:[^ ]*]]
|
||||
// : [[HANDLER]]: (can't check this in Release-Asserts builds)
|
||||
// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(ptr @_ZTIN5test51AE)
|
||||
// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIN5test51AE)
|
||||
}
|
||||
|
||||
namespace test6 {
|
||||
@ -96,7 +96,7 @@ namespace test6 {
|
||||
|
||||
// PR7127
|
||||
namespace test7 {
|
||||
// CHECK-LABEL: define{{.*}} i32 @_ZN5test73fooEv()
|
||||
// CHECK-LABEL: define{{.*}} i32 @_ZN5test73fooEv()
|
||||
// CHECK-SAME: personality ptr @__gxx_personality_v0
|
||||
int foo() {
|
||||
// CHECK: [[CAUGHTEXNVAR:%.*]] = alloca ptr
|
||||
@ -119,7 +119,7 @@ namespace test7 {
|
||||
// CHECK-NEXT: store i32 [[SELECTOR]], ptr [[SELECTORVAR]]
|
||||
// CHECK-NEXT: br label
|
||||
// CHECK: [[SELECTOR:%.*]] = load i32, ptr [[SELECTORVAR]]
|
||||
// CHECK-NEXT: [[T0:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
|
||||
// CHECK-NEXT: [[T0:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
|
||||
// CHECK-NEXT: icmp eq i32 [[SELECTOR]], [[T0]]
|
||||
// CHECK-NEXT: br i1
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr [[CAUGHTEXNVAR]]
|
||||
|
||||
@ -628,7 +628,7 @@ void may_throw();
|
||||
// CHECK-EH-03-NEXT: br label [[CATCH_DISPATCH:%.*]]
|
||||
// CHECK-EH-03: catch.dispatch:
|
||||
// CHECK-EH-03-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4
|
||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTI1X) #[[ATTR7]]
|
||||
// CHECK-EH-03-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTI1X) #[[ATTR7]]
|
||||
// CHECK-EH-03-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]]
|
||||
// CHECK-EH-03-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
|
||||
// CHECK-EH-03: catch:
|
||||
@ -707,7 +707,7 @@ void may_throw();
|
||||
// CHECK-EH-11-NEXT: br label [[CATCH_DISPATCH:%.*]]
|
||||
// CHECK-EH-11: catch.dispatch:
|
||||
// CHECK-EH-11-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4
|
||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTI1X) #[[ATTR6]]
|
||||
// CHECK-EH-11-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTI1X) #[[ATTR6]]
|
||||
// CHECK-EH-11-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[SEL]], [[TMP3]]
|
||||
// CHECK-EH-11-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
|
||||
// CHECK-EH-11: catch:
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -std=c++20 %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple spirv64-unknown-unknown -fsycl-is-device -std=c++20 %s -emit-llvm -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
|
||||
|
||||
struct S { char buf[32]; };
|
||||
template<S s> constexpr const char *begin() { return s.buf; }
|
||||
@ -8,25 +9,34 @@ extern const void *callee(const S*);
|
||||
template<S s> constexpr const void* observable_addr() { return callee(&s); }
|
||||
|
||||
// CHECK: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE]]
|
||||
// WITH-NONZERO-DEFAULT-AS: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE]]
|
||||
// CHECK-SAME: = linkonce_odr addrspace(1) constant { <{ [11 x i8], [21 x i8] }> } { <{ [11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer }> }, comdat
|
||||
|
||||
// CHECK: @p
|
||||
// CHECK-SAME: addrspace(1) global ptr addrspacecast (ptr addrspace(1) [[HELLO]] to ptr)
|
||||
// WITH-NONZERO-DEFAULT-AS: addrspace(1) global ptr addrspace(4) addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4))
|
||||
const char *p = begin<S{"hello world"}>();
|
||||
|
||||
// CHECK: @q
|
||||
// CHECK-SAME: addrspace(1) global ptr addrspacecast (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) [[HELLO]], i64 11) to ptr)
|
||||
// WITH-NONZERO-DEFAULT-AS: addrspace(1) global ptr addrspace(4) addrspacecast (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) [[HELLO]], i64 11) to ptr addrspace(4))
|
||||
const char *q = end<S{"hello world"}>();
|
||||
|
||||
const void *(*r)() = &retval<S{"hello world"}>;
|
||||
|
||||
// CHECK: @s
|
||||
// CHECK-SAME: addrspace(1) global ptr null
|
||||
// WITH-NONZERO-DEFAULT-AS: addrspace(1) global ptr addrspace(4) null
|
||||
const void *s = observable_addr<S{"hello world"}>();
|
||||
|
||||
// CHECK: define linkonce_odr noundef ptr @_Z6retvalIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
|
||||
// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} noundef ptr addrspace(4) @_Z6retvalIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
|
||||
// CHECK: ret ptr addrspacecast (ptr addrspace(1) [[HELLO]] to ptr)
|
||||
// WITH-NONZERO-DEFAULT-AS: ret ptr addrspace(4) addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4))
|
||||
|
||||
// CHECK: define linkonce_odr noundef ptr @_Z15observable_addrIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
|
||||
// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} noundef ptr addrspace(4) @_Z15observable_addrIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
|
||||
// CHECK: %call = call noundef ptr @_Z6calleePK1S(ptr noundef addrspacecast (ptr addrspace(1) [[HELLO]] to ptr))
|
||||
// WITH-NONZERO-DEFAULT-AS: %call = call {{.*}} noundef ptr addrspace(4) @_Z6calleePK1S(ptr addrspace(4) noundef addrspacecast (ptr addrspace(1) [[HELLO]] to ptr addrspace(4)))
|
||||
// CHECK: declare noundef ptr @_Z6calleePK1S(ptr noundef)
|
||||
// WITH-NONZERO-DEFAULT-AS: declare {{.*}} noundef ptr addrspace(4) @_Z6calleePK1S(ptr addrspace(4) noundef)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// RUN: %clang_cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
|
||||
|
||||
struct X {
|
||||
~X();
|
||||
@ -15,3 +16,4 @@ void f() {
|
||||
}
|
||||
|
||||
// CHECK: declare void @__cxa_throw(ptr, ptr addrspace(1), ptr)
|
||||
// WITH-NONZERO-DEFAULT-AS: declare{{.*}} void @__cxa_throw(ptr addrspace(4), ptr addrspace(1), ptr addrspace(4))
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
|
||||
|
||||
struct X { };
|
||||
|
||||
@ -10,7 +11,8 @@ void f() {
|
||||
// CHECK: ptr addrspace(1) @_ZTI1X
|
||||
} catch (const X x) {
|
||||
// CHECK: catch ptr addrspace(1) @_ZTI1X
|
||||
// CHECK: call i32 @llvm.eh.typeid.for(ptr addrspacecast (ptr addrspace(1) @_ZTI1X to ptr))
|
||||
// CHECK: call i32 @llvm.eh.typeid.for.p0(ptr addrspacecast (ptr addrspace(1) @_ZTI1X to ptr))
|
||||
// WITH-NONZERO-DEFAULT-AS: call i32 @llvm.eh.typeid.for.p4(ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTI1X to ptr addrspace(4)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +22,7 @@ void h() {
|
||||
// CHECK: ptr addrspace(1) @_ZTIPKc
|
||||
} catch (char const(&)[4]) {
|
||||
// CHECK: catch ptr addrspace(1) @_ZTIA4_c
|
||||
// CHECK: call i32 @llvm.eh.typeid.for(ptr addrspacecast (ptr addrspace(1) @_ZTIA4_c to ptr))
|
||||
// CHECK: call i32 @llvm.eh.typeid.for.p0(ptr addrspacecast (ptr addrspace(1) @_ZTIA4_c to ptr))
|
||||
// WITH-NONZERO-DEFAULT-AS: call i32 @llvm.eh.typeid.for.p4(ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIA4_c to ptr addrspace(4)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -std=c++11 -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -std=c++11 -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
|
||||
#include <typeinfo>
|
||||
|
||||
namespace Test1 {
|
||||
@ -19,14 +20,17 @@ struct B : virtual A {};
|
||||
struct C { int n; };
|
||||
|
||||
// CHECK: @_ZN5Test15itemsE ={{.*}} constant [4 x {{.*}}] [{{.*}} ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr), {{.*}} @_ZN5Test19make_implINS_1AEEEPvv {{.*}} ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr), {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11CE to ptr), {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} ptr addrspacecast (ptr addrspace(1) @_ZTIi to ptr), {{.*}} @_ZN5Test19make_implIiEEPvv }]
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZN5Test15itemsE ={{.*}} addrspace(1) constant [4 x {{.*}}] [{{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1AEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11CE to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), {{.*}} @_ZN5Test19make_implIiEEPvv }]
|
||||
extern constexpr Item items[] = {
|
||||
item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int")
|
||||
};
|
||||
|
||||
// CHECK: @_ZN5Test11xE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZN5Test11xE ={{.*}} addrspace(1) constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), align 8
|
||||
constexpr auto &x = items[0].ti;
|
||||
|
||||
// CHECK: @_ZN5Test11yE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZN5Test11yE ={{.*}} addrspace(1) constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11BE to ptr addrspace(4)), align 8
|
||||
constexpr auto &y = typeid(B{});
|
||||
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
|
||||
#include <typeinfo>
|
||||
|
||||
namespace Test1 {
|
||||
@ -7,19 +8,23 @@ namespace Test1 {
|
||||
struct A { virtual void f(); };
|
||||
|
||||
// CHECK: @_ZN5Test16int_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIi to ptr), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZN5Test16int_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), align 8
|
||||
const std::type_info &int_ti = typeid(int);
|
||||
|
||||
// CHECK: @_ZN5Test14A_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZN5Test14A_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIN5Test11AE to ptr addrspace(4)), align 8
|
||||
const std::type_info &A_ti = typeid(const volatile A &);
|
||||
|
||||
volatile char c;
|
||||
|
||||
// CHECK: @_ZN5Test14c_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIc to ptr), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZN5Test14c_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIc to ptr addrspace(4)), align 8
|
||||
const std::type_info &c_ti = typeid(c);
|
||||
|
||||
extern const double &d;
|
||||
|
||||
// CHECK: @_ZN5Test14d_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTId to ptr), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZN5Test14d_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTId to ptr addrspace(4)), align 8
|
||||
const std::type_info &d_ti = typeid(d);
|
||||
|
||||
extern A &a;
|
||||
@ -28,18 +33,24 @@ extern A &a;
|
||||
const std::type_info &a_ti = typeid(a);
|
||||
|
||||
// CHECK: @_ZN5Test18A10_c_tiE ={{.*}} constant ptr addrspacecast (ptr addrspace(1) @_ZTIA10_c to ptr), align 8
|
||||
// WITH-NONZERO-DEFAULT-AS: @_ZN5Test18A10_c_tiE ={{.*}} constant ptr addrspace(4) addrspacecast (ptr addrspace(1) @_ZTIA10_c to ptr addrspace(4)), align 8
|
||||
const std::type_info &A10_c_ti = typeid(char const[10]);
|
||||
|
||||
// CHECK-LABEL: define{{.*}} ptr @_ZN5Test11fEv
|
||||
// CHECK-SAME: personality ptr @__gxx_personality_v0
|
||||
// WITH-NONZERO-DEFAULT-AS-LABEL: define{{.*}} ptr addrspace(4) @_ZN5Test11fEv
|
||||
// WITH-NONZERO-DEFAULT-AS-SAME: personality ptr @__gxx_personality_v0
|
||||
const char *f() {
|
||||
try {
|
||||
// CHECK: br i1
|
||||
// CHECK: invoke void @__cxa_bad_typeid() [[NR:#[0-9]+]]
|
||||
// WITH-NONZERO-DEFAULT-AS: invoke{{.*}} void @__cxa_bad_typeid() [[NR:#[0-9]+]]
|
||||
return typeid(*static_cast<A *>(0)).name();
|
||||
} catch (...) {
|
||||
// CHECK: landingpad { ptr, i32 }
|
||||
// CHECK-NEXT: catch ptr null
|
||||
// WITH-NONZERO-DEFAULT-AS: landingpad { ptr addrspace(4), i32 }
|
||||
// WITH-NONZERO-DEFAULT-AS-NEXT: catch ptr addrspace(4) null
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s -check-prefix=AS
|
||||
// RUN: %clang_cc1 -I%S %s -triple spirv64-unknown-unknown -fsycl-is-device -emit-llvm -o - | FileCheck %s -check-prefix=NONZERO-DEFAULT-AS
|
||||
// RUN: %clang_cc1 -I%S %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s -check-prefix=NO-AS
|
||||
#include <typeinfo>
|
||||
|
||||
@ -25,24 +26,30 @@ class B : A {
|
||||
|
||||
unsigned long Fn(B& b) {
|
||||
// AS: %call = call noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr {{.*}} addrspacecast (ptr addrspace(1) @_ZTISt9type_info to ptr), ptr {{.*}} %2)
|
||||
// NONZERO-DEFAULT-AS: %call = call{{.*}} noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTISt9type_info to ptr addrspace(4)), ptr addrspace(4) {{.*}} %2)
|
||||
// NO-AS: %call = call noundef zeroext i1 @_ZNKSt9type_infoeqERKS_(ptr {{.*}} @_ZTISt9type_info, ptr {{.*}} %2)
|
||||
if (typeid(std::type_info) == typeid(b))
|
||||
return 42;
|
||||
// AS: %call2 = call noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr {{.*}} addrspacecast (ptr addrspace(1) @_ZTIi to ptr), ptr {{.*}} %5)
|
||||
// NONZERO-DEFAULT-AS: %call2 = call{{.*}} noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTIi to ptr addrspace(4)), ptr addrspace(4) {{.*}} %5)
|
||||
// NO-AS: %call2 = call noundef zeroext i1 @_ZNKSt9type_infoneERKS_(ptr {{.*}} @_ZTIi, ptr {{.*}} %5)
|
||||
if (typeid(int) != typeid(b))
|
||||
return 1712;
|
||||
// AS: %call5 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} addrspacecast (ptr addrspace(1) @_ZTI1A to ptr))
|
||||
// NONZERO-DEFAULT-AS: %call5 = call{{.*}} noundef ptr addrspace(4) @_ZNKSt9type_info4nameEv(ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTI1A to ptr addrspace(4)))
|
||||
// NO-AS: %call5 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} @_ZTI1A)
|
||||
// AS: %call7 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} %8)
|
||||
// NONZERO-DEFAULT-AS: %call7 = call{{.*}} noundef ptr addrspace(4) @_ZNKSt9type_info4nameEv(ptr addrspace(4) {{.*}} %8)
|
||||
// NO-AS: %call7 = call noundef ptr @_ZNKSt9type_info4nameEv(ptr {{.*}} %8)
|
||||
if (typeid(A).name() == typeid(b).name())
|
||||
return 0;
|
||||
// AS: %call11 = call noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr {{.*}} %11, ptr {{.*}} addrspacecast (ptr addrspace(1) @_ZTIf to ptr))
|
||||
// NONZERO-DEFAULT-AS: %call11 = call{{.*}} noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr addrspace(4) {{.*}} %11, ptr addrspace(4) {{.*}} addrspacecast (ptr addrspace(1) @_ZTIf to ptr addrspace(4)))
|
||||
// NO-AS: %call11 = call noundef zeroext i1 @_ZNKSt9type_info6beforeERKS_(ptr {{.*}} %11, ptr {{.*}} @_ZTIf)
|
||||
if (typeid(b).before(typeid(float)))
|
||||
return 1;
|
||||
// AS: %call15 = call noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr {{.*}} %14)
|
||||
// NONZERO-DEFAULT-AS: %call15 = call{{.*}} noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr addrspace(4) {{.*}} %14)
|
||||
// NO-AS: %call15 = call noundef i64 @_ZNKSt9type_info9hash_codeEv(ptr {{.*}} %14)
|
||||
return typeid(b).hash_code();
|
||||
}
|
||||
|
||||
@ -1,14 +1,17 @@
|
||||
// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -std=c++11 -emit-llvm -o %t.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
|
||||
// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
|
||||
// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o %t.ll -O1 -disable-llvm-passes -fms-extensions -fstrict-vtable-pointers
|
||||
// FIXME: Assume load should not require -fstrict-vtable-pointers
|
||||
|
||||
// RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s
|
||||
// RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s
|
||||
// RUN: FileCheck --check-prefix=CHECK3 --input-file=%t.ll %s
|
||||
// RUN: FileCheck --check-prefix=CHECK4 --input-file=%t.ll %s
|
||||
// RUN: FileCheck --check-prefix=CHECK5 --input-file=%t.ll %s
|
||||
// RUN: FileCheck --check-prefix=CHECK-MS --input-file=%t.ms.ll %s
|
||||
// RUN: FileCheck --check-prefix=CHECK6 --input-file=%t.ll %s
|
||||
// RUN: FileCheck --check-prefix=CHECK7 --input-file=%t.ll %s
|
||||
// RUN: FileCheck --check-prefix=CHECK8 --input-file=%t.ll %s
|
||||
// RUN: FileCheck --check-prefix=CHECK9 --input-file=%t.ll %s
|
||||
namespace test1 {
|
||||
|
||||
struct A {
|
||||
@ -23,8 +26,8 @@ struct B : A {
|
||||
void g(A *a) { a->foo(); }
|
||||
|
||||
// CHECK1-LABEL: define{{.*}} void @_ZN5test14fooAEv()
|
||||
// CHECK1: call void @_ZN5test11AC1Ev(ptr
|
||||
// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}}
|
||||
// CHECK1: call{{.*}} void @_ZN5test11AC1Ev(ptr {{((addrspace(4)){0,1})}}
|
||||
// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}
|
||||
// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11AE, i32 0, i32 0, i32 2)
|
||||
// CHECK1: call void @llvm.assume(i1 %[[CMP]])
|
||||
// CHECK1-LABEL: {{^}}}
|
||||
@ -35,8 +38,8 @@ void fooA() {
|
||||
}
|
||||
|
||||
// CHECK1-LABEL: define{{.*}} void @_ZN5test14fooBEv()
|
||||
// CHECK1: call void @_ZN5test11BC1Ev(ptr {{[^,]*}} %{{.*}})
|
||||
// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}}
|
||||
// CHECK1: call{{.*}} void @_ZN5test11BC1Ev(ptr {{[^,]*}} %{{.*}})
|
||||
// CHECK1: %[[VTABLE:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}
|
||||
// CHECK1: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test11BE, i32 0, i32 0, i32 2)
|
||||
// CHECK1: call void @llvm.assume(i1 %[[CMP]])
|
||||
// CHECK1-LABEL: {{^}}}
|
||||
@ -46,7 +49,7 @@ void fooB() {
|
||||
g(&b);
|
||||
}
|
||||
// there should not be any assumes in the ctor that calls base ctor
|
||||
// CHECK1-LABEL: define linkonce_odr void @_ZN5test11BC2Ev(ptr
|
||||
// CHECK1-LABEL: define linkonce_odr{{.*}} void @_ZN5test11BC2Ev(ptr
|
||||
// CHECK1-NOT: @llvm.assume(
|
||||
// CHECK1-LABEL: {{^}}}
|
||||
}
|
||||
@ -69,17 +72,17 @@ void g(A *a) { a->foo(); }
|
||||
void h(B *b) { b->bar(); }
|
||||
|
||||
// CHECK2-LABEL: define{{.*}} void @_ZN5test24testEv()
|
||||
// CHECK2: call void @_ZN5test21CC1Ev(ptr
|
||||
// CHECK2: call{{.*}} void @_ZN5test21CC1Ev(ptr
|
||||
// CHECK2: %[[VTABLE:.*]] = load ptr addrspace(1), ptr {{.*}}
|
||||
// CHECK2: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 0, i32 2)
|
||||
// CHECK2: call void @llvm.assume(i1 %[[CMP]])
|
||||
|
||||
// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i64 8
|
||||
// CHECK2: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr %[[ADD_PTR]]
|
||||
// CHECK2: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}, i64 8
|
||||
// CHECK2: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%[[ADD_PTR]]
|
||||
// CHECK2: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)], [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test21CE, i32 0, i32 1, i32 2)
|
||||
// CHECK2: call void @llvm.assume(i1 %[[CMP2]])
|
||||
|
||||
// CHECK2: call void @_ZN5test21gEPNS_1AE(
|
||||
// CHECK2: call{{.*}} void @_ZN5test21gEPNS_1AE(
|
||||
// CHECK2-LABEL: {{^}}}
|
||||
|
||||
void test() {
|
||||
@ -106,7 +109,7 @@ struct C : virtual A, B {
|
||||
void g(B *a) { a->foo(); }
|
||||
|
||||
// CHECK3-LABEL: define{{.*}} void @_ZN5test34testEv()
|
||||
// CHECK3: call void @_ZN5test31CC1Ev(ptr
|
||||
// CHECK3: call{{.*}} void @_ZN5test31CC1Ev(ptr
|
||||
// CHECK3: %[[CMP:.*]] = icmp eq ptr addrspace(1) %{{.*}}, getelementptr inbounds inrange(-24, 8) ({ [4 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test31CE, i32 0, i32 0, i32 3)
|
||||
// CHECK3: call void @llvm.assume(i1 %[[CMP]])
|
||||
// CHECK3-LABLEL: }
|
||||
@ -134,12 +137,12 @@ struct C : B {
|
||||
void g(C *c) { c->foo(); }
|
||||
|
||||
// CHECK4-LABEL: define{{.*}} void @_ZN5test44testEv()
|
||||
// CHECK4: call void @_ZN5test41CC1Ev(ptr
|
||||
// CHECK4: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}}
|
||||
// CHECK4: call{{.*}} void @_ZN5test41CC1Ev(ptr
|
||||
// CHECK4: %[[VTABLE:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}
|
||||
// CHECK4: %[[CMP:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4)
|
||||
// CHECK4: call void @llvm.assume(i1 %[[CMP]]
|
||||
|
||||
// CHECK4: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr %{{.*}}
|
||||
// CHECK4: %[[VTABLE2:.*]] = load ptr addrspace(1), ptr {{((addrspace(4)){0,1})}}{{.*}}%{{.*}}
|
||||
// CHECK4: %[[CMP2:.*]] = icmp eq ptr addrspace(1) %[[VTABLE2]], getelementptr inbounds inrange(-32, 8) ({ [5 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTVN5test41CE, i32 0, i32 0, i32 4)
|
||||
// CHECK4: call void @llvm.assume(i1 %[[CMP2]])
|
||||
// CHECK4-LABEL: {{^}}}
|
||||
@ -150,6 +153,27 @@ void test() {
|
||||
}
|
||||
} // test4
|
||||
|
||||
namespace testMS {
|
||||
|
||||
struct __declspec(novtable) S {
|
||||
virtual void foo();
|
||||
};
|
||||
|
||||
void g(S &s) { s.foo(); }
|
||||
|
||||
// if struct has novtable specifier, then we can't generate assumes
|
||||
// CHECK-MS-LABEL: define dso_local void @"?test@testMS@@YAXXZ"()
|
||||
// CHECK-MS: call x86_thiscallcc noundef ptr @"??0S@testMS@@QAE@XZ"(
|
||||
// CHECK-MS-NOT: @llvm.assume
|
||||
// CHECK-MS-LABEL: {{^}}}
|
||||
|
||||
void test() {
|
||||
S s;
|
||||
g(s);
|
||||
}
|
||||
|
||||
} // testMS
|
||||
|
||||
namespace test6 {
|
||||
struct A {
|
||||
A();
|
||||
@ -161,17 +185,17 @@ struct B : A {
|
||||
};
|
||||
// FIXME: Because A's vtable is external, and no virtual functions are hidden,
|
||||
// it's safe to generate assumption loads.
|
||||
// CHECK5-LABEL: define{{.*}} void @_ZN5test61gEv()
|
||||
// CHECK5: call void @_ZN5test61AC1Ev(
|
||||
// CHECK5-NOT: call void @llvm.assume(
|
||||
// CHECK6-LABEL: define{{.*}} void @_ZN5test61gEv()
|
||||
// CHECK6: call{{.*}} void @_ZN5test61AC1Ev(
|
||||
// CHECK6-NOT: call void @llvm.assume(
|
||||
|
||||
// We can't emit assumption loads for B, because if we would refer to vtable
|
||||
// it would refer to functions that will not be able to find (like implicit
|
||||
// inline destructor).
|
||||
|
||||
// CHECK5-LABEL: call void @_ZN5test61BC1Ev(
|
||||
// CHECK5-NOT: call void @llvm.assume(
|
||||
// CHECK5-LABEL: {{^}}}
|
||||
// CHECK6-LABEL: call{{.*}} void @_ZN5test61BC1Ev(
|
||||
// CHECK6-NOT: call void @llvm.assume(
|
||||
// CHECK6-LABEL: {{^}}}
|
||||
void g() {
|
||||
A *a = new A;
|
||||
B *b = new B;
|
||||
@ -180,7 +204,7 @@ void g() {
|
||||
|
||||
namespace test7 {
|
||||
// Because A's key function is defined here, vtable is generated in this TU
|
||||
// CHECK6: @_ZTVN5test71AE ={{.*}} unnamed_addr addrspace(1) constant
|
||||
// CHECK7: @_ZTVN5test71AE ={{.*}} unnamed_addr addrspace(1) constant
|
||||
struct A {
|
||||
A();
|
||||
virtual void foo();
|
||||
@ -188,10 +212,10 @@ struct A {
|
||||
};
|
||||
void A::foo() {}
|
||||
|
||||
// CHECK6-LABEL: define{{.*}} void @_ZN5test71gEv()
|
||||
// CHECK6: call void @_ZN5test71AC1Ev(
|
||||
// CHECK6: call void @llvm.assume(
|
||||
// CHECK6-LABEL: {{^}}}
|
||||
// CHECK7-LABEL: define{{.*}} void @_ZN5test71gEv()
|
||||
// CHECK7: call{{.*}} void @_ZN5test71AC1Ev(
|
||||
// CHECK7: call void @llvm.assume(
|
||||
// CHECK7-LABEL: {{^}}}
|
||||
void g() {
|
||||
A *a = new A();
|
||||
a->bar();
|
||||
@ -205,14 +229,14 @@ struct A {
|
||||
virtual void bar();
|
||||
};
|
||||
|
||||
// CHECK7-DAG: @_ZTVN5test81BE = available_externally unnamed_addr addrspace(1) constant
|
||||
// CHECK8-DAG: @_ZTVN5test81BE = available_externally unnamed_addr addrspace(1) constant
|
||||
struct B : A {
|
||||
B();
|
||||
void foo();
|
||||
void bar();
|
||||
};
|
||||
|
||||
// CHECK7-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr addrspace(1) constant
|
||||
// CHECK8-DAG: @_ZTVN5test81CE = linkonce_odr unnamed_addr addrspace(1) constant
|
||||
struct C : A {
|
||||
C();
|
||||
void bar();
|
||||
@ -227,14 +251,14 @@ struct D : A {
|
||||
};
|
||||
void D::bar() {}
|
||||
|
||||
// CHECK7-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr addrspace(1) constant
|
||||
// CHECK8-DAG: @_ZTVN5test81EE = linkonce_odr unnamed_addr addrspace(1) constant
|
||||
struct E : A {
|
||||
E();
|
||||
};
|
||||
|
||||
// CHECK7-LABEL: define{{.*}} void @_ZN5test81bEv()
|
||||
// CHECK7: call void @llvm.assume(
|
||||
// CHECK7-LABEL: {{^}}}
|
||||
// CHECK8-LABEL: define{{.*}} void @_ZN5test81bEv()
|
||||
// CHECK8: call void @llvm.assume(
|
||||
// CHECK8-LABEL: {{^}}}
|
||||
void b() {
|
||||
B b;
|
||||
b.bar();
|
||||
@ -243,26 +267,26 @@ void b() {
|
||||
// FIXME: C has inline virtual functions which prohibits as from generating
|
||||
// assumption loads, but because vtable is generated in this TU (key function
|
||||
// defined here) it would be correct to refer to it.
|
||||
// CHECK7-LABEL: define{{.*}} void @_ZN5test81cEv()
|
||||
// CHECK7-NOT: call void @llvm.assume(
|
||||
// CHECK7-LABEL: {{^}}}
|
||||
// CHECK8-LABEL: define{{.*}} void @_ZN5test81cEv()
|
||||
// CHECK8-NOT: call void @llvm.assume(
|
||||
// CHECK8-LABEL: {{^}}}
|
||||
void c() {
|
||||
C c;
|
||||
c.bar();
|
||||
}
|
||||
|
||||
// FIXME: We could generate assumption loads here.
|
||||
// CHECK7-LABEL: define{{.*}} void @_ZN5test81dEv()
|
||||
// CHECK7-NOT: call void @llvm.assume(
|
||||
// CHECK7-LABEL: {{^}}}
|
||||
// CHECK8-LABEL: define{{.*}} void @_ZN5test81dEv()
|
||||
// CHECK8-NOT: call void @llvm.assume(
|
||||
// CHECK8-LABEL: {{^}}}
|
||||
void d() {
|
||||
D d;
|
||||
d.bar();
|
||||
}
|
||||
|
||||
// CHECK7-LABEL: define{{.*}} void @_ZN5test81eEv()
|
||||
// CHECK7: call void @llvm.assume(
|
||||
// CHECK7-LABEL: {{^}}}
|
||||
// CHECK8-LABEL: define{{.*}} void @_ZN5test81eEv()
|
||||
// CHECK8: call void @llvm.assume(
|
||||
// CHECK8-LABEL: {{^}}}
|
||||
void e() {
|
||||
E e;
|
||||
e.bar();
|
||||
@ -276,9 +300,9 @@ struct S {
|
||||
__attribute__((visibility("hidden"))) virtual void doStuff();
|
||||
};
|
||||
|
||||
// CHECK8-LABEL: define{{.*}} void @_ZN5test94testEv()
|
||||
// CHECK8-NOT: @llvm.assume(
|
||||
// CHECK8: }
|
||||
// CHECK9-LABEL: define{{.*}} void @_ZN5test94testEv()
|
||||
// CHECK9-NOT: @llvm.assume(
|
||||
// CHECK9: }
|
||||
void test() {
|
||||
S *s = new S();
|
||||
s->doStuff();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -std=c++11 -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
|
||||
|
||||
struct Field {
|
||||
Field();
|
||||
@ -24,6 +25,7 @@ struct A : Base {
|
||||
// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1A, i32 0, i32 0, i32 2)
|
||||
// CHECK: call void @_ZN5FieldC1Ev(
|
||||
// CHECK: ret void
|
||||
// WITH-NONZERO-DEFAULT-AS-LABEL: define{{.*}} void @_ZN1AC2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
|
||||
A::A() { }
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_ZN1AD2Ev(ptr {{[^,]*}} %this) unnamed_addr
|
||||
@ -31,6 +33,7 @@ A::A() { }
|
||||
// CHECK: call void @_ZN5FieldD1Ev(
|
||||
// CHECK: call void @_ZN4BaseD2Ev(
|
||||
// CHECK: ret void
|
||||
// WITH-NONZERO-DEFAULT-AS-LABEL: define{{.*}} void @_ZN1AD2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
|
||||
A::~A() { }
|
||||
|
||||
struct B : Base {
|
||||
@ -43,18 +46,22 @@ void f() { B b; }
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_ZN1BC1Ev(ptr {{[^,]*}} %this) unnamed_addr
|
||||
// CHECK: call void @_ZN1BC2Ev(
|
||||
// WITH-NONZERO-DEFAULT-AS-LABEL: define linkonce_odr{{.*}} void @_ZN1BC1Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_ZN1BD1Ev(ptr {{[^,]*}} %this) unnamed_addr
|
||||
// CHECK: call void @_ZN1BD2Ev(
|
||||
// WITH-NONZERO-DEFAULT-AS-LABEL: define linkonce_odr{{.*}} void @_ZN1BD1Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ev(ptr {{[^,]*}} %this) unnamed_addr
|
||||
// CHECK: call void @_ZN4BaseC2Ev(
|
||||
// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2)
|
||||
// CHECK: call void @_ZN5FieldC1Ev
|
||||
// CHECK: ret void
|
||||
// WITH-NONZERO-DEFAULT-AS-LABEL: define linkonce_odr{{.*}} void @_ZN1BC2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_ZN1BD2Ev(ptr {{[^,]*}} %this) unnamed_addr
|
||||
// CHECK: store ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2)
|
||||
// CHECK: call void @_ZN5FieldD1Ev(
|
||||
// CHECK: call void @_ZN4BaseD2Ev(
|
||||
// CHECK: ret void
|
||||
// WITH-NONZERO-DEFAULT-AS-LABEL: define linkonce_odr{{.*}} void @_ZN1BD2Ev(ptr addrspace(4) {{[^,]*}} %this) unnamed_addr
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -std=c++11 -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 %s -triple=spirv64-unknown-unknown -fsycl-is-device -std=c++11 -emit-llvm -o - | FileCheck %s --check-prefix=WITH-NONZERO-DEFAULT-AS
|
||||
|
||||
// This is the sample from the C++ Itanium ABI, p2.6.2.
|
||||
namespace Test {
|
||||
@ -25,3 +26,9 @@ namespace Test {
|
||||
// CHECK: define linkonce_odr void @_ZN4Test2V2C2Ev(ptr noundef nonnull align 8 dereferenceable(20) %this, ptr addrspace(1) noundef %vtt)
|
||||
// CHECK: define linkonce_odr void @_ZN4Test2C1C2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this, ptr addrspace(1) noundef %vtt)
|
||||
// CHECK: define linkonce_odr void @_ZN4Test2C2C2Ev(ptr noundef nonnull align 8 dereferenceable(12) %this, ptr addrspace(1) noundef %vtt)
|
||||
// WITH-NONZERO-DEFAULT-AS: call {{.*}} void @_ZN4Test2V2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(20) %2, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 11))
|
||||
// WITH-NONZERO-DEFAULT-AS: call {{.*}} void @_ZN4Test2C1C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this1, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 1))
|
||||
// WITH-NONZERO-DEFAULT-AS: call {{.*}} void @_ZN4Test2C2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %3, ptr addrspace(1) noundef getelementptr inbounds ([13 x ptr addrspace(1)], ptr addrspace(1) @_ZTTN4Test1DE, i64 0, i64 3))
|
||||
// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} void @_ZN4Test2V2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(20) %this, ptr addrspace(1) noundef %vtt)
|
||||
// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} void @_ZN4Test2C1C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this, ptr addrspace(1) noundef %vtt)
|
||||
// WITH-NONZERO-DEFAULT-AS: define linkonce_odr {{.*}} void @_ZN4Test2C2C2Ev(ptr addrspace(4) noundef align 8 dereferenceable_or_null(12) %this, ptr addrspace(1) noundef %vtt)
|
||||
|
||||
@ -34,7 +34,7 @@ void test0() {
|
||||
// CHECK-NEXT: %[[EXN:.*]] = call ptr @llvm.wasm.get.exception(token %[[CATCHPAD]])
|
||||
// CHECK-NEXT: store ptr %[[EXN]], ptr %exn.slot
|
||||
// CHECK-NEXT: %[[SELECTOR:.*]] = call i32 @llvm.wasm.get.ehselector(token %[[CATCHPAD]])
|
||||
// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #7
|
||||
// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #7
|
||||
// CHECK-NEXT: %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
|
||||
// CHECK-NEXT: br i1 %[[MATCHES]], label %[[CATCH_INT_BB:.*]], label %[[CATCH_FALLTHROUGH_BB:.*]]
|
||||
|
||||
@ -51,7 +51,7 @@ void test0() {
|
||||
// CHECK-NEXT: br label %[[TRY_CONT_BB:.*]]
|
||||
|
||||
// CHECK: [[CATCH_FALLTHROUGH_BB]]
|
||||
// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTId) #7
|
||||
// CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTId) #7
|
||||
// CHECK-NEXT: %[[MATCHES:.*]] = icmp eq i32 %[[SELECTOR]], %[[TYPEID]]
|
||||
// CHECK-NEXT: br i1 %[[MATCHES]], label %[[CATCH_FLOAT_BB:.*]], label %[[RETHROW_BB:.*]]
|
||||
|
||||
|
||||
@ -1865,7 +1865,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos,
|
||||
|
||||
// llvm.eh.typeid.for intrinsic
|
||||
|
||||
getDeclaration(&module, llvm::Intrinsic::eh_typeid_for);
|
||||
getDeclaration(&module, llvm::Intrinsic::eh_typeid_for, builder.getPtrTy());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1371,7 +1371,7 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
|
||||
|
||||
// The result of eh.typeid.for depends on the enclosing function, but inside a
|
||||
// given function it is 'const' and may be CSE'd etc.
|
||||
def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>;
|
||||
def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty], [IntrNoMem]>;
|
||||
|
||||
def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>;
|
||||
def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>;
|
||||
@ -1730,7 +1730,7 @@ def int_coro_subfn_addr : DefaultAttrsIntrinsic<
|
||||
|
||||
///===-------------------------- Other Intrinsics --------------------------===//
|
||||
//
|
||||
// TODO: We should introduce a new memory kind fo traps (and other side effects
|
||||
// TODO: We should introduce a new memory kind fo traps (and other side effects
|
||||
// we only model to keep things alive).
|
||||
def int_trap : Intrinsic<[], [], [IntrNoReturn, IntrCold, IntrInaccessibleMemOnly,
|
||||
IntrWriteMem]>, ClangBuiltin<"__builtin_trap">;
|
||||
|
||||
@ -44,7 +44,7 @@ lpad: ; preds = %entry
|
||||
; CHECK-NEXT: %[[CDR:.*]] = extractvalue { ptr, i32 } %[[IVI2]], 1
|
||||
|
||||
catch.dispatch: ; preds = %lpad
|
||||
%3 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
|
||||
%3 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
|
||||
%matches = icmp eq i32 %2, %3
|
||||
br i1 %matches, label %catch1, label %catch
|
||||
; CHECK: catch.dispatch:
|
||||
@ -139,7 +139,7 @@ lpad: ; preds = %entry
|
||||
br label %catch.dispatch
|
||||
|
||||
catch.dispatch: ; preds = %lpad
|
||||
%4 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
|
||||
%4 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
|
||||
%matches = icmp eq i32 %3, %4
|
||||
br i1 %matches, label %catch1, label %catch
|
||||
|
||||
@ -162,7 +162,7 @@ declare void @foo(i32)
|
||||
declare ptr @bar(i8, i8)
|
||||
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
declare i32 @llvm.eh.typeid.for(ptr)
|
||||
declare i32 @llvm.eh.typeid.for.p0(ptr)
|
||||
declare ptr @__cxa_begin_catch(ptr)
|
||||
declare void @__cxa_end_catch()
|
||||
declare void @__cxa_call_unexpected(ptr)
|
||||
|
||||
@ -292,7 +292,7 @@ define i32 @foo2(ptr nocapture readonly %i) local_unnamed_addr personality ptr @
|
||||
; CHECK-NEXT: [[BC1:%.*]] = add i32 [[TMP0]], 10
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #[[ATTR1]]
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #[[ATTR1]]
|
||||
; CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP4]], [[TMP5]]
|
||||
; CHECK-NEXT: [[BC7:%.*]] = add i32 [[TMP0]], 10
|
||||
; CHECK-NEXT: [[TMP6:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP3]]) #[[ATTR1]]
|
||||
@ -340,7 +340,7 @@ lpad:
|
||||
%bc1 = add i32 %0, 10
|
||||
%3 = extractvalue { ptr, i32 } %2, 0
|
||||
%4 = extractvalue { ptr, i32 } %2, 1
|
||||
%5 = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #2
|
||||
%5 = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #2
|
||||
%matches = icmp eq i32 %4, %5
|
||||
%bc7 = add i32 %0, 10
|
||||
%6 = tail call ptr @__cxa_begin_catch(ptr %3) #2
|
||||
@ -383,7 +383,7 @@ declare void @__cxa_throw(ptr, ptr, ptr) local_unnamed_addr
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
|
||||
; Function Attrs: nounwind readnone
|
||||
declare i32 @llvm.eh.typeid.for(ptr) #1
|
||||
declare i32 @llvm.eh.typeid.for.p0(ptr) #1
|
||||
|
||||
declare ptr @__cxa_begin_catch(ptr) local_unnamed_addr
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ declare void @use(i32) nounwind
|
||||
|
||||
declare void @opaque()
|
||||
|
||||
declare i32 @llvm.eh.typeid.for(ptr) nounwind
|
||||
declare i32 @llvm.eh.typeid.for.p0(ptr) nounwind
|
||||
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
|
||||
@ -74,7 +74,7 @@ lpad: ; preds = %entry
|
||||
catch ptr @_ZTIi
|
||||
%eh.exc = extractvalue { ptr, i32 } %exn, 0
|
||||
%eh.selector = extractvalue { ptr, i32 } %exn, 1
|
||||
%0 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) nounwind
|
||||
%0 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) nounwind
|
||||
%1 = icmp eq i32 %eh.selector, %0
|
||||
br i1 %1, label %catch, label %eh.resume
|
||||
|
||||
@ -109,7 +109,7 @@ eh.resume:
|
||||
; CHECK-NEXT: phi { ptr, i32 } [
|
||||
; CHECK-NEXT: extractvalue { ptr, i32 }
|
||||
; CHECK-NEXT: extractvalue { ptr, i32 }
|
||||
; CHECK-NEXT: call i32 @llvm.eh.typeid.for(
|
||||
; CHECK-NEXT: call i32 @llvm.eh.typeid.for.p0(
|
||||
|
||||
|
||||
;; Test 1 - Correctly handle phis in outer landing pads.
|
||||
@ -133,7 +133,7 @@ lpad:
|
||||
catch ptr @_ZTIi
|
||||
%eh.exc = extractvalue { ptr, i32 } %exn, 0
|
||||
%eh.selector = extractvalue { ptr, i32 } %exn, 1
|
||||
%0 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) nounwind
|
||||
%0 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) nounwind
|
||||
%1 = icmp eq i32 %eh.selector, %0
|
||||
br i1 %1, label %catch, label %eh.resume
|
||||
|
||||
@ -212,7 +212,7 @@ eh.resume:
|
||||
; CHECK-NEXT: [[EXNJ1:%.*]] = phi { ptr, i32 } [ [[EXNJ2]], %[[LPAD_JOIN2]] ], [ [[LPADVAL1]], %[[RESUME1]] ]
|
||||
; CHECK-NEXT: extractvalue { ptr, i32 } [[EXNJ1]], 0
|
||||
; CHECK-NEXT: [[SELJ1:%.*]] = extractvalue { ptr, i32 } [[EXNJ1]], 1
|
||||
; CHECK-NEXT: [[T:%.*]] = call i32 @llvm.eh.typeid.for(
|
||||
; CHECK-NEXT: [[T:%.*]] = call i32 @llvm.eh.typeid.for.p0(
|
||||
; CHECK-NEXT: icmp eq i32 [[SELJ1]], [[T]]
|
||||
|
||||
; CHECK: call void @use(i32 [[XJ1]])
|
||||
|
||||
@ -304,7 +304,7 @@ define void @loop_within_tryblock() personality ptr @__gxx_personality_v0 {
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
|
||||
; CHECK-NEXT: br label [[CATCH_DISPATCH:%.*]]
|
||||
; CHECK: catch.dispatch:
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
|
||||
; CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]
|
||||
; CHECK-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
|
||||
; CHECK: catch:
|
||||
@ -355,7 +355,7 @@ lpad:
|
||||
br label %catch.dispatch
|
||||
|
||||
catch.dispatch:
|
||||
%4 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #3
|
||||
%4 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #3
|
||||
%matches = icmp eq i32 %3, %4
|
||||
br i1 %matches, label %catch, label %eh.resume
|
||||
|
||||
@ -564,6 +564,6 @@ declare ptr @__cxa_begin_catch(ptr)
|
||||
|
||||
declare void @__cxa_end_catch()
|
||||
|
||||
declare i32 @llvm.eh.typeid.for(ptr)
|
||||
declare i32 @llvm.eh.typeid.for.p0(ptr)
|
||||
|
||||
declare void @f() uwtable
|
||||
|
||||
@ -65,7 +65,7 @@ lpad: ; preds = %cfi.cont
|
||||
%1 = landingpad { ptr, i32 }
|
||||
catch ptr @_ZTIi
|
||||
%2 = extractvalue { ptr, i32 } %1, 1
|
||||
%3 = tail call i32 @llvm.eh.typeid.for(ptr nonnull @_ZTIi) #5
|
||||
%3 = tail call i32 @llvm.eh.typeid.for.p0(ptr nonnull @_ZTIi) #5
|
||||
%matches = icmp eq i32 %2, %3
|
||||
br i1 %matches, label %catch, label %eh.resume
|
||||
|
||||
@ -90,7 +90,7 @@ declare void @__cfi_slowpath(i64, ptr) local_unnamed_addr
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
|
||||
; Function Attrs: nofree nosync nounwind memory(none)
|
||||
declare i32 @llvm.eh.typeid.for(ptr) #2
|
||||
declare i32 @llvm.eh.typeid.for.p0(ptr) #2
|
||||
|
||||
declare ptr @__cxa_begin_catch(ptr) local_unnamed_addr
|
||||
|
||||
@ -181,7 +181,7 @@ attributes #8 = { noreturn nounwind }
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 }
|
||||
; CHECK-NEXT: catch ptr @_ZTIi
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr nonnull @_ZTIi) #[[ATTR6]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr nonnull @_ZTIi) #[[ATTR6]]
|
||||
; CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP1]], [[TMP2]]
|
||||
; CHECK-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]]
|
||||
; CHECK: catch:
|
||||
|
||||
@ -10,7 +10,7 @@ declare void @_Z4barv()
|
||||
|
||||
declare void @_Z7cleanupv()
|
||||
|
||||
declare i32 @llvm.eh.typeid.for(ptr) nounwind readonly
|
||||
declare i32 @llvm.eh.typeid.for.p0(ptr) nounwind readonly
|
||||
|
||||
declare ptr @__cxa_begin_catch(ptr) nounwind
|
||||
|
||||
@ -32,11 +32,11 @@ define void @_Z3foov() uwtable personality ptr @__gxx_personality_v0 {
|
||||
; CHECK-NEXT: catch ptr @_ZTIb
|
||||
; CHECK-NEXT: [[EXC_PTR2_I:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0
|
||||
; CHECK-NEXT: [[FILTER3_I:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
|
||||
; CHECK-NEXT: [[TYPEID_I:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
|
||||
; CHECK-NEXT: [[TYPEID_I:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[FILTER3_I]], [[TYPEID_I]]
|
||||
; CHECK-NEXT: br i1 [[TMP1]], label [[PPAD:%.*]], label [[NEXT:%.*]]
|
||||
; CHECK: next:
|
||||
; CHECK-NEXT: [[TYPEID1_I:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIb)
|
||||
; CHECK-NEXT: [[TYPEID1_I:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIb)
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[FILTER3_I]], [[TYPEID1_I]]
|
||||
; CHECK-NEXT: br i1 [[TMP2]], label [[PPAD2:%.*]], label [[NEXT2:%.*]]
|
||||
; CHECK: ppad:
|
||||
@ -77,12 +77,12 @@ lpad: ; preds = %entry
|
||||
catch ptr @_ZTIb
|
||||
%exc_ptr2.i = extractvalue { ptr, i32 } %0, 0
|
||||
%filter3.i = extractvalue { ptr, i32 } %0, 1
|
||||
%typeid.i = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
|
||||
%typeid.i = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
|
||||
%1 = icmp eq i32 %filter3.i, %typeid.i
|
||||
br i1 %1, label %ppad, label %next
|
||||
|
||||
next: ; preds = %lpad
|
||||
%typeid1.i = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIb)
|
||||
%typeid1.i = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIb)
|
||||
%2 = icmp eq i32 %filter3.i, %typeid1.i
|
||||
br i1 %2, label %ppad2, label %next2
|
||||
|
||||
@ -98,12 +98,12 @@ ppad2: ; preds = %next
|
||||
|
||||
next2: ; preds = %next
|
||||
call void @_Z7cleanupv()
|
||||
%typeid = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
|
||||
%typeid = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
|
||||
%4 = icmp eq i32 %filter3.i, %typeid
|
||||
br i1 %4, label %ppad3, label %next3
|
||||
|
||||
next3: ; preds = %next2
|
||||
%typeid1 = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIb)
|
||||
%typeid1 = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIb)
|
||||
%5 = icmp eq i32 %filter3.i, %typeid1
|
||||
br i1 %5, label %ppad4, label %unwind
|
||||
|
||||
|
||||
@ -635,7 +635,7 @@ def LLVM_VaEndOp : LLVM_ZeroResultIntrOp<"vaend", [0]>,
|
||||
// Exception handling intrinsics.
|
||||
//
|
||||
|
||||
def LLVM_EhTypeidForOp : LLVM_OneResultIntrOp<"eh.typeid.for"> {
|
||||
def LLVM_EhTypeidForOp : LLVM_OneResultIntrOp<"eh.typeid.for", [], [0]> {
|
||||
let arguments = (ins LLVM_AnyPointer:$type_info);
|
||||
let assemblyFormat = "$type_info attr-dict `:` functional-type(operands, results)";
|
||||
}
|
||||
|
||||
@ -732,7 +732,7 @@ define void @coro_promise(ptr %0, i32 %1, i1 %2) {
|
||||
; CHECK-LABEL: llvm.func @eh_typeid_for
|
||||
define void @eh_typeid_for(ptr %0) {
|
||||
; CHECK: llvm.intr.eh.typeid.for %{{.*}} : (!llvm.ptr) -> i32
|
||||
%2 = call i32 @llvm.eh.typeid.for(ptr %0)
|
||||
%2 = call i32 @llvm.eh.typeid.for.p0(ptr %0)
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -1082,7 +1082,7 @@ declare i1 @llvm.coro.end(ptr, i1, token)
|
||||
declare ptr @llvm.coro.free(token, ptr nocapture readonly)
|
||||
declare void @llvm.coro.resume(ptr)
|
||||
declare ptr @llvm.coro.promise(ptr nocapture, i32, i1)
|
||||
declare i32 @llvm.eh.typeid.for(ptr)
|
||||
declare i32 @llvm.eh.typeid.for.p0(ptr)
|
||||
declare ptr @llvm.stacksave.p0()
|
||||
declare ptr addrspace(1) @llvm.stacksave.p1()
|
||||
declare void @llvm.stackrestore.p0(ptr)
|
||||
|
||||
@ -724,7 +724,7 @@ llvm.func @coro_promise(%arg0: !llvm.ptr, %arg1 : i32, %arg2 : i1) {
|
||||
|
||||
// CHECK-LABEL: @eh_typeid_for
|
||||
llvm.func @eh_typeid_for(%arg0 : !llvm.ptr) {
|
||||
// CHECK: call i32 @llvm.eh.typeid.for
|
||||
// CHECK: call i32 @llvm.eh.typeid.for.p0
|
||||
%0 = llvm.intr.eh.typeid.for %arg0 : (!llvm.ptr) -> i32
|
||||
llvm.return
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user