[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:
Alex Voicu 2024-05-19 16:59:03 +03:00 committed by GitHub
parent c587483da0
commit 10edb4991c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 283 additions and 98 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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());

View File

@ -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;

View File

@ -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 {{.*}}"}
//.

View File

@ -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]]

View File

@ -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:

View File

@ -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)

View File

@ -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))

View File

@ -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)))
}
}

View File

@ -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{});
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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();

View File

@ -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

View File

@ -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)

View File

@ -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:.*]]

View File

@ -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());
}

View File

@ -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">;

View File

@ -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)

View File

@ -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

View File

@ -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]])

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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)";
}

View File

@ -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)

View File

@ -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
}