Skip to content

Commit

Permalink
adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
joaosaffran-zz committed Nov 4, 2024
1 parent 20af135 commit 20587a9
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 42 deletions.
24 changes: 8 additions & 16 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,8 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
Expand All @@ -57,14 +55,12 @@
#include "llvm/IR/IntrinsicsR600.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/IntrinsicsS390.h"
#include "llvm/IR/IntrinsicsSPIRV.h"
#include "llvm/IR/IntrinsicsVE.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/MatrixBuilder.h"
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/AMDGPUAddrSpace.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/MathExtras.h"
Expand Down Expand Up @@ -112,35 +108,31 @@ static Value *handleHlslClip(const CallExpr *E, CodeGenFunction *CGF) {
if (const auto *VecTy = E->getArg(0)->getType()->getAs<clang::VectorType>()) {
FZeroConst = ConstantVector::getSplat(
ElementCount::getFixed(VecTy->getNumElements()), FZeroConst);
CMP = CGF->Builder.CreateFCmpOLT(Op0, FZeroConst);
auto *FCompInst = CGF->Builder.CreateFCmpOLT(Op0, FZeroConst);
CMP = CGF->Builder.CreateIntrinsic(
CGF->Builder.getInt1Ty(), CGF->CGM.getHLSLRuntime().getAnyIntrinsic(),
{FCompInst}, nullptr);
} else
CMP = CGF->Builder.CreateFCmpOLT(Op0, FZeroConst);

if (CGF->CGM.getTarget().getTriple().isDXIL())
return CGF->Builder.CreateIntrinsic(CGF->VoidTy, llvm::Intrinsic::dx_clip,
{CMP}, nullptr);

if (const auto *VecTy = E->getArg(0)->getType()->getAs<clang::VectorType>()){

CMP = CGF->Builder.CreateIntrinsic(CGF->Builder.getInt1Ty(), llvm::Intrinsic::spv_any,
{CMP}, nullptr);
}


BasicBlock *LT0 = CGF->createBasicBlock("lt0", CGF->CurFn);
BasicBlock *End = CGF->createBasicBlock("end", CGF->CurFn);

CGF->Builder.CreateCondBr(CMP, LT0, End);

CGF->Builder.SetInsertPoint(LT0);

auto *IntrCall = CGF->Builder.CreateIntrinsic(
CGF->VoidTy, llvm::Intrinsic::spv_clip, {}, nullptr);
CGF->Builder.CreateIntrinsic(CGF->VoidTy, llvm::Intrinsic::spv_clip, {},
nullptr);

CGF->Builder.CreateBr(End);
auto *BrCall = CGF->Builder.CreateBr(End);

CGF->Builder.SetInsertPoint(End);
return IntrCall;
return BrCall;
}

static Value *handleHlslSplitdouble(const CallExpr *E, CodeGenFunction *CGF) {
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGHLSLRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class CGHLSLRuntime {
GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)

GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding, handle_fromBinding)

//===----------------------------------------------------------------------===//
Expand Down
17 changes: 10 additions & 7 deletions clang/test/CodeGenHLSL/builtins/clip.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,33 @@ void test_scalar(float Buf) {
// CHECK: define void @{{.*}}test_scalar{{.*}}(float {{.*}} [[VALP:%.*]])
// CHECK: [[LOAD:%.*]] = load float, ptr [[VALP]].addr, align 4
// CHECK-NEXT: [[FCMP:%.*]] = fcmp olt float [[LOAD]], 0.000000e+00
// CHECK-NEXT: call void @llvm.dx.clip.i1(i1 [[FCMP]])
// CHECK-NO: call i1 @llvm.dx.any
// CHECK-NEXT: call void @llvm.dx.clip(i1 [[FCMP]])
//
// SPIRV: define spir_func void @{{.*}}test_scalar{{.*}}(float {{.*}} [[VALP:%.*]])
// SPIRV: [[LOAD:%.*]] = load float, ptr [[VALP]].addr, align 4
// SPIRV-NEXT: [[FCMP:%.*]] = fcmp olt float [[LOAD]], 0.000000e+00
// SPIRV-NO: call i1 @llvm.dx.any
// SPIRV-NEXT: br i1 [[FCMP]], label %[[LTL:.*]], label %[[ENDL:.*]]
// SPIRV: [[LTL]]: ; preds = %entry
// SPIRV: [[LTL]]: ; preds = %entry
// SPIRV-NEXT: call void @llvm.spv.clip()
// SPIRV: br label %[[ENDL]]
// SPIRV: br label %[[ENDL]]
clip(Buf);
}

void test_vector4(float4 Buf) {
// CHECK: define void @{{.*}}test_vector{{.*}}(<4 x float> {{.*}} [[VALP:%.*]])
// CHECK: [[LOAD:%.*]] = load <4 x float>, ptr [[VALP]].addr, align 16
// CHECK-NEXT: [[FCMP:%.*]] = fcmp olt <4 x float> [[LOAD]], zeroinitializer
// CHECK-NEXT: call void @llvm.dx.clip.v4i1(<4 x i1> [[FCMP]])
// CHECK-NEXT: [[ANYC:%.*]] = call i1 @llvm.dx.any.v4i1(<4 x i1> [[FCMP]])
// CHECK-NEXT: call void @llvm.dx.clip(i1 [[ANYC]])
//
// SPIRV: define spir_func void @{{.*}}test_vector{{.*}}(<4 x float> {{.*}} [[VALP:%.*]])
// SPIRV: [[LOAD:%.*]] = load <4 x float>, ptr [[VALP]].addr, align 16
// SPIRV-NEXT: [[FCMP:%.*]] = fcmp olt <4 x float> [[LOAD]], zeroinitializer
// SPIRV-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FCMP]])
// SPIRV-NEXT: br i1 [[RED]], label %[[LTL:.*]], label %[[ENDL:.*]]
// SPIRV: [[LTL]]: ; preds = %entry
// SPIRV-NEXT: [[ANYC:%.*]] = call i1 @llvm.spv.any.v4i1(<4 x i1> [[FCMP]])
// SPIRV-NEXT: br i1 [[ANYC]], label %[[LTL:.*]], label %[[ENDL:.*]]
// SPIRV: [[LTL]]: ; preds = %entry
// SPIRV-NEXT: call void @llvm.spv.clip()
// SPIRV-NEXT: br label %[[ENDL]]
clip(Buf);
Expand Down
22 changes: 22 additions & 0 deletions clang/test/SemaHLSL/BuiltIns/clip-errors.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -verify


void test_arg_missing() {
__builtin_hlsl_elementwise_clip();
// expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
}

void test_too_many_args(float p1, float p2) {
__builtin_hlsl_elementwise_clip(p1, p2);
// expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
}

void test_first_arg_type_mismatch(bool p) {
__builtin_hlsl_elementwise_clip(p);
// expected-error@-1 {{invalid operand of type 'bool' where 'float' or a vector of such type is required}}
}

void test_first_arg_type_mismatch_2(half p) {
__builtin_hlsl_elementwise_clip(p);
// expected-error@-1 {{invalid operand of type 'double' where 'float' or a vector of such type is required}}
}
2 changes: 1 addition & 1 deletion llvm/include/llvm/IR/IntrinsicsDirectX.td
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, L
def int_dx_splitdouble : DefaultAttrsIntrinsic<[llvm_anyint_ty, LLVMMatchType<0>],
[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [IntrNoMem]>;
def int_dx_radians : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
def int_dx_clip : DefaultAttrsIntrinsic<[], [llvm_anyint_ty], [IntrNoMem]>;
def int_dx_clip : DefaultAttrsIntrinsic<[], [llvm_i1_ty], [IntrNoMem]>;
}
4 changes: 3 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ static const std::map<std::string, SPIRV::Extension::Extension>
{"SPV_KHR_cooperative_matrix",
SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
{"SPV_KHR_non_semantic_info",
SPIRV::Extension::Extension::SPV_KHR_non_semantic_info}};
SPIRV::Extension::Extension::SPV_KHR_non_semantic_info},
{"SPV_EXT_demote_to_helper_invocation",
SPIRV::Extension::Extension::SPV_EXT_demote_to_helper_invocation}};

bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName,
llvm::StringRef ArgValue,
Expand Down
21 changes: 17 additions & 4 deletions llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/IR/IntrinsicsSPIRV.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/VersionTuple.h"

#define DEBUG_TYPE "spirv-isel"

Expand Down Expand Up @@ -1973,9 +1972,23 @@ bool SPIRVInstructionSelector::selectSplatVector(Register ResVReg,
bool SPIRVInstructionSelector::selectClip(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
const auto Opcode = (STI.isAtLeastSPIRVVer(VersionTuple(1, 6)))
? SPIRV::OpDemoteToHelperInvocation
: SPIRV::OpKill;

unsigned Opcode;

if (STI.isAtLeastSPIRVVer(VersionTuple(1, 6))) {
if (!STI.canUseExtension(
SPIRV::Extension::SPV_EXT_demote_to_helper_invocation))
report_fatal_error(
"llvm.spv.clip intrinsic: this instruction requires the following "
"SPIR-V extension: SPV_EXT_demote_to_helper_invocation",
false);
Opcode = SPIRV::OpDemoteToHelperInvocation;
} else {
Opcode = SPIRV::OpKill;
// OpKill must be the last operation of any basic block.
MachineInstr *NextI = I.getNextNode();
NextI->removeFromParent();
}

MachineBasicBlock &BB = *I.getParent();
return BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,17 @@ void addInstrRequirements(const MachineInstr &MI,
Reqs.addCapability(SPIRV::Capability::SplitBarrierINTEL);
}
break;

case SPIRV::OpKill: {
Reqs.addCapability(SPIRV::Capability::Shader);
} break;
case SPIRV::OpDemoteToHelperInvocation:
if (ST.canUseExtension(
SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
Reqs.addExtension(SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
Reqs.addCapability(SPIRV::Capability::DemoteToHelperInvocation);
}
break;
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ defm VulkanMemoryModelDeviceScopeKHR : CapabilityOperand<5346, 0, 0, [], []>;
defm ImageFootprintNV : CapabilityOperand<5282, 0, 0, [], []>;
defm FragmentBarycentricNV : CapabilityOperand<5284, 0, 0, [], []>;
defm ComputeDerivativeGroupQuadsNV : CapabilityOperand<5288, 0, 0, [], []>;
defm DemoteToHelperInvocation : CapabilityOperand<5379, 0, 0, [SPV_EXT_demote_to_helper_invocation], []>;
defm ComputeDerivativeGroupLinearNV : CapabilityOperand<5350, 0, 0, [], []>;
defm FragmentDensityEXT : CapabilityOperand<5291, 0, 0, [], [Shader]>;
defm PhysicalStorageBufferAddressesEXT : CapabilityOperand<5347, 0, 0, [], [Shader]>;
Expand Down
24 changes: 21 additions & 3 deletions llvm/test/CodeGen/DirectX/clip.ll
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
; RUN: opt -S -dxil-intrinsic-expansion -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-pixel %s | FileCheck %s
; RUN: opt -passes='function(scalarizer),module(dxil-op-lower,dxil-intrinsic-expansion)' -S -mtriple=dxil-pc-shadermodel6.3-pixel %s | FileCheck %s

; CHECK-LABEL: define void @test_dxil_lowering
; CHECK-LABEL: define void @test_scalar
; CHECK: call void @dx.op.discard(i32 82, i1 %0)
;
define void @test_dxil_lowering(float noundef %p) #0 {
define void @test_scalar(float noundef %p) #0 {
entry:
%0 = fcmp olt float %p, 0.000000e+00
call void @llvm.dx.clip(i1 %0)
ret void
}

; CHECK-LABEL: define void @test_vector
; CHECK: [[EXTR0:%.*]] = extractelement <4 x i1> [[INP:%.*]], i64 0
; CHECK-NEXT: [[EXTR1:%.*]] = extractelement <4 x i1> [[INP:%.*]], i64 1
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[EXTR0]], [[EXTR1]]
; CHECK-NEXT: [[EXTR2:%.*]] = extractelement <4 x i1> [[INP:%.*]], i64 2
; CHECK-NEXT: [[OR2:%.*]] = or i1 [[OR1]], [[EXTR2]]
; CHECK-NEXT: [[EXTR3:%.*]] = extractelement <4 x i1> [[INP:%.*]], i64 3
; CHECK-NEXT: [[OR3:%.*]] = or i1 [[OR2]], [[EXTR3]]
; CHECK-NEXT: call void @dx.op.discard(i32 82, i1 [[OR3]])
;
define void @test_vector(<4 x float> noundef %p) #0 {
entry:
%0 = fcmp olt <4 x float> %p, zeroinitializer
%1 = call i1 @llvm.dx.any.v4i1(<4 x i1> %0)
call void @llvm.dx.clip(i1 %1)
ret void
}
56 changes: 46 additions & 10 deletions llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clip.ll
Original file line number Diff line number Diff line change
@@ -1,14 +1,40 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,SPIRV15
; RUN: llc -verify-machineinstrs -spirv-ext=+SPV_EXT_demote_to_helper_invocation -O0 -mtriple=spirv32v1.6-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,SPIRV16
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}


define void @test_scalar_lowering(float noundef %Buf) {
; Make sure lowering is correctly generating spirv code.

; CHECK-DAG: %[[#float:]] = OpTypeFloat 32
; CHECK-DAG: %[[#void:]] = OpTypeVoid
; CHECK-DAG: %[[#bool:]] = OpTypeBool
; CHECK-DAG: %[[#v4bool:]] = OpTypeVector %[[#bool]] 4
; CHECK-DAG: %[[#v4float:]] = OpTypeVector %[[#float]] 4
; CHECK-DAG: %[[#fzero:]] = OpConstant %[[#float]] 0
; CHECK-DAG: %[[#v4fzero:]] = OpConstantNull %[[#v4float]]
; SPIRV16-DAG: %[[#vecfuncopptr:]] = OpTypePointer Function %[[#v4float]]
; SPIRV16-DAG: %[[#funcopptr:]] = OpTypePointer Function %[[#float]]

define void @test_scalar(float noundef %Buf) {
entry:
; CHECK-LABEL: ; -- Begin function test_scalar
; SPIRV16: %[[#param:]] = OpVariable %[[#funcopptr]] Function
; SPIRV16: %[[#load:]] = OpLoad %[[#float]] %[[#param]] Aligned 4
; SPIRV15: %[[#load:]] = OpFunctionParameter %[[#float]]
; CHECK: %[[#cmplt:]] = OpFOrdLessThan %[[#bool]] %[[#load]] %[[#fzero]]
; CHECK: OpBranchConditional %[[#cmplt]] %[[#truel:]] %[[#endl:]]
; CHECK: %[[#truel]] = OpLabel
; SPIRV15: OpKill
; SPIRV16-NO: OpKill
; SPIRV15-NO: OpBranch %[[#endl]]
; SPIRV16: OpDemoteToHelperInvocation
; SPIRV16: OpBranch %[[#endl]]
; CHECK: %[[#endl]] = OpLabel
%Buf.addr = alloca float, align 4
store float %Buf, ptr %Buf.addr, align 4
%0 = load float, ptr %Buf.addr, align 4
%1 = fcmp olt float %0, 0.000000e+00
br i1 %1, label %lt0, label %end
%1 = load float, ptr %Buf.addr, align 4
%2 = fcmp olt float %1, 0.000000e+00
br i1 %2, label %lt0, label %end

lt0: ; preds = %entry
call void @llvm.spv.clip()
Expand All @@ -17,17 +43,29 @@ lt0: ; preds = %entry
end: ; preds = %lt0, %entry
ret void
}

declare void @llvm.spv.clip()


define void @test_vector(<4 x float> noundef %Buf) {
entry:
; CHECK-LABEL: ; -- Begin function test_vector
; SPIRV16: %[[#param:]] = OpVariable %[[#vecfuncopptr]] Function
; SPIRV16: %[[#loadvec:]] = OpLoad %[[#v4float]] %[[#param]] Aligned 16
; SPIRV15: %[[#loadvec:]] = OpFunctionParameter %[[#v4float]]
; CHECK: %[[#cmplt:]] = OpFOrdLessThan %[[#v4bool]] %[[#loadvec]] %[[#v4fzero]]
; CHECK: %[[#opany:]] = OpAny %[[#bool]] %[[#cmplt]]
; CHECK: OpBranchConditional %[[#opany]] %[[#truel:]] %[[#endl:]]
; CHECK: %[[#truel]] = OpLabel
; SPIRV15: OpKill
; SPIRV16-NO: OpKill
; SPIRV15-NO: OpBranch %[[#endl]]
; SPIRV16: OpDemoteToHelperInvocation
; SPIRV16: OpBranch %[[#endl]]
; CHECK: %[[#endl]] = OpLabel
%Buf.addr = alloca <4 x float>, align 16
store <4 x float> %Buf, ptr %Buf.addr, align 16
%1 = load <4 x float>, ptr %Buf.addr, align 16
%2 = fcmp olt <4 x float> %1, zeroinitializer
%3 = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %2)
%3 = call i1 @llvm.spv.any.v4i1(<4 x i1> %2)
br i1 %3, label %lt0, label %end

lt0: ; preds = %entry
Expand All @@ -37,5 +75,3 @@ lt0: ; preds = %entry
end: ; preds = %lt0, %entry
ret void
}

declare i1 @llvm.vector.reduce.or.v4i1(<4 x i1>) #3

0 comments on commit 20587a9

Please sign in to comment.