Skip to content

Commit 20587a9

Browse files
adding tests
1 parent 20af135 commit 20587a9

File tree

11 files changed

+141
-42
lines changed

11 files changed

+141
-42
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

+8-16
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,8 @@
4141
#include "llvm/ADT/SmallPtrSet.h"
4242
#include "llvm/ADT/StringExtras.h"
4343
#include "llvm/Analysis/ValueTracking.h"
44-
#include "llvm/IR/Constants.h"
4544
#include "llvm/IR/DataLayout.h"
4645
#include "llvm/IR/InlineAsm.h"
47-
#include "llvm/IR/InstrTypes.h"
4846
#include "llvm/IR/Intrinsics.h"
4947
#include "llvm/IR/IntrinsicsAArch64.h"
5048
#include "llvm/IR/IntrinsicsAMDGPU.h"
@@ -57,14 +55,12 @@
5755
#include "llvm/IR/IntrinsicsR600.h"
5856
#include "llvm/IR/IntrinsicsRISCV.h"
5957
#include "llvm/IR/IntrinsicsS390.h"
60-
#include "llvm/IR/IntrinsicsSPIRV.h"
6158
#include "llvm/IR/IntrinsicsVE.h"
6259
#include "llvm/IR/IntrinsicsWebAssembly.h"
6360
#include "llvm/IR/IntrinsicsX86.h"
6461
#include "llvm/IR/MDBuilder.h"
6562
#include "llvm/IR/MatrixBuilder.h"
6663
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
67-
#include "llvm/IR/Type.h"
6864
#include "llvm/Support/AMDGPUAddrSpace.h"
6965
#include "llvm/Support/ConvertUTF.h"
7066
#include "llvm/Support/MathExtras.h"
@@ -112,35 +108,31 @@ static Value *handleHlslClip(const CallExpr *E, CodeGenFunction *CGF) {
112108
if (const auto *VecTy = E->getArg(0)->getType()->getAs<clang::VectorType>()) {
113109
FZeroConst = ConstantVector::getSplat(
114110
ElementCount::getFixed(VecTy->getNumElements()), FZeroConst);
115-
CMP = CGF->Builder.CreateFCmpOLT(Op0, FZeroConst);
111+
auto *FCompInst = CGF->Builder.CreateFCmpOLT(Op0, FZeroConst);
112+
CMP = CGF->Builder.CreateIntrinsic(
113+
CGF->Builder.getInt1Ty(), CGF->CGM.getHLSLRuntime().getAnyIntrinsic(),
114+
{FCompInst}, nullptr);
116115
} else
117116
CMP = CGF->Builder.CreateFCmpOLT(Op0, FZeroConst);
118117

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

123-
if (const auto *VecTy = E->getArg(0)->getType()->getAs<clang::VectorType>()){
124-
125-
CMP = CGF->Builder.CreateIntrinsic(CGF->Builder.getInt1Ty(), llvm::Intrinsic::spv_any,
126-
{CMP}, nullptr);
127-
}
128-
129-
130122
BasicBlock *LT0 = CGF->createBasicBlock("lt0", CGF->CurFn);
131123
BasicBlock *End = CGF->createBasicBlock("end", CGF->CurFn);
132124

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

135127
CGF->Builder.SetInsertPoint(LT0);
136128

137-
auto *IntrCall = CGF->Builder.CreateIntrinsic(
138-
CGF->VoidTy, llvm::Intrinsic::spv_clip, {}, nullptr);
129+
CGF->Builder.CreateIntrinsic(CGF->VoidTy, llvm::Intrinsic::spv_clip, {},
130+
nullptr);
139131

140-
CGF->Builder.CreateBr(End);
132+
auto *BrCall = CGF->Builder.CreateBr(End);
141133

142134
CGF->Builder.SetInsertPoint(End);
143-
return IntrCall;
135+
return BrCall;
144136
}
145137

146138
static Value *handleHlslSplitdouble(const CallExpr *E, CodeGenFunction *CGF) {

clang/lib/CodeGen/CGHLSLRuntime.h

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class CGHLSLRuntime {
9191
GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot)
9292
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane)
9393
GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane)
94+
9495
GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding, handle_fromBinding)
9596

9697
//===----------------------------------------------------------------------===//

clang/test/CodeGenHLSL/builtins/clip.hlsl

+10-7
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,33 @@ void test_scalar(float Buf) {
66
// CHECK: define void @{{.*}}test_scalar{{.*}}(float {{.*}} [[VALP:%.*]])
77
// CHECK: [[LOAD:%.*]] = load float, ptr [[VALP]].addr, align 4
88
// CHECK-NEXT: [[FCMP:%.*]] = fcmp olt float [[LOAD]], 0.000000e+00
9-
// CHECK-NEXT: call void @llvm.dx.clip.i1(i1 [[FCMP]])
9+
// CHECK-NO: call i1 @llvm.dx.any
10+
// CHECK-NEXT: call void @llvm.dx.clip(i1 [[FCMP]])
1011
//
1112
// SPIRV: define spir_func void @{{.*}}test_scalar{{.*}}(float {{.*}} [[VALP:%.*]])
1213
// SPIRV: [[LOAD:%.*]] = load float, ptr [[VALP]].addr, align 4
1314
// SPIRV-NEXT: [[FCMP:%.*]] = fcmp olt float [[LOAD]], 0.000000e+00
15+
// SPIRV-NO: call i1 @llvm.dx.any
1416
// SPIRV-NEXT: br i1 [[FCMP]], label %[[LTL:.*]], label %[[ENDL:.*]]
15-
// SPIRV: [[LTL]]: ; preds = %entry
17+
// SPIRV: [[LTL]]: ; preds = %entry
1618
// SPIRV-NEXT: call void @llvm.spv.clip()
17-
// SPIRV: br label %[[ENDL]]
19+
// SPIRV: br label %[[ENDL]]
1820
clip(Buf);
1921
}
2022

2123
void test_vector4(float4 Buf) {
2224
// CHECK: define void @{{.*}}test_vector{{.*}}(<4 x float> {{.*}} [[VALP:%.*]])
2325
// CHECK: [[LOAD:%.*]] = load <4 x float>, ptr [[VALP]].addr, align 16
2426
// CHECK-NEXT: [[FCMP:%.*]] = fcmp olt <4 x float> [[LOAD]], zeroinitializer
25-
// CHECK-NEXT: call void @llvm.dx.clip.v4i1(<4 x i1> [[FCMP]])
27+
// CHECK-NEXT: [[ANYC:%.*]] = call i1 @llvm.dx.any.v4i1(<4 x i1> [[FCMP]])
28+
// CHECK-NEXT: call void @llvm.dx.clip(i1 [[ANYC]])
2629
//
2730
// SPIRV: define spir_func void @{{.*}}test_vector{{.*}}(<4 x float> {{.*}} [[VALP:%.*]])
2831
// SPIRV: [[LOAD:%.*]] = load <4 x float>, ptr [[VALP]].addr, align 16
2932
// SPIRV-NEXT: [[FCMP:%.*]] = fcmp olt <4 x float> [[LOAD]], zeroinitializer
30-
// SPIRV-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[FCMP]])
31-
// SPIRV-NEXT: br i1 [[RED]], label %[[LTL:.*]], label %[[ENDL:.*]]
32-
// SPIRV: [[LTL]]: ; preds = %entry
33+
// SPIRV-NEXT: [[ANYC:%.*]] = call i1 @llvm.spv.any.v4i1(<4 x i1> [[FCMP]])
34+
// SPIRV-NEXT: br i1 [[ANYC]], label %[[LTL:.*]], label %[[ENDL:.*]]
35+
// SPIRV: [[LTL]]: ; preds = %entry
3336
// SPIRV-NEXT: call void @llvm.spv.clip()
3437
// SPIRV-NEXT: br label %[[ENDL]]
3538
clip(Buf);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -verify
2+
3+
4+
void test_arg_missing() {
5+
__builtin_hlsl_elementwise_clip();
6+
// expected-error@-1 {{too few arguments to function call, expected 1, have 0}}
7+
}
8+
9+
void test_too_many_args(float p1, float p2) {
10+
__builtin_hlsl_elementwise_clip(p1, p2);
11+
// expected-error@-1 {{too many arguments to function call, expected 1, have 2}}
12+
}
13+
14+
void test_first_arg_type_mismatch(bool p) {
15+
__builtin_hlsl_elementwise_clip(p);
16+
// expected-error@-1 {{invalid operand of type 'bool' where 'float' or a vector of such type is required}}
17+
}
18+
19+
void test_first_arg_type_mismatch_2(half p) {
20+
__builtin_hlsl_elementwise_clip(p);
21+
// expected-error@-1 {{invalid operand of type 'double' where 'float' or a vector of such type is required}}
22+
}

llvm/include/llvm/IR/IntrinsicsDirectX.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,5 @@ def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, L
9292
def int_dx_splitdouble : DefaultAttrsIntrinsic<[llvm_anyint_ty, LLVMMatchType<0>],
9393
[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [IntrNoMem]>;
9494
def int_dx_radians : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
95-
def int_dx_clip : DefaultAttrsIntrinsic<[], [llvm_anyint_ty], [IntrNoMem]>;
95+
def int_dx_clip : DefaultAttrsIntrinsic<[], [llvm_i1_ty], [IntrNoMem]>;
9696
}

llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ static const std::map<std::string, SPIRV::Extension::Extension>
7373
{"SPV_KHR_cooperative_matrix",
7474
SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
7575
{"SPV_KHR_non_semantic_info",
76-
SPIRV::Extension::Extension::SPV_KHR_non_semantic_info}};
76+
SPIRV::Extension::Extension::SPV_KHR_non_semantic_info},
77+
{"SPV_EXT_demote_to_helper_invocation",
78+
SPIRV::Extension::Extension::SPV_EXT_demote_to_helper_invocation}};
7779

7880
bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName,
7981
llvm::StringRef ArgValue,

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

+17-4
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
#include "llvm/CodeGen/TargetOpcodes.h"
3333
#include "llvm/IR/IntrinsicsSPIRV.h"
3434
#include "llvm/Support/Debug.h"
35-
#include "llvm/Support/VersionTuple.h"
3635

3736
#define DEBUG_TYPE "spirv-isel"
3837

@@ -1973,9 +1972,23 @@ bool SPIRVInstructionSelector::selectSplatVector(Register ResVReg,
19731972
bool SPIRVInstructionSelector::selectClip(Register ResVReg,
19741973
const SPIRVType *ResType,
19751974
MachineInstr &I) const {
1976-
const auto Opcode = (STI.isAtLeastSPIRVVer(VersionTuple(1, 6)))
1977-
? SPIRV::OpDemoteToHelperInvocation
1978-
: SPIRV::OpKill;
1975+
1976+
unsigned Opcode;
1977+
1978+
if (STI.isAtLeastSPIRVVer(VersionTuple(1, 6))) {
1979+
if (!STI.canUseExtension(
1980+
SPIRV::Extension::SPV_EXT_demote_to_helper_invocation))
1981+
report_fatal_error(
1982+
"llvm.spv.clip intrinsic: this instruction requires the following "
1983+
"SPIR-V extension: SPV_EXT_demote_to_helper_invocation",
1984+
false);
1985+
Opcode = SPIRV::OpDemoteToHelperInvocation;
1986+
} else {
1987+
Opcode = SPIRV::OpKill;
1988+
// OpKill must be the last operation of any basic block.
1989+
MachineInstr *NextI = I.getNextNode();
1990+
NextI->removeFromParent();
1991+
}
19791992

19801993
MachineBasicBlock &BB = *I.getParent();
19811994
return BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,17 @@ void addInstrRequirements(const MachineInstr &MI,
13761376
Reqs.addCapability(SPIRV::Capability::SplitBarrierINTEL);
13771377
}
13781378
break;
1379+
1380+
case SPIRV::OpKill: {
1381+
Reqs.addCapability(SPIRV::Capability::Shader);
1382+
} break;
1383+
case SPIRV::OpDemoteToHelperInvocation:
1384+
if (ST.canUseExtension(
1385+
SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
1386+
Reqs.addExtension(SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
1387+
Reqs.addCapability(SPIRV::Capability::DemoteToHelperInvocation);
1388+
}
1389+
break;
13791390
default:
13801391
break;
13811392
}

llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td

+1
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ defm VulkanMemoryModelDeviceScopeKHR : CapabilityOperand<5346, 0, 0, [], []>;
456456
defm ImageFootprintNV : CapabilityOperand<5282, 0, 0, [], []>;
457457
defm FragmentBarycentricNV : CapabilityOperand<5284, 0, 0, [], []>;
458458
defm ComputeDerivativeGroupQuadsNV : CapabilityOperand<5288, 0, 0, [], []>;
459+
defm DemoteToHelperInvocation : CapabilityOperand<5379, 0, 0, [SPV_EXT_demote_to_helper_invocation], []>;
459460
defm ComputeDerivativeGroupLinearNV : CapabilityOperand<5350, 0, 0, [], []>;
460461
defm FragmentDensityEXT : CapabilityOperand<5291, 0, 0, [], [Shader]>;
461462
defm PhysicalStorageBufferAddressesEXT : CapabilityOperand<5347, 0, 0, [], [Shader]>;

llvm/test/CodeGen/DirectX/clip.ll

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,29 @@
1-
; RUN: opt -S -dxil-intrinsic-expansion -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-pixel %s | FileCheck %s
1+
; RUN: opt -passes='function(scalarizer),module(dxil-op-lower,dxil-intrinsic-expansion)' -S -mtriple=dxil-pc-shadermodel6.3-pixel %s | FileCheck %s
22

3-
; CHECK-LABEL: define void @test_dxil_lowering
3+
; CHECK-LABEL: define void @test_scalar
44
; CHECK: call void @dx.op.discard(i32 82, i1 %0)
55
;
6-
define void @test_dxil_lowering(float noundef %p) #0 {
6+
define void @test_scalar(float noundef %p) #0 {
77
entry:
88
%0 = fcmp olt float %p, 0.000000e+00
99
call void @llvm.dx.clip(i1 %0)
1010
ret void
1111
}
12+
13+
; CHECK-LABEL: define void @test_vector
14+
; CHECK: [[EXTR0:%.*]] = extractelement <4 x i1> [[INP:%.*]], i64 0
15+
; CHECK-NEXT: [[EXTR1:%.*]] = extractelement <4 x i1> [[INP:%.*]], i64 1
16+
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[EXTR0]], [[EXTR1]]
17+
; CHECK-NEXT: [[EXTR2:%.*]] = extractelement <4 x i1> [[INP:%.*]], i64 2
18+
; CHECK-NEXT: [[OR2:%.*]] = or i1 [[OR1]], [[EXTR2]]
19+
; CHECK-NEXT: [[EXTR3:%.*]] = extractelement <4 x i1> [[INP:%.*]], i64 3
20+
; CHECK-NEXT: [[OR3:%.*]] = or i1 [[OR2]], [[EXTR3]]
21+
; CHECK-NEXT: call void @dx.op.discard(i32 82, i1 [[OR3]])
22+
;
23+
define void @test_vector(<4 x float> noundef %p) #0 {
24+
entry:
25+
%0 = fcmp olt <4 x float> %p, zeroinitializer
26+
%1 = call i1 @llvm.dx.any.v4i1(<4 x i1> %0)
27+
call void @llvm.dx.clip(i1 %1)
28+
ret void
29+
}

llvm/test/CodeGen/SPIRV/hlsl-intrinsics/clip.ll

+46-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,40 @@
1-
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
1+
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,SPIRV15
2+
; 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
23
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
34

45

5-
define void @test_scalar_lowering(float noundef %Buf) {
6+
; Make sure lowering is correctly generating spirv code.
7+
8+
; CHECK-DAG: %[[#float:]] = OpTypeFloat 32
9+
; CHECK-DAG: %[[#void:]] = OpTypeVoid
10+
; CHECK-DAG: %[[#bool:]] = OpTypeBool
11+
; CHECK-DAG: %[[#v4bool:]] = OpTypeVector %[[#bool]] 4
12+
; CHECK-DAG: %[[#v4float:]] = OpTypeVector %[[#float]] 4
13+
; CHECK-DAG: %[[#fzero:]] = OpConstant %[[#float]] 0
14+
; CHECK-DAG: %[[#v4fzero:]] = OpConstantNull %[[#v4float]]
15+
; SPIRV16-DAG: %[[#vecfuncopptr:]] = OpTypePointer Function %[[#v4float]]
16+
; SPIRV16-DAG: %[[#funcopptr:]] = OpTypePointer Function %[[#float]]
17+
18+
define void @test_scalar(float noundef %Buf) {
619
entry:
20+
; CHECK-LABEL: ; -- Begin function test_scalar
21+
; SPIRV16: %[[#param:]] = OpVariable %[[#funcopptr]] Function
22+
; SPIRV16: %[[#load:]] = OpLoad %[[#float]] %[[#param]] Aligned 4
23+
; SPIRV15: %[[#load:]] = OpFunctionParameter %[[#float]]
24+
; CHECK: %[[#cmplt:]] = OpFOrdLessThan %[[#bool]] %[[#load]] %[[#fzero]]
25+
; CHECK: OpBranchConditional %[[#cmplt]] %[[#truel:]] %[[#endl:]]
26+
; CHECK: %[[#truel]] = OpLabel
27+
; SPIRV15: OpKill
28+
; SPIRV16-NO: OpKill
29+
; SPIRV15-NO: OpBranch %[[#endl]]
30+
; SPIRV16: OpDemoteToHelperInvocation
31+
; SPIRV16: OpBranch %[[#endl]]
32+
; CHECK: %[[#endl]] = OpLabel
733
%Buf.addr = alloca float, align 4
834
store float %Buf, ptr %Buf.addr, align 4
9-
%0 = load float, ptr %Buf.addr, align 4
10-
%1 = fcmp olt float %0, 0.000000e+00
11-
br i1 %1, label %lt0, label %end
35+
%1 = load float, ptr %Buf.addr, align 4
36+
%2 = fcmp olt float %1, 0.000000e+00
37+
br i1 %2, label %lt0, label %end
1238

1339
lt0: ; preds = %entry
1440
call void @llvm.spv.clip()
@@ -17,17 +43,29 @@ lt0: ; preds = %entry
1743
end: ; preds = %lt0, %entry
1844
ret void
1945
}
20-
2146
declare void @llvm.spv.clip()
2247

23-
2448
define void @test_vector(<4 x float> noundef %Buf) {
2549
entry:
50+
; CHECK-LABEL: ; -- Begin function test_vector
51+
; SPIRV16: %[[#param:]] = OpVariable %[[#vecfuncopptr]] Function
52+
; SPIRV16: %[[#loadvec:]] = OpLoad %[[#v4float]] %[[#param]] Aligned 16
53+
; SPIRV15: %[[#loadvec:]] = OpFunctionParameter %[[#v4float]]
54+
; CHECK: %[[#cmplt:]] = OpFOrdLessThan %[[#v4bool]] %[[#loadvec]] %[[#v4fzero]]
55+
; CHECK: %[[#opany:]] = OpAny %[[#bool]] %[[#cmplt]]
56+
; CHECK: OpBranchConditional %[[#opany]] %[[#truel:]] %[[#endl:]]
57+
; CHECK: %[[#truel]] = OpLabel
58+
; SPIRV15: OpKill
59+
; SPIRV16-NO: OpKill
60+
; SPIRV15-NO: OpBranch %[[#endl]]
61+
; SPIRV16: OpDemoteToHelperInvocation
62+
; SPIRV16: OpBranch %[[#endl]]
63+
; CHECK: %[[#endl]] = OpLabel
2664
%Buf.addr = alloca <4 x float>, align 16
2765
store <4 x float> %Buf, ptr %Buf.addr, align 16
2866
%1 = load <4 x float>, ptr %Buf.addr, align 16
2967
%2 = fcmp olt <4 x float> %1, zeroinitializer
30-
%3 = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %2)
68+
%3 = call i1 @llvm.spv.any.v4i1(<4 x i1> %2)
3169
br i1 %3, label %lt0, label %end
3270

3371
lt0: ; preds = %entry
@@ -37,5 +75,3 @@ lt0: ; preds = %entry
3775
end: ; preds = %lt0, %entry
3876
ret void
3977
}
40-
41-
declare i1 @llvm.vector.reduce.or.v4i1(<4 x i1>) #3

0 commit comments

Comments
 (0)