Skip to content
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

[OpaquePointers] Correctly find leader of EC in type scavenger #2133

Merged
merged 4 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 3 additions & 5 deletions lib/SPIRV/SPIRVTypeScavenger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ Type *SPIRVTypeScavenger::substituteTypeVariables(Type *T) {
}
if (auto Index = isTypeVariable(T)) {
unsigned TypeVarNum = *Index;
TypeVarNum = UnifiedTypeVars.join(TypeVarNum, TypeVarNum);
TypeVarNum = UnifiedTypeVars.findLeader(TypeVarNum);
Type *&SubstTy = TypeVariables[TypeVarNum];
// A value in TypeVariables may itself contain type variables that need to
// be substituted. Substitute these as well.
Expand All @@ -273,9 +273,7 @@ bool SPIRVTypeScavenger::unifyType(Type *T1, Type *T2) {
return true;

auto SetTypeVar = [&](unsigned TypeVarNum, Type *ActualTy) {
// .findLeader doesn't work in uncompressed mode, so use .join with itself
// to find the leader.
unsigned Leader = UnifiedTypeVars.join(TypeVarNum, TypeVarNum);
unsigned Leader = UnifiedTypeVars.findLeader(TypeVarNum);

// This method might be called with T1 as a concrete type containing
// pointers, and we want to make sure those don't leak into type variables.
Expand Down Expand Up @@ -411,7 +409,7 @@ void SPIRVTypeScavenger::typeModule(Module &M) {
// them as an i8* type.
Type *Int8Ty = Type::getInt8Ty(M.getContext());
for (const auto &[TypeVarNum, TypeVar] : enumerate(TypeVariables)) {
unsigned PrimaryVar = UnifiedTypeVars.join(TypeVarNum, TypeVarNum);
unsigned PrimaryVar = UnifiedTypeVars.findLeader(TypeVarNum);
Type *LeaderTy = TypeVariables[PrimaryVar];
if (TypeVar)
TypeVar = substituteTypeVariables(TypeVar);
Expand Down
79 changes: 79 additions & 0 deletions test/type-scavenger/equivalence.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
; Test if llvm-spirv type scavenging has an assertion
; failure due to incorrect lookup of an equivalence class leader.

; RUN: llvm-as < %s | llvm-spirv -o %t.spv
; RUN: spirv-val %t.spv
; RUN: llvm-spirv %t.spv -o - -to-text | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: llvm-spirv %t.spv -o - -r | llvm-dis | FileCheck %s --check-prefix=CHECK-LLVM

; Incorrect lookup of equivalence class leader caused an assertion failure when
; processing call instruction to this name
; CHECK-SPIRV: _func0
; CHECK-LLVM: _func0

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
target triple = "spir64-unknown-unknown"

define spir_func void @_func1() {
entry:
br label %for.cond

for.cond: ; preds = %for.cond, %entry
%call3 = call spir_func ptr addrspace(4) @_func2()
%call5 = call spir_func ptr addrspace(4) @_func0(ptr addrspace(4) %call3, i64 0)
br label %for.cond
}

define spir_func void @_func3() {
entry:
br label %for.cond

for.cond: ; preds = %for.cond, %entry
%call3 = call spir_func ptr @_func4()
%call3.ascast = addrspacecast ptr %call3 to ptr addrspace(4)
%call5 = call spir_func ptr addrspace(4) @_func0(ptr addrspace(4) %call3.ascast, i64 0)
br label %for.cond
}

declare spir_func ptr addrspace(4) @_func5()

define spir_func void @_func6(ptr addrspace(4) %call3.ascast) {
entry:
br label %for.cond

for.cond: ; preds = %for.cond, %entry
%call5 = call spir_func ptr addrspace(4) @_func0(ptr addrspace(4) %call3.ascast, i64 0)
br label %for.cond
}

define spir_func void @_func7() {
entry:
br label %for.cond

for.cond: ; preds = %for.cond, %entry
%call3 = call spir_func ptr addrspace(4) @_func5()
%call5 = call spir_func ptr addrspace(4) @_func0(ptr addrspace(4) %call3, i64 0)
br label %for.cond
}

declare spir_func ptr @_func4()

declare spir_func ptr addrspace(4) @_func2()

define spir_func ptr addrspace(4) @_func0(ptr addrspace(4) %this, i64 %index) {
entry:
%arrayidx = getelementptr [5 x i32], ptr addrspace(4) %this, i64 0, i64 %index
ret ptr addrspace(4) null
}

define spir_func void @_func8() {
entry:
br label %for.cond

for.cond: ; preds = %for.cond, %entry
%call8 = call spir_func ptr addrspace(4) @_func0(ptr addrspace(4) null, i64 0)
br label %for.cond
}

; uselistorder directives
uselistorder ptr @_func0, { 0, 4, 3, 2, 1 }