Skip to content

Commit 5ba6cb8

Browse files
gandhi56David Salinas
authored andcommitted
[CUDA] Increment VTable index for device thunks (llvm#124989)
Currently, the clang frontend incorrectly emits the callee instead of the thunk for the callee in the VTable. This is the case because the thunk index is not incremented when their callees cannot be emitted. This patch fixes the bug.
1 parent 499cece commit 5ba6cb8

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

clang/lib/CodeGen/CGVTables.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,10 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
771771
case VTableComponent::CK_DeletingDtorPointer: {
772772
GlobalDecl GD = component.getGlobalDecl();
773773

774+
const bool IsThunk =
775+
nextVTableThunkIndex < layout.vtable_thunks().size() &&
776+
layout.vtable_thunks()[nextVTableThunkIndex].first == componentIndex;
777+
774778
if (CGM.getLangOpts().CUDA) {
775779
// Emit NULL for methods we can't codegen on this
776780
// side. Otherwise we'd end up with vtable with unresolved
@@ -782,9 +786,12 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
782786
CGM.getLangOpts().CUDAIsDevice
783787
? MD->hasAttr<CUDADeviceAttr>()
784788
: (MD->hasAttr<CUDAHostAttr>() || !MD->hasAttr<CUDADeviceAttr>());
785-
if (!CanEmitMethod)
789+
if (!CanEmitMethod) {
790+
if (IsThunk)
791+
nextVTableThunkIndex++;
786792
return builder.add(
787793
llvm::ConstantExpr::getNullValue(CGM.GlobalsInt8PtrTy));
794+
}
788795
// Method is acceptable, continue processing as usual.
789796
}
790797

@@ -830,9 +837,7 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
830837
fnPtr = DeletedVirtualFn;
831838

832839
// Thunks.
833-
} else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
834-
layout.vtable_thunks()[nextVTableThunkIndex].first ==
835-
componentIndex) {
840+
} else if (IsThunk) {
836841
auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second;
837842

838843
nextVTableThunkIndex++;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %clang_cc1 -fcuda-is-device -triple amdgcn-amd-amdhsa -target-cpu gfx942 \
2+
// RUN: -emit-llvm -xhip %s -o - | FileCheck %s --check-prefix=GCN
3+
// RUN: %clang_cc1 -fcuda-is-device -triple spirv64-amd-amdhsa \
4+
// RUN: -emit-llvm -xhip %s -o - | FileCheck %s --check-prefix=SPIRV
5+
6+
// GCN: @_ZTV1C = linkonce_odr unnamed_addr addrspace(1) constant { [5 x ptr addrspace(1)], [4 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZN1B2f2Ev to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZN1C2f1Ev to ptr addrspace(1))], [4 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -8 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @_ZThn8_N1C2f1Ev to ptr addrspace(1))] }, comdat, align 8
7+
// GCN: @_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) null, ptr addrspace(1) addrspacecast (ptr @_ZN1B2f2Ev to ptr addrspace(1))] }, comdat, align 8
8+
// GCN: @_ZTV1A = linkonce_odr unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr @__cxa_pure_virtual to ptr addrspace(1))] }, comdat, align 8
9+
// SPIRV: @_ZTV1C = linkonce_odr unnamed_addr addrspace(1) constant { [5 x ptr addrspace(1)], [4 x ptr addrspace(1)] } { [5 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1B2f2Ev to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1C2f1Ev to ptr addrspace(1))], [4 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -8 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZThn8_N1C2f1Ev to ptr addrspace(1))] }, comdat, align 8
10+
// SPIRV: @_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) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1B2f2Ev to ptr addrspace(1))] }, comdat, align 8
11+
// SPIRV: @_ZTV1A = linkonce_odr unnamed_addr addrspace(1) constant { [4 x ptr addrspace(1)] } { [4 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) addrspacecast (ptr addrspace(4) @__cxa_pure_virtual to ptr addrspace(1))] }, comdat, align 8
12+
13+
struct A {
14+
__attribute__((device)) A() { }
15+
virtual void neither_device_nor_host_f() = 0 ;
16+
__attribute__((device)) virtual void f1() = 0;
17+
18+
};
19+
20+
struct B {
21+
__attribute__((device)) B() { }
22+
__attribute__((device)) virtual void f2() { };
23+
};
24+
25+
struct C : public B, public A {
26+
__attribute__((device)) C() : B(), A() { }
27+
28+
virtual void neither_device_nor_host_f() override { }
29+
__attribute__((device)) virtual void f1() override { }
30+
31+
};
32+
33+
__attribute__((device)) void test() {
34+
C obj;
35+
}

0 commit comments

Comments
 (0)