[clang] [llvm] [Clang] Make exact dynamic_cast optimization AS aware (PR #213927)
Jan Patrick Lehr via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 4 05:53:35 PDT 2026
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 <JanPatrick.Lehr at amd.com>
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
More information about the llvm-commits
mailing list