llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-backend-spir-v Author: None (NeKon69) <details> <summary>Changes</summary> This PR adds `fma` HLSL intrinsic (supports matrices in dxil backend) It follows all of the steps from #<!-- -->99117 and also closes that issue. --- Patch is 32.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/185304.diff 16 Files Affected: - (modified) clang/include/clang/Basic/Builtins.td (+6) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+6) - (modified) clang/lib/CodeGen/CGHLSLBuiltins.cpp (+16) - (modified) clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h (+16) - (modified) clang/lib/Sema/SemaHLSL.cpp (+61) - (added) clang/test/CodeGen/SPIRV/hlsl-intrinsics/fma.ll () - (added) clang/test/CodeGenHLSL/builtins/fma.hlsl (+151) - (added) clang/test/Sema/incompatible-function-to-ptr-decay.c (+18) - (added) clang/test/SemaHLSL/BuiltIns/fma-errors.hlsl (+145) - (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+2) - (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+1-1) - (modified) llvm/lib/Target/DirectX/DXIL.td (+10) - (modified) llvm/lib/Target/DirectX/DXILShaderFlags.cpp (+10-1) - (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+2) - (modified) llvm/test/CodeGen/DirectX/ShaderFlags/double-extensions.ll (+8) - (added) llvm/test/CodeGen/SPIRV/hlsl-intrinsics/fma.ll (+53) ``````````diff diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 531c3702161f2..542249f829424 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -5318,6 +5318,12 @@ def HLSLNormalize : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLFma : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_fma"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + def HLSLRcp : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_elementwise_rcp"]; let Attributes = [NoThrow, Const, CustomTypeChecking]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8882ac9b8c0a8..787cd7bcc61bb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -13229,6 +13229,12 @@ def err_builtin_invalid_arg_type: Error< "%plural{0:|: }3" "%plural{[0,3]:type|:types}1 (was %4)">; +def err_builtin_requires_double_type: Error< + "%ordinal0 argument must be a scalar, vector, or matrix of double type (was %1)">; + +def err_builtin_requires_fp_scalar_or_vector_type: Error< + "%ordinal0 argument must be a scalar or vector of floating-point type (was %1)">; + def err_bswapg_invalid_bit_width : Error< "_BitInt type %0 (%1 bits) must be a multiple of 16 bits for byte swapping">; diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 70891eac39425..bb5eaf12c93cc 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -979,6 +979,22 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, retType, CGM.getHLSLRuntime().getIsNaNIntrinsic(), ArrayRef<Value *>{Op0}, nullptr, "hlsl.isnan"); } + case Builtin::BI__builtin_hlsl_elementwise_fma: { + Value *M = EmitScalarExpr(E->getArg(0)); + Value *A = EmitScalarExpr(E->getArg(1)); + Value *B = EmitScalarExpr(E->getArg(2)); + if (CGM.getTarget().getTriple().isDXIL()) + return Builder.CreateIntrinsic(M->getType(), Intrinsic::dx_fma, + ArrayRef<Value *>{M, A, B}, nullptr, + "dx.fma"); + + if (CGM.getTarget().getTriple().isSPIRV()) + return Builder.CreateIntrinsic(M->getType(), Intrinsic::spv_fma, + ArrayRef<Value *>{M, A, B}, nullptr, + "spv.fma"); + + break; + } case Builtin::BI__builtin_hlsl_mad: { Value *M = EmitScalarExpr(E->getArg(0)); Value *A = EmitScalarExpr(E->getArg(1)); diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h index 2543401bdfbf9..ab5c6edd6d555 100644 --- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h @@ -1891,6 +1891,22 @@ float3 pow(float3, float3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_pow) float4 pow(float4, float4); +//===----------------------------------------------------------------------===// +// fused multiply-add builtins +//===----------------------------------------------------------------------===// + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_fma) +double fma(double, double, double); + +template <int s> +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_fma) +vector<double, s> fma(vector<double, s>, vector<double, s>, vector<double, s>); + +template <int w, int h> +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_fma) +matrix<double, w, h> fma(matrix<double, w, h>, matrix<double, w, h>, + matrix<double, w, h>); + //===----------------------------------------------------------------------===// // reversebits builtins //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 804ea70aaddce..624f621b532a1 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -31,6 +31,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/Ownership.h" #include "clang/Sema/ParsedAttr.h" #include "clang/Sema/Sema.h" #include "clang/Sema/Template.h" @@ -3040,6 +3041,36 @@ static bool CheckFloatOrHalfRepresentation(Sema *S, SourceLocation Loc, return false; } +static bool CheckFloatOrHalfOrDoubleRepresentation(Sema *S, SourceLocation Loc, + int ArgOrdinal, + clang::QualType PassedType) { + clang::QualType BaseType = + PassedType->isVectorType() + ? PassedType->castAs<clang::VectorType>()->getElementType() + : PassedType; + if (!BaseType->isFloatingType()) + return S->Diag(Loc, diag::err_builtin_requires_fp_scalar_or_vector_type) + << ArgOrdinal << PassedType; + return false; +} + +static bool CheckAnyDoubleRepresentation(Sema *S, SourceLocation Loc, + int ArgOrdinal, + clang::QualType PassedType) { + clang::QualType BaseType = + PassedType->isVectorType() + ? PassedType->castAs<clang::VectorType>()->getElementType() + : PassedType->isMatrixType() + ? PassedType->castAs<clang::MatrixType>()->getElementType() + : PassedType; + if (!BaseType->isDoubleType()) { + return S->Diag(Loc, diag::err_builtin_requires_double_type) + << ArgOrdinal << PassedType; + } + + return false; +} + static bool CheckModifiableLValue(Sema *S, CallExpr *TheCall, unsigned ArgIndex) { auto *Arg = TheCall->getArg(ArgIndex); @@ -3787,6 +3818,35 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { TheCall->setType(ArgTyA); break; } + case Builtin::BI__builtin_hlsl_elementwise_fma: { + if (SemaRef.checkArgCount(TheCall, 3)) { + return true; + } + const llvm::Triple &TT = getASTContext().getTargetInfo().getTriple(); + // This check is here because emitting a general error for both backends + // here (like for exmaple "Accepts only floating points") won't end really + // good. after that we still need to check if the types satisfy + // backends constrains, so we better check everything now rather than + // confusing user with 2 different error messages + + if (TT.isSPIRV()) { + // SPIR-V accept any float (besides matrices) + if (CheckAllArgTypesAreCorrect(&SemaRef, TheCall, + CheckFloatOrHalfOrDoubleRepresentation)) + return true; + } else if (TT.isDXIL()) { + // while DirectX accepts only double + if (CheckAllArgTypesAreCorrect(&SemaRef, TheCall, + CheckAnyDoubleRepresentation)) + return true; + } + + ExprResult A = TheCall->getArg(0); + QualType ArgTyA = A.get()->getType(); + // return type is the same as input type + TheCall->setType(ArgTyA); + break; + } case Builtin::BI__builtin_hlsl_elementwise_sign: { if (SemaRef.PrepareBuiltinElementwiseMathOneArgCall(TheCall)) return true; @@ -3936,6 +3996,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case Builtin::BI__builtin_elementwise_exp10: case Builtin::BI__builtin_elementwise_floor: case Builtin::BI__builtin_elementwise_fmod: + case Builtin::BI__builtin_elementwise_fma: case Builtin::BI__builtin_elementwise_log: case Builtin::BI__builtin_elementwise_log2: case Builtin::BI__builtin_elementwise_log10: diff --git a/clang/test/CodeGen/SPIRV/hlsl-intrinsics/fma.ll b/clang/test/CodeGen/SPIRV/hlsl-intrinsics/fma.ll new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/CodeGenHLSL/builtins/fma.hlsl b/clang/test/CodeGenHLSL/builtins/fma.hlsl new file mode 100644 index 0000000000000..88b8e27c37043 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/fma.hlsl @@ -0,0 +1,151 @@ +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -DTEST_DXIL \ +// RUN: -fmatrix-memory-layout=row-major -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,DXIL_CHECK -DTARGET=dx +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -DTEST_SPIRV \ +// RUN: -fmatrix-memory-layout=row-major -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,SPIRV_CHECK -DTARGET=spv +// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ +// RUN: spirv-unknown-vulkan-compute %s -DTEST_SPIRV_HALF -fnative-half-type \ +// RUN: -fmatrix-memory-layout=row-major -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefix=SPIRV_HALF_CHECK + +// CHECK-LABEL: define {{.*}} double @{{.*}}fma_double{{.*}}( +// CHECK: %[[P0:.*]] = load double, ptr %{{.*}}, align 8 +// CHECK: %[[P1:.*]] = load double, ptr %{{.*}}, align 8 +// CHECK: %[[P2:.*]] = load double, ptr %{{.*}}, align 8 +// CHECK: %{{dx|spv}}.fma = call reassoc nnan ninf nsz arcp afn double @llvm.[[TARGET]].fma.f64(double %[[P0]], double %[[P1]], double %[[P2]]) +// CHECK: ret double %{{dx|spv}}.fma +double dxil_fma_double(double a, double b, double c) { return fma(a, b, c); } + +// CHECK-LABEL: define {{.*}} <2 x double> @{{.*}}fma_double2{{.*}}( +// CHECK: %[[P0:.*]] = load <2 x double>, ptr %{{.*}}, align 16 +// CHECK: %[[P1:.*]] = load <2 x double>, ptr %{{.*}}, align 16 +// CHECK: %[[P2:.*]] = load <2 x double>, ptr %{{.*}}, align 16 +// CHECK: %{{dx|spv}}.fma = call reassoc nnan ninf nsz arcp afn <2 x double> @llvm.[[TARGET]].fma.v2f64(<2 x double> %[[P0]], <2 x double> %[[P1]], <2 x double> %[[P2]]) +// CHECK: ret <2 x double> %{{dx|spv}}.fma +double2 dxil_fma_double2(double2 a, double2 b, double2 c) { return fma(a, b, c); } + +// CHECK-LABEL: define {{.*}} <3 x double> @{{.*}}fma_double3{{.*}}( +// CHECK: %[[P0:.*]] = load <3 x double>, ptr %{{.*}}, align 32 +// CHECK: %[[P1:.*]] = load <3 x double>, ptr %{{.*}}, align 32 +// CHECK: %[[P2:.*]] = load <3 x double>, ptr %{{.*}}, align 32 +// CHECK: %{{dx|spv}}.fma = call reassoc nnan ninf nsz arcp afn <3 x double> @llvm.[[TARGET]].fma.v3f64(<3 x double> %[[P0]], <3 x double> %[[P1]], <3 x double> %[[P2]]) +// CHECK: ret <3 x double> %{{dx|spv}}.fma +double3 dxil_fma_double3(double3 a, double3 b, double3 c) { return fma(a, b, c); } + +// CHECK-LABEL: define {{.*}} <4 x double> @{{.*}}fma_double4{{.*}}( +// CHECK: %[[P0:.*]] = load <4 x double>, ptr %{{.*}}, align 32 +// CHECK: %[[P1:.*]] = load <4 x double>, ptr %{{.*}}, align 32 +// CHECK: %[[P2:.*]] = load <4 x double>, ptr %{{.*}}, align 32 +// CHECK: %{{dx|spv}}.fma = call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.[[TARGET]].fma.v4f64(<4 x double> %[[P0]], <4 x double> %[[P1]], <4 x double> %[[P2]]) +// CHECK: ret <4 x double> %{{dx|spv}}.fma +double4 dxil_fma_double4(double4 a, double4 b, double4 c) { return fma(a, b, c); } + +#ifdef TEST_DXIL + +// DXIL_CHECK-LABEL: define {{.*}} <4 x double> @{{.*}}dxil_fma_double1x4{{.*}}( +// DXIL_CHECK: %dx.fma = call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.dx.fma.v4f64( +// DXIL_CHECK: ret <4 x double> %dx.fma +double1x4 dxil_fma_double1x4(double1x4 a, double1x4 b, double1x4 c) { return fma(a, b, c); } + +// DXIL_CHECK-LABEL: define {{.*}} <4 x double> @{{.*}}dxil_fma_double4x1{{.*}}( +// DXIL_CHECK: %dx.fma = call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.dx.fma.v4f64( +// DXIL_CHECK: ret <4 x double> %dx.fma +double4x1 dxil_fma_double4x1(double4x1 a, double4x1 b, double4x1 c) { return fma(a, b, c); } + +// DXIL_CHECK-LABEL: define {{.*}} <4 x double> @{{.*}}dxil_fma_double2x2{{.*}}( +// DXIL_CHECK: %dx.fma = call reassoc nnan ninf nsz arcp afn <4 x double> @llvm.dx.fma.v4f64( +// DXIL_CHECK: ret <4 x double> %dx.fma +double2x2 dxil_fma_double2x2(double2x2 a, double2x2 b, double2x2 c) { return fma(a, b, c); } + +// DXIL_CHECK-LABEL: define {{.*}} <6 x double> @{{.*}}dxil_fma_double2x3{{.*}}( +// DXIL_CHECK: %dx.fma = call reassoc nnan ninf nsz arcp afn <6 x double> @llvm.dx.fma.v6f64( +// DXIL_CHECK: ret <6 x double> %dx.fma +double2x3 dxil_fma_double2x3(double2x3 a, double2x3 b, double2x3 c) { return fma(a, b, c); } + +// DXIL_CHECK-LABEL: define {{.*}} <6 x double> @{{.*}}dxil_fma_double3x2{{.*}}( +// DXIL_CHECK: %dx.fma = call reassoc nnan ninf nsz arcp afn <6 x double> @llvm.dx.fma.v6f64( +// DXIL_CHECK: ret <6 x double> %dx.fma +double3x2 dxil_fma_double3x2(double3x2 a, double3x2 b, double3x2 c) { return fma(a, b, c); } + +// DXIL_CHECK-LABEL: define {{.*}} <9 x double> @{{.*}}dxil_fma_double3x3{{.*}}( +// DXIL_CHECK: %dx.fma = call reassoc nnan ninf nsz arcp afn <9 x double> @llvm.dx.fma.v9f64( +// DXIL_CHECK: ret <9 x double> %dx.fma +double3x3 dxil_fma_double3x3(double3x3 a, double3x3 b, double3x3 c) { return fma(a, b, c); } + +// DXIL_CHECK-LABEL: define {{.*}} <16 x double> @{{.*}}dxil_fma_double4x4{{.*}}( +// DXIL_CHECK: %dx.fma = call reassoc nnan ninf nsz arcp afn <16 x double> @llvm.dx.fma.v16f64( +// DXIL_CHECK: ret <16 x double> %dx.fma +double4x4 dxil_fma_double4x4(double4x4 a, double4x4 b, double4x4 c) { return fma(a, b, c); } +#endif + +#ifdef TEST_SPIRV +// SPIRV_CHECK-LABEL: define {{.*}} float @{{.*}}spv_fma_float{{.*}}( +// SPIRV_CHECK: %[[P0:.*]] = load float, ptr %{{.*}}, align 4 +// SPIRV_CHECK: %[[P1:.*]] = load float, ptr %{{.*}}, align 4 +// SPIRV_CHECK: %[[P2:.*]] = load float, ptr %{{.*}}, align 4 +// SPIRV_CHECK: %spv.fma = call reassoc nnan ninf nsz arcp afn float @llvm.spv.fma.f32(float %[[P0]], float %[[P1]], float %[[P2]]) +// SPIRV_CHECK: ret float %spv.fma +float spv_fma_float(float a, float b, float c) { return fma(a, b, c); } + +// SPIRV_CHECK-LABEL: define {{.*}} <2 x float> @{{.*}}spv_fma_float2{{.*}}( +// SPIRV_CHECK: %[[P0:.*]] = load <2 x float>, ptr %{{.*}}, align 8 +// SPIRV_CHECK: %[[P1:.*]] = load <2 x float>, ptr %{{.*}}, align 8 +// SPIRV_CHECK: %[[P2:.*]] = load <2 x float>, ptr %{{.*}}, align 8 +// SPIRV_CHECK: %spv.fma = call reassoc nnan ninf nsz arcp afn <2 x float> @llvm.spv.fma.v2f32(<2 x float> %[[P0]], <2 x float> %[[P1]], <2 x float> %[[P2]]) +// SPIRV_CHECK: ret <2 x float> %spv.fma +float2 spv_fma_float2(float2 a, float2 b, float2 c) { return fma(a, b, c); } + +// SPIRV_CHECK-LABEL: define {{.*}} <3 x float> @{{.*}}spv_fma_float3{{.*}}( +// SPIRV_CHECK: %[[P0:.*]] = load <3 x float>, ptr %{{.*}}, align 16 +// SPIRV_CHECK: %[[P1:.*]] = load <3 x float>, ptr %{{.*}}, align 16 +// SPIRV_CHECK: %[[P2:.*]] = load <3 x float>, ptr %{{.*}}, align 16 +// SPIRV_CHECK: %spv.fma = call reassoc nnan ninf nsz arcp afn <3 x float> @llvm.spv.fma.v3f32(<3 x float> %[[P0]], <3 x float> %[[P1]], <3 x float> %[[P2]]) +// SPIRV_CHECK: ret <3 x float> %spv.fma +float3 spv_fma_float3(float3 a, float3 b, float3 c) { return fma(a, b, c); } + +// SPIRV_CHECK-LABEL: define {{.*}} <4 x float> @{{.*}}spv_fma_float4{{.*}}( +// SPIRV_CHECK: %[[P0:.*]] = load <4 x float>, ptr %{{.*}}, align 16 +// SPIRV_CHECK: %[[P1:.*]] = load <4 x float>, ptr %{{.*}}, align 16 +// SPIRV_CHECK: %[[P2:.*]] = load <4 x float>, ptr %{{.*}}, align 16 +// SPIRV_CHECK: %spv.fma = call reassoc nnan ninf nsz arcp afn <4 x float> @llvm.spv.fma.v4f32(<4 x float> %[[P0]], <4 x float> %[[P1]], <4 x float> %[[P2]]) +// SPIRV_CHECK: ret <4 x float> %spv.fma +float4 spv_fma_float4(float4 a, float4 b, float4 c) { return fma(a, b, c); } + +#endif + +#ifdef TEST_SPIRV_HALF +// SPIRV_HALF_CHECK-LABEL: define {{.*}} half @{{.*}}spv_fma_half{{.*}}( +// SPIRV_HALF_CHECK: %[[P0:.*]] = load half, ptr %{{.*}}, align 2 +// SPIRV_HALF_CHECK: %[[P1:.*]] = load half, ptr %{{.*}}, align 2 +// SPIRV_HALF_CHECK: %[[P2:.*]] = load half, ptr %{{.*}}, align 2 +// SPIRV_HALF_CHECK: %spv.fma = call reassoc nnan ninf nsz arcp afn half @llvm.spv.fma.f16(half %[[P0]], half %[[P1]], half %[[P2]]) +// SPIRV_HALF_CHECK: ret half %spv.fma +half spv_fma_half(half a, half b, half c) { return fma(a, b, c); } + +// SPIRV_HALF_CHECK-LABEL: define {{.*}} <2 x half> @{{.*}}spv_fma_half2{{.*}}( +// SPIRV_HALF_CHECK: %[[P0:.*]] = load <2 x half>, ptr %{{.*}}, align 4 +// SPIRV_HALF_CHECK: %[[P1:.*]] = load <2 x half>, ptr %{{.*}}, align 4 +// SPIRV_HALF_CHECK: %[[P2:.*]] = load <2 x half>, ptr %{{.*}}, align 4 +// SPIRV_HALF_CHECK: %spv.fma = call reassoc nnan ninf nsz arcp afn <2 x half> @llvm.spv.fma.v2f16(<2 x half> %[[P0]], <2 x half> %[[P1]], <2 x half> %[[P2]]) +// SPIRV_HALF_CHECK: ret <2 x half> %spv.fma +half2 spv_fma_half2(half2 a, half2 b, half2 c) { return fma(a, b, c); } + +// SPIRV_HALF_CHECK-LABEL: define {{.*}} <3 x half> @{{.*}}spv_fma_half3{{.*}}( +// SPIRV_HALF_CHECK: %[[P0:.*]] = load <3 x half>, ptr %{{.*}}, align 8 +// SPIRV_HALF_CHECK: %[[P1:.*]] = load <3 x half>, ptr %{{.*}}, align 8 +// SPIRV_HALF_CHECK: %[[P2:.*]] = load <3 x half>, ptr %{{.*}}, align 8 +// SPIRV_HALF_CHECK: %spv.fma = call reassoc nnan ninf nsz arcp afn <3 x half> @llvm.spv.fma.v3f16(<3 x half> %[[P0]], <3 x half> %[[P1]], <3 x half> %[[P2]]) +// SPIRV_HALF_CHECK: ret <3 x half> %spv.fma +half3 spv_fma_half3(half3 a, half3 b, half3 c) { return fma(a, b, c); } + +// SPIRV_HALF_CHECK-LABEL: define {{.*}} <4 x half> @{{.*}}spv_fma_half4{{.*}}( +// SPIRV_HALF_CHECK: %[[P0:.*]] = load <4 x half>, ptr %{{.*}}, align 8 +// SPIRV_HALF_CHECK: %[[P1:.*]] = load <4 x half>, ptr %{{.*}}, align 8 +// SPIRV_HALF_CHECK: %[[P2:.*]] = load <4 x half>, ptr %{{.*}}, align 8 +// SPIRV_HALF_CHECK: %spv.fma = call reassoc nnan ninf nsz arcp afn <4 x half> @llvm.spv.fma.v4f16(<4 x half> %[[P0]], <4 x half> %[[P1]], <4 x half> %[[P2]]) +// SPIRV_HALF_CHECK: ret <4 x half> %spv.fma +half4 spv_fma_half4(half4 a, half4 b, half4 c) { return fma(a, b, c); } +#endif diff --git a/clang/test/Sema/incompatible-function-to-ptr-decay.c b/clang/test/Sema/incompatible-function-to-ptr-decay.c new file mode 100644 index 0000000000000..240b5b8763a23 --- /dev/null +++ b/clang/test/Sema/incompatible-function-to-ptr-decay.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -fexperimental-overflow-behavior-types -verify %s + +// Issue 182534 +int foo(); + +void bar(__attribute__((opencl_global)) int*); // #cldecl +void baz(__ob_wrap int*); // #ofdecl + +void a() { + bar(foo); + // expected-error@-1 {{passing 'int (*)()' to parameter of type '__global int *' changes address space of pointer}} + // expected-note@#cldecl {{passing argument to parameter here}} + __ob_trap int val[10]; + baz(val); + // expected-error@-1 {{assigning to '__ob_wrap int *' from '__ob_trap int *' with incompatible overflow behavior types ('__ob_wrap' and '__ob_trap')}} + // expected-note@#ofdecl {{passing argument to parameter here}} +} + diff --git a/clang/test/SemaHLSL/BuiltIns/fma-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/fma-errors.hlsl new file mode 100644 index 0000000000000..1ed7b34b4396f --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/fma-errors.hlsl @@ -0,0 +1,145 @@ +// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -x hlsl \ +// RUN: -triple dxil-pc-shadermodel6.6-library %s -DTEST_DXIL \ +// RUN: -emit-llvm-only -disable-llvm-passes -verify=dxil +// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -x hlsl \ +// RUN: -triple spirv-unknown-vulkan-compute %s -DTEST_SPIRV \ +// RUN: -emit-llvm-only -disable-llvm-passes -verify=spv + +#ifdef TEST_DXIL +float dxil_fma_float(float a, float b, float c) { + return fma(a, b, c); + // dxil-error@-1 {{1st argument must be a scalar, vector, or matrix of double type (was 'float')}} +} + +float2 dxil_fma_float2(float2 a, float2 b, float2 c) { + return fma(a, b, c); + // dxil-error@-1 {{1st argument must be a scalar, vector, or matrix of double type (was 'float2' (aka 'vector<float, 2>'))}} +} + +float4 dxil_fma_float4(float4 a, float4 b, float4 c) { + return fma(a, b, c); + // dxil-error@-1 {{1st argument must be a scalar, vector, or matrix of double type (was 'float4' (aka 'vector<float, 4>'))}} +} + +float2x2 dxil_fma_float2x2(float2x2 a, float2x2 b, float2x2 c) { + return fma(a, b, c); + // dxil-error@-1 {{1st argument must be a scalar, vector, or matrix of double type (was 'float2x2' (aka 'matrix<float, 2, 2>'))}} +} + +doub... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/185304 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
