1; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv1.5-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=spirv1.5-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,SPIRV16,WITH-EXTENSION,WITH-CAPABILITY 3; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv1.6-unknown-unknown %s -o - | FileCheck %s --check-prefixes=CHECK,SPIRV16,WITH-CAPABILITY 4; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %} 5; RUN: %if spirv-tools %{ llc -O0 -spirv-ext=+SPV_EXT_demote_to_helper_invocation -mtriple=spirv1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %} 6; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.6-unknown-unknown %s -o - -filetype=obj | spirv-val %} 7 8 9; Make sure lowering is correctly generating spirv code. 10 11; WITH-CAPABILITY-DAG: OpCapability DemoteToHelperInvocation 12; WITH-EXTENSION-DAG: OpExtension "SPV_EXT_demote_to_helper_invocation" 13 14; CHECK-DAG: %[[#float:]] = OpTypeFloat 32 15; CHECK-DAG: %[[#void:]] = OpTypeVoid 16; CHECK-DAG: %[[#bool:]] = OpTypeBool 17; CHECK-DAG: %[[#v4bool:]] = OpTypeVector %[[#bool]] 4 18; CHECK-DAG: %[[#v4float:]] = OpTypeVector %[[#float]] 4 19; CHECK-DAG: %[[#fzero:]] = OpConstant %[[#float]] 0 20; CHECK-DAG: %[[#v4fzero:]] = OpConstantNull %[[#v4float]] 21 22define void @test_scalar(float noundef %Buf) { 23entry: 24; CHECK-LABEL: ; -- Begin function test_scalar 25; CHECK: %[[#load:]] = OpFunctionParameter %[[#float]] 26; CHECK: %[[#cmplt:]] = OpFOrdLessThan %[[#bool]] %[[#load]] %[[#fzero]] 27; CHECK: OpBranchConditional %[[#cmplt]] %[[#truel:]] %[[#endl:]] 28; CHECK: %[[#truel]] = OpLabel 29; SPIRV15: OpKill 30; SPIRV16-NO: OpKill 31; SPIRV15-NO: OpBranch %[[#endl]] 32; SPIRV16: OpDemoteToHelperInvocation 33; SPIRV16: OpBranch %[[#endl]] 34; CHECK: %[[#endl]] = OpLabel 35 %Buf.addr = alloca float, align 4 36 store float %Buf, ptr %Buf.addr, align 4 37 %1 = load float, ptr %Buf.addr, align 4 38 %2 = fcmp olt float %1, 0.000000e+00 39 br i1 %2, label %lt0, label %end 40 41lt0: ; preds = %entry 42 call void @llvm.spv.discard() 43 br label %end 44 45end: ; preds = %lt0, %entry 46 ret void 47} 48declare void @llvm.spv.discard() 49 50define void @test_vector(<4 x float> noundef %Buf) { 51entry: 52; CHECK-LABEL: ; -- Begin function test_vector 53; CHECK: %[[#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 64 %Buf.addr = alloca <4 x float>, align 16 65 store <4 x float> %Buf, ptr %Buf.addr, align 16 66 %1 = load <4 x float>, ptr %Buf.addr, align 16 67 %2 = fcmp olt <4 x float> %1, zeroinitializer 68 %3 = call i1 @llvm.spv.any.v4i1(<4 x i1> %2) 69 br i1 %3, label %lt0, label %end 70 71lt0: ; preds = %entry 72 call void @llvm.spv.discard() 73 br label %end 74 75end: ; preds = %lt0, %entry 76 ret void 77} 78