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

Reply via email to