This PR relands [#122992](https://github.com/llvm/llvm-project/pull/122992). Some machines were failing to run the `reflect-error.ll` test due to the RUN lines ```llvm ; RUN: not %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o /dev/null 2>&1 -filetype=obj %} ; RUN: not %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o /dev/null 2>&1 -filetype=obj %} ``` which failed when `spirv-tools` was not present on the machine due to running the command `not` without any arguments. These RUN lines have been removed since they don't actually test anything new compared to the other two RUN lines due to the expected error during instruction selection. ```llvm ; RUN: not llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o /dev/null 2>&1 | FileCheck %s ; RUN: not llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o /dev/null 2>&1 | FileCheck %s ```
108 lines
3.4 KiB
C++
108 lines
3.4 KiB
C++
//===- SemaSPIRV.cpp - Semantic Analysis for SPIRV constructs--------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
// This implements Semantic Analysis for SPIRV constructs.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/Sema/SemaSPIRV.h"
|
|
#include "clang/Basic/TargetBuiltins.h"
|
|
#include "clang/Sema/Sema.h"
|
|
|
|
namespace clang {
|
|
|
|
SemaSPIRV::SemaSPIRV(Sema &S) : SemaBase(S) {}
|
|
|
|
bool SemaSPIRV::CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID,
|
|
CallExpr *TheCall) {
|
|
switch (BuiltinID) {
|
|
case SPIRV::BI__builtin_spirv_distance: {
|
|
if (SemaRef.checkArgCount(TheCall, 2))
|
|
return true;
|
|
|
|
ExprResult A = TheCall->getArg(0);
|
|
QualType ArgTyA = A.get()->getType();
|
|
auto *VTyA = ArgTyA->getAs<VectorType>();
|
|
if (VTyA == nullptr) {
|
|
SemaRef.Diag(A.get()->getBeginLoc(),
|
|
diag::err_typecheck_convert_incompatible)
|
|
<< ArgTyA
|
|
<< SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1
|
|
<< 0 << 0;
|
|
return true;
|
|
}
|
|
|
|
ExprResult B = TheCall->getArg(1);
|
|
QualType ArgTyB = B.get()->getType();
|
|
auto *VTyB = ArgTyB->getAs<VectorType>();
|
|
if (VTyB == nullptr) {
|
|
SemaRef.Diag(A.get()->getBeginLoc(),
|
|
diag::err_typecheck_convert_incompatible)
|
|
<< ArgTyB
|
|
<< SemaRef.Context.getVectorType(ArgTyB, 2, VectorKind::Generic) << 1
|
|
<< 0 << 0;
|
|
return true;
|
|
}
|
|
|
|
QualType RetTy = VTyA->getElementType();
|
|
TheCall->setType(RetTy);
|
|
break;
|
|
}
|
|
case SPIRV::BI__builtin_spirv_length: {
|
|
if (SemaRef.checkArgCount(TheCall, 1))
|
|
return true;
|
|
ExprResult A = TheCall->getArg(0);
|
|
QualType ArgTyA = A.get()->getType();
|
|
auto *VTy = ArgTyA->getAs<VectorType>();
|
|
if (VTy == nullptr) {
|
|
SemaRef.Diag(A.get()->getBeginLoc(),
|
|
diag::err_typecheck_convert_incompatible)
|
|
<< ArgTyA
|
|
<< SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1
|
|
<< 0 << 0;
|
|
return true;
|
|
}
|
|
QualType RetTy = VTy->getElementType();
|
|
TheCall->setType(RetTy);
|
|
break;
|
|
}
|
|
case SPIRV::BI__builtin_spirv_reflect: {
|
|
if (SemaRef.checkArgCount(TheCall, 2))
|
|
return true;
|
|
|
|
ExprResult A = TheCall->getArg(0);
|
|
QualType ArgTyA = A.get()->getType();
|
|
auto *VTyA = ArgTyA->getAs<VectorType>();
|
|
if (VTyA == nullptr) {
|
|
SemaRef.Diag(A.get()->getBeginLoc(),
|
|
diag::err_typecheck_convert_incompatible)
|
|
<< ArgTyA
|
|
<< SemaRef.Context.getVectorType(ArgTyA, 2, VectorKind::Generic) << 1
|
|
<< 0 << 0;
|
|
return true;
|
|
}
|
|
|
|
ExprResult B = TheCall->getArg(1);
|
|
QualType ArgTyB = B.get()->getType();
|
|
auto *VTyB = ArgTyB->getAs<VectorType>();
|
|
if (VTyB == nullptr) {
|
|
SemaRef.Diag(A.get()->getBeginLoc(),
|
|
diag::err_typecheck_convert_incompatible)
|
|
<< ArgTyB
|
|
<< SemaRef.Context.getVectorType(ArgTyB, 2, VectorKind::Generic) << 1
|
|
<< 0 << 0;
|
|
return true;
|
|
}
|
|
|
|
QualType RetTy = ArgTyA;
|
|
TheCall->setType(RetTy);
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
} // namespace clang
|