Skip to content

[Clang][CodeGen] Start migrating away from assuming the Default AS is 0 #88182

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
May 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
426e74c
Start migrating away from the embedded assumption that the default AS…
AlexVlx Mar 18, 2024
ad3baf3
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Mar 22, 2024
361af80
Merge branch 'not_all_defaults_are_zero' of https://github.com/AlexVl…
AlexVlx Mar 22, 2024
74ae6f5
Make querying the Global AS more robust, add 1 new test (WiP).
AlexVlx Mar 25, 2024
a873905
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Mar 25, 2024
6e80204
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Mar 26, 2024
98cd6dd
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Mar 27, 2024
4017e92
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 5, 2024
360c0df
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 5, 2024
c0960d7
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 5, 2024
16221fc
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 7, 2024
3848e19
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 9, 2024
b12e6dd
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 9, 2024
ef0bd83
Fix a few additional places where we emit globals in AS 0 implicitly;…
AlexVlx Apr 9, 2024
453e96a
Simplify generic pointer type retrieval.
AlexVlx Apr 9, 2024
6c09621
Fix formatting.
AlexVlx Apr 9, 2024
2549f5a
(Actually) Fix formatting.
AlexVlx Apr 9, 2024
0b3dac3
Delete unnecessary leftover diff.
AlexVlx Apr 9, 2024
4131889
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 16, 2024
c18febe
Roll-back Global generation to use defaults now that #88455 went in.
AlexVlx Apr 16, 2024
0005649
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 16, 2024
5449b65
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 23, 2024
029f690
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 23, 2024
483c8b4
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 23, 2024
d038191
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 23, 2024
64f314f
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 23, 2024
0e19e7d
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 23, 2024
df94ae0
Add comment trying to explain why `typeid` cannot (for now) return a …
AlexVlx Apr 23, 2024
7aeba28
Compact tests.
AlexVlx Apr 24, 2024
65adbb6
Compact more tests, remove redundant ones.
AlexVlx Apr 25, 2024
515f4f9
`llvm.eh.typeid.for` should also be generic.
AlexVlx Apr 25, 2024
fc33ebc
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 25, 2024
0b63586
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx Apr 28, 2024
c64150f
Reword comment.
AlexVlx Apr 28, 2024
2336c75
Fix formatting.
AlexVlx Apr 28, 2024
a3a9b38
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx May 1, 2024
ebdc9e2
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx May 6, 2024
db6b04c
Compact test.
AlexVlx May 7, 2024
6237bee
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx May 7, 2024
3f5c5d3
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx May 7, 2024
8ba6bad
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx May 8, 2024
14250fd
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx May 12, 2024
45ff90d
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx May 12, 2024
6ab0dfc
Merge branch 'main' of https://github.com/llvm/llvm-project into not_…
AlexVlx May 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions clang/lib/CodeGen/CGException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down Expand Up @@ -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);

Expand Down
7 changes: 6 additions & 1 deletion clang/lib/CodeGen/CGExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be GlobalsInt8PtrTy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should but sadly it cannot, see our historical conversation here: https://reviews.llvm.org/D157452. I've not got around to working on your suggestion there about supporting declaring a default AS for a class, so we have to keep things like so for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also find this somewhat surprising. Looking at the discussion that linked review the concern seems to be that you'd end up emitting e.g. ptr addrspace(1) here and users of EmitCXXTypeidLValue do not expect to handle that?

Could you add a comment that the result of this type is used in contexts where the "default" address space is expected. Without the comment I find this very confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done-ish, please let me know if this is not actually helpful in clarifying and I can refine / reword.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO seems like a strange way to phrase this if it's true that this can never be GlobalsInt8PtrTy

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be GlobalsInt8PtrTy, but the main roadblock would require something that @rjmccall suggested looking into, namely adding the ability to declare a default AS for a class type, which stdlib implementations could then re-use. Having said that, I've neither had the time to look into it, nor figured out if this would work in general, considering we need to compose with stdlib implementations other than libc++. Having said that, perhaps the TODO: should actually be at the end of the comment, and just say something along the lines of "investigate if it is possible to remove this limitation"?

LangAS GlobAS = CGM.GetGlobalVarAddressSpace(nullptr);

auto MaybeASCast = [=](auto &&TypeInfo) {
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to cause regressions for HIP -fsanitize=address.

Basically rocm device library for ASAN is compiled from OpenCL source code, for which the default address space is mapped to addr space 5 in IR. Int8PtrTy is used to determine the pointer type in the llvm.compiler.used global array, which causes the pointers in that array to be in addr space 5. However, for HIP those are in addr space 0. The variable from different bitcode are appended together by the linker. The linker checks their type and emits error since they do not match.

https://godbolt.org/z/s48fTj7Pv

Before this change, the pointers are in addr space 0 for both HIP and OpenCL, therefore no such issue.

Copy link
Contributor Author

@AlexVlx AlexVlx May 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be an error on ASAN's side, it's relying on non-guaranteed behaviour and linking BC emanating from different languages with different AS maps. To wit, 0 is private for OCL, so having llvm.used and llvm.compiler.used be global arrays of pointers to private is somewhat suspect (especially since useds are Globals). I will / should fix emitUsed to rely on GlobalsInt8PtrTy, which seems like the right thing to do anyway, but whilst that'll make ASAN "work", it doesn't make ASAN correct, IMHO.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AMDGPU address space mapping is at https://llvm.org/docs/AMDGPUUsage.html#address-spaces and address space 0 is not private. The address space for all languages compiled for the AMDGPU target is consistent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IR address space is a pure target concept. Any address space error would be on the frontend emitting the wrong IR for the target

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing emitUsed probably is a feasible solution, but GlobalsInt8PtrTy will cause the used array containing pointers to addr space 1, which is not backward compatible for HIP. Maybe just use pointer to addr space 0 type as before.

Copy link
Contributor

@arsenm arsenm May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is special case linker code to handle mismatched address spaces for the intrinsic globals, so I don't think changing this would break anything. The address space of llvm.used doesn't really mean anything

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing emitUsed probably is a feasible solution, but GlobalsInt8PtrTy will cause the used array containing pointers to addr space 1, which is not backward compatible for HIP. Maybe just use pointer to addr space 0 type as before.

This would be wrong, assuming that 0 / Unqual is generally equivalent with some form of generic pointer is the core problem here. I'm not exactly sure what you mean by "backward compatible" here though, both the HIP source and whatever BC gets linked should go through the same toolchain, surely? Also, what @arsenm said sounds about right.

Copy link
Contributor Author

@AlexVlx AlexVlx May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IR address space is a pure target concept. Any address space error would be on the frontend emitting the wrong IR for the target

I don't think mixing languages with different LangAS maps is sound, OCL originating BC is not generic BC. There's no "error" here, the FE is doing what is asked of it (indiscriminately assuming that AS 0 is some generic/flat pointer that is valid everywhere is rather risque, as per prior conversation in this review). The actual problem is, AFAICT, that when we call AMDGPUTargetInfo::adjust we indiscriminately set private as default for any and all OCL compilations? There's a 6 year old TODO, which may or may not be vestigial at this point.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think mixing languages with different LangAS maps is sound

It is entirely sound, and required for this entire system to work (e.g. we implement the libraries in OpenCL used by all the languages). The point of the LangAS is to map to the target address space, which does not care what the language is. Different languages should be trying to be ABI compatible with each other, which includes emitting the correct IR address space

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think mixing languages with different LangAS maps is sound

It is entirely sound, and required for this entire system to work

I am aware of what we decided to do. Whether or not that is actually sound is a different kettle of fish, but let's agree to disagree and move on. Stepping back, I'm trying to figure out what the actual suggestion is. Reverting the change is wrong, because there are other targets where for which 0 is definitely not a sound default, and this impacts more than the used/compiler.used arrays. Seems like there are two viable options:

  1. I'm going to propose changing emitUsed anyway, since that makes sense even if the AS is indeed mostly meaningless there
  2. IMHO OCL should default to AMDGPUDefIsGenMap for its LangAS map, which would "fix" this as well.

If there's some third reasonable solution, I apologise for missing it - please share!

C.getTargetAddressSpace(LangAS::Default));
const llvm::DataLayout &DL = M.getDataLayout();
AllocaInt8PtrTy =
llvm::PointerType::get(LLVMContext, DL.getAllocaAddrSpace());
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenTypeCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
123 changes: 113 additions & 10 deletions clang/test/CodeGenCXX/dynamic-cast-address-space.cpp
Original file line number Diff line number Diff line change
@@ -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 {{.*}}"}
//.
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/eh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand All @@ -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]]
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/nrvo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
10 changes: 10 additions & 0 deletions clang/test/CodeGenCXX/template-param-objects-address-space.cpp
Original file line number Diff line number Diff line change
@@ -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; }
Expand All @@ -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)
Original file line number Diff line number Diff line change
@@ -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();
Expand All @@ -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))
7 changes: 5 additions & 2 deletions clang/test/CodeGenCXX/try-catch-with-address-space.cpp
Original file line number Diff line number Diff line change
@@ -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 { };

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

Expand All @@ -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)))
}
}
Loading
Loading