https://github.com/jplehr created https://github.com/llvm/llvm-project/pull/213927
PR https://github.com/llvm/llvm-project/pull/213253 exposed a problem in AMDGPU where exact dynamic_cast optimization would generate compare operands for the compare instruction that live in different address spaces. The culprit appears to have been the introduction of the `final` keyword in the derived struct definition. This patch uses CGF.GetVTablePtr and uses CGM.GlobalsInt8PtrTy in the code for emitExactDynamicCast, following the pattern that is used in EmitTypeid. A test case that was reduced from the above PR is added as test. >From be566748f6adea6600a7809d9e8fdd4353c56595 Mon Sep 17 00:00:00 2001 From: JP Lehr <[email protected]> Date: Tue, 4 Aug 2026 07:44:22 -0500 Subject: [PATCH] [Clang] Make exact dynamic_cast optimization AS aware PR https://github.com/llvm/llvm-project/pull/213253 exposed a problem in AMDGPU where exact dynamic_cast optimization would generate compare operands for the compare instruction that live in different address spaces. The culprit appears to have been the introduction of the `final` keyword in the derived struct definition. This patch uses CGF.GetVTablePtr and uses CGM.GlobalsInt8PtrTy in the code for emitExactDynamicCast, following the pattern that is used in EmitTypeid. A test case that was reduced from the above PR is added as test. --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 4 +-- .../dynamic-cast-exact-address-space.cpp | 27 +++++++++++++++++++ .../ci/openmp-offload-amdgpu-libc-runtime.py | 0 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGenCXX/dynamic-cast-exact-address-space.cpp mode change 100644 => 100755 offload/ci/openmp-offload-amdgpu-libc-runtime.py diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 9ff0c37ca77fc..c9a5f94e28110 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1785,12 +1785,12 @@ llvm::Value *ItaniumCXXABI::emitExactDynamicCast( PerformPostCastAuthentication = CGF.getLangOpts().PointerAuthCalls; CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip, false, false, nullptr); - Address VTablePtrPtr = ThisAddr.withElementType(CGF.VoidPtrPtrTy); + Address VTablePtrPtr = ThisAddr.withElementType(CGM.GlobalsInt8PtrTy); VTable = CGF.Builder.CreateLoad(VTablePtrPtr, "vtable"); if (PerformPostCastAuthentication) VTable = CGF.EmitPointerAuthAuth(StrippingAuthInfo, VTable); } else - VTable = CGF.GetVTablePtr(ThisAddr, CGF.DefaultPtrTy, SrcDecl); + VTable = CGF.GetVTablePtr(ThisAddr, CGM.GlobalsInt8PtrTy, SrcDecl); // Compare the vptr against the expected vptr for the destination type at // this offset. diff --git a/clang/test/CodeGenCXX/dynamic-cast-exact-address-space.cpp b/clang/test/CodeGenCXX/dynamic-cast-exact-address-space.cpp new file mode 100644 index 0000000000000..53ac8292f0d62 --- /dev/null +++ b/clang/test/CodeGenCXX/dynamic-cast-exact-address-space.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -triple amdgpu-amd-amdhsa -emit-llvm -std=c++11 \ +// RUN: -O1 -disable-llvm-passes -fvisibility=hidden -o - | FileCheck %s \ +// RUN: --implicit-check-not='call {{.*}} @__dynamic_cast' + +struct __attribute__((type_visibility("default"))) A { + virtual ~A(); +}; +struct __attribute__((type_visibility("default"))) B final : A {}; + +// CHECK-LABEL: define {{.*}} ptr @_Z4castP1A( +// CHECK: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %{{.*}} +// CHECK: %[[MATCH:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr {{.*}} ptr addrspace(1) @_ZTV1B +B *cast(A *a) { + return dynamic_cast<B *>(a); +} + +struct __attribute__((type_visibility("default"))) Left : A {}; +struct __attribute__((type_visibility("default"))) Right : A {}; +struct __attribute__((type_visibility("default"))) Repeated final : Left, Right {}; + +// CHECK-LABEL: define {{.*}} ptr @_Z13cast_repeatedP1A( +// CHECK: %[[PRIMARY:.*]] = getelementptr inbounds i8, ptr %{{.*}}, i64 %{{.*}} +// CHECK: %[[VTABLE:.*]] = load ptr addrspace(1), ptr %[[PRIMARY]] +// CHECK: %[[MATCH:.*]] = icmp eq ptr addrspace(1) %[[VTABLE]], getelementptr {{.*}} ptr addrspace(1) @_ZTV8Repeated +Repeated *cast_repeated(A *a) { + return dynamic_cast<Repeated *>(a); +} diff --git a/offload/ci/openmp-offload-amdgpu-libc-runtime.py b/offload/ci/openmp-offload-amdgpu-libc-runtime.py old mode 100644 new mode 100755 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
