blob: efc5cf7e5481ba66dea144020f4d14ef380942c0 [file] [log] [blame]
// Copyright (c) 2019 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "gmock/gmock.h"
#include "test/link/linker_fixture.h"
namespace spvtools {
namespace {
using TypeMatch = spvtest::LinkerTest;
// Basic types
#define PartInt(D, N) D(N) " = OpTypeInt 32 0"
#define PartFloat(D, N) D(N) " = OpTypeFloat 32"
#define PartOpaque(D, N) D(N) " = OpTypeOpaque \"bar\""
#define PartSampler(D, N) D(N) " = OpTypeSampler"
#define PartEvent(D, N) D(N) " = OpTypeEvent"
#define PartDeviceEvent(D, N) D(N) " = OpTypeDeviceEvent"
#define PartReserveId(D, N) D(N) " = OpTypeReserveId"
#define PartQueue(D, N) D(N) " = OpTypeQueue"
#define PartPipe(D, N) D(N) " = OpTypePipe ReadWrite"
#define PartPipeStorage(D, N) D(N) " = OpTypePipeStorage"
#define PartNamedBarrier(D, N) D(N) " = OpTypeNamedBarrier"
// Compound types
#define PartVector(DR, DA, N, T) DR(N) " = OpTypeVector " DA(T) " 3"
#define PartMatrix(DR, DA, N, T) DR(N) " = OpTypeMatrix " DA(T) " 4"
#define PartImage(DR, DA, N, T) \
DR(N) " = OpTypeImage " DA(T) " 2D 0 0 0 0 Rgba32f"
#define PartSampledImage(DR, DA, N, T) DR(N) " = OpTypeSampledImage " DA(T)
#define PartArray(DR, DA, N, T) DR(N) " = OpTypeArray " DA(T) " " DA(const)
#define PartRuntimeArray(DR, DA, N, T) DR(N) " = OpTypeRuntimeArray " DA(T)
#define PartStruct(DR, DA, N, T) DR(N) " = OpTypeStruct " DA(T) " " DA(T)
#define PartPointer(DR, DA, N, T) DR(N) " = OpTypePointer Workgroup " DA(T)
#define PartFunction(DR, DA, N, T) DR(N) " = OpTypeFunction " DA(T) " " DA(T)
#define CheckDecoRes(S) "[[" #S ":%\\w+]]"
#define CheckDecoArg(S) "[[" #S "]]"
#define InstDeco(S) "%" #S
#define MatchPart1(F, N) \
"; CHECK: " Part##F(CheckDecoRes, N) "\n" Part##F(InstDeco, N) "\n"
#define MatchPart2(F, N, T) \
"; CHECK: " Part##F(CheckDecoRes, CheckDecoArg, N, T) "\n" Part##F( \
InstDeco, InstDeco, N, T) "\n"
#define MatchF(N, CODE) \
TEST_F(TypeMatch, N) { \
const std::string base = \
"OpCapability Linkage\n" \
"OpCapability NamedBarrier\n" \
"OpCapability PipeStorage\n" \
"OpCapability Pipes\n" \
"OpCapability DeviceEnqueue\n" \
"OpCapability Kernel\n" \
"OpCapability Shader\n" \
"OpCapability Addresses\n" \
"OpMemoryModel Physical64 OpenCL\n" \
"OpDecorate %var LinkageAttributes \"foo\" " \
"{Import,Export}\n" \
"; CHECK: [[baseint:%\\w+]] = OpTypeInt 32 1\n" \
"%baseint = OpTypeInt 32 1\n" \
"; CHECK: [[const:%\\w+]] = OpConstant [[baseint]] 3\n" \
"%const = OpConstant %baseint 3\n" CODE \
"; CHECK: OpVariable [[type]] Uniform\n" \
"%var = OpVariable %type Uniform"; \
ExpandAndMatch(base); \
}
#define Match1(T) MatchF(Type##T, MatchPart1(T, type))
#define Match2(T, A) \
MatchF(T##OfType##A, MatchPart1(A, a) MatchPart2(T, type, a))
#define Match3(T, A, B) \
MatchF(T##Of##A##Of##B, \
MatchPart1(B, b) MatchPart2(A, a, b) MatchPart2(T, type, a))
// clang-format off
// Basic types
Match1(Int)
Match1(Float)
Match1(Opaque)
Match1(Sampler)
Match1(Event)
Match1(DeviceEvent)
Match1(ReserveId)
Match1(Queue)
Match1(Pipe)
Match1(PipeStorage)
Match1(NamedBarrier)
// Simpler (restricted) compound types
Match2(Vector, Float)
Match3(Matrix, Vector, Float)
Match2(Image, Float)
// Unrestricted compound types
#define MatchCompounds1(A) \
Match2(RuntimeArray, A) \
Match2(Struct, A) \
Match2(Pointer, A) \
Match2(Function, A) \
Match2(Array, A)
#define MatchCompounds2(A, B) \
Match3(RuntimeArray, A, B) \
Match3(Struct, A, B) \
Match3(Pointer, A, B) \
Match3(Function, A, B) \
Match3(Array, A, B)
MatchCompounds1(Float)
MatchCompounds2(Array, Float)
MatchCompounds2(RuntimeArray, Float)
MatchCompounds2(Struct, Float)
MatchCompounds2(Pointer, Float)
MatchCompounds2(Function, Float)
// clang-format on
// ForwardPointer tests, which don't fit into the previous mold
#define MatchFpF(N, CODE) \
MatchF(N, \
"; CHECK: OpTypeForwardPointer [[type:%\\w+]] Workgroup\n" \
"OpTypeForwardPointer %type Workgroup\n" CODE \
"; CHECK: [[type]] = OpTypePointer Workgroup [[realtype]]\n" \
"%type = OpTypePointer Workgroup %realtype\n")
#define MatchFp1(T) MatchFpF(ForwardPointerOf##T, MatchPart1(T, realtype))
#define MatchFp2(T, A) \
MatchFpF(ForwardPointerOf##T, MatchPart1(A, a) MatchPart2(T, realtype, a))
// clang-format off
MatchFp1(Float)
MatchFp2(Array, Float)
MatchFp2(RuntimeArray, Float)
MatchFp2(Struct, Float)
MatchFp2(Function, Float)
// clang-format on
} // namespace
} // namespace spvtools