Skip to content

Commit 85dc1ee

Browse files
spirv-val: Add OpSpecConstantOp for Arithmetics and Bitwise (KhronosGroup#6582)
another chunk of KhronosGroup#6564 adds `ArithmeticsPass` and `BitwisePass`
1 parent 281fecf commit 85dc1ee

3 files changed

Lines changed: 201 additions & 16 deletions

File tree

source/val/validate_arithmetics.cpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
namespace spvtools {
2525
namespace val {
2626

27-
spv_result_t ValidateFloat(ValidationState_t& _, const Instruction* inst) {
27+
spv_result_t ValidateFloat(ValidationState_t& _, const Instruction* inst,
28+
uint32_t starting_index = 2) {
2829
const spv::Op opcode = inst->opcode();
2930
const uint32_t result_type = inst->type_id();
3031
bool supportsCoopMat =
@@ -42,8 +43,8 @@ spv_result_t ValidateFloat(ValidationState_t& _, const Instruction* inst) {
4243
<< "Expected floating scalar or vector type as Result Type: "
4344
<< spvOpcodeString(opcode);
4445

45-
for (size_t operand_index = 2; operand_index < inst->operands().size();
46-
++operand_index) {
46+
for (size_t operand_index = starting_index;
47+
operand_index < inst->operands().size(); ++operand_index) {
4748
if (supportsCoopVec && _.IsCooperativeVectorNVType(result_type)) {
4849
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
4950
if (!_.IsCooperativeVectorNVType(type_id)) {
@@ -73,8 +74,8 @@ spv_result_t ValidateFloat(ValidationState_t& _, const Instruction* inst) {
7374
return SPV_SUCCESS;
7475
}
7576

76-
spv_result_t ValidateUnsignedInt(ValidationState_t& _,
77-
const Instruction* inst) {
77+
spv_result_t ValidateUnsignedInt(ValidationState_t& _, const Instruction* inst,
78+
uint32_t starting_index = 2) {
7879
const spv::Op opcode = inst->opcode();
7980
const uint32_t result_type = inst->type_id();
8081
bool supportsCoopMat = (opcode == spv::Op::OpUDiv);
@@ -87,8 +88,8 @@ spv_result_t ValidateUnsignedInt(ValidationState_t& _,
8788
<< "Expected unsigned int scalar or vector type as Result Type: "
8889
<< spvOpcodeString(opcode);
8990

90-
for (size_t operand_index = 2; operand_index < inst->operands().size();
91-
++operand_index) {
91+
for (size_t operand_index = starting_index;
92+
operand_index < inst->operands().size(); ++operand_index) {
9293
if (supportsCoopVec && _.IsCooperativeVectorNVType(result_type)) {
9394
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
9495
if (!_.IsCooperativeVectorNVType(type_id)) {
@@ -119,7 +120,8 @@ spv_result_t ValidateUnsignedInt(ValidationState_t& _,
119120
return SPV_SUCCESS;
120121
}
121122

122-
spv_result_t ValidateSignedInt(ValidationState_t& _, const Instruction* inst) {
123+
spv_result_t ValidateSignedInt(ValidationState_t& _, const Instruction* inst,
124+
uint32_t starting_index = 2) {
123125
const spv::Op opcode = inst->opcode();
124126
const uint32_t result_type = inst->type_id();
125127
bool supportsCoopMat =
@@ -140,8 +142,8 @@ spv_result_t ValidateSignedInt(ValidationState_t& _, const Instruction* inst) {
140142
const uint32_t dimension = _.GetDimension(result_type);
141143
const uint32_t bit_width = _.GetBitWidth(result_type);
142144

143-
for (size_t operand_index = 2; operand_index < inst->operands().size();
144-
++operand_index) {
145+
for (size_t operand_index = starting_index;
146+
operand_index < inst->operands().size(); ++operand_index) {
145147
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
146148

147149
if (supportsCoopVec && _.IsCooperativeVectorNVType(result_type)) {
@@ -884,6 +886,33 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
884886
return ValidateCooperativeMatrixMulAddKHR(_, inst);
885887
case spv::Op::OpCooperativeMatrixReduceNV:
886888
return ValidateCooperativeMatrixReduceNV(_, inst);
889+
890+
case spv::Op::OpSpecConstantOp: {
891+
switch (inst->GetOperandAs<spv::Op>(2u)) {
892+
case spv::Op::OpFAdd:
893+
case spv::Op::OpFSub:
894+
case spv::Op::OpFMul:
895+
case spv::Op::OpFDiv:
896+
case spv::Op::OpFRem:
897+
case spv::Op::OpFMod:
898+
case spv::Op::OpFNegate:
899+
return ValidateFloat(_, inst, 3);
900+
case spv::Op::OpUDiv:
901+
case spv::Op::OpUMod:
902+
return ValidateUnsignedInt(_, inst, 3);
903+
case spv::Op::OpISub:
904+
case spv::Op::OpIAdd:
905+
case spv::Op::OpIMul:
906+
case spv::Op::OpSDiv:
907+
case spv::Op::OpSMod:
908+
case spv::Op::OpSRem:
909+
case spv::Op::OpSNegate:
910+
return ValidateSignedInt(_, inst, 3);
911+
default:
912+
break;
913+
}
914+
break;
915+
}
887916
default:
888917
break;
889918
}

source/val/validate_bitwise.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ spv_result_t ValidateBaseType(ValidationState_t& _, const Instruction* inst,
5757
return SPV_SUCCESS;
5858
}
5959

60-
spv_result_t ValidateShift(ValidationState_t& _, const Instruction* inst) {
60+
spv_result_t ValidateShift(ValidationState_t& _, const Instruction* inst,
61+
uint32_t starting_index = 2) {
6162
const spv::Op opcode = inst->opcode();
6263
const uint32_t result_type = inst->type_id();
6364
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
@@ -67,8 +68,8 @@ spv_result_t ValidateShift(ValidationState_t& _, const Instruction* inst) {
6768
<< spvOpcodeString(opcode);
6869

6970
const uint32_t result_dimension = _.GetDimension(result_type);
70-
const uint32_t base_type = _.GetOperandTypeId(inst, 2);
71-
const uint32_t shift_type = _.GetOperandTypeId(inst, 3);
71+
const uint32_t base_type = _.GetOperandTypeId(inst, starting_index);
72+
const uint32_t shift_type = _.GetOperandTypeId(inst, starting_index + 1);
7273

7374
if (!base_type ||
7475
(!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type) &&
@@ -101,7 +102,8 @@ spv_result_t ValidateShift(ValidationState_t& _, const Instruction* inst) {
101102
return SPV_SUCCESS;
102103
}
103104

104-
spv_result_t ValidateBitwise(ValidationState_t& _, const Instruction* inst) {
105+
spv_result_t ValidateBitwise(ValidationState_t& _, const Instruction* inst,
106+
uint32_t starting_index = 2) {
105107
const spv::Op opcode = inst->opcode();
106108
const uint32_t result_type = inst->type_id();
107109
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
@@ -113,8 +115,8 @@ spv_result_t ValidateBitwise(ValidationState_t& _, const Instruction* inst) {
113115
const uint32_t result_dimension = _.GetDimension(result_type);
114116
const uint32_t result_bit_width = _.GetBitWidth(result_type);
115117

116-
for (size_t operand_index = 2; operand_index < inst->operands().size();
117-
++operand_index) {
118+
for (size_t operand_index = starting_index;
119+
operand_index < inst->operands().size(); ++operand_index) {
118120
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
119121
if (!type_id ||
120122
(!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id) &&
@@ -245,6 +247,24 @@ spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
245247
return ValidateBitReverse(_, inst);
246248
case spv::Op::OpBitCount:
247249
return ValidateBitCount(_, inst);
250+
251+
case spv::Op::OpSpecConstantOp: {
252+
switch (inst->GetOperandAs<spv::Op>(2u)) {
253+
case spv::Op::OpShiftRightLogical:
254+
case spv::Op::OpShiftRightArithmetic:
255+
case spv::Op::OpShiftLeftLogical:
256+
return ValidateShift(_, inst, 3);
257+
case spv::Op::OpBitwiseOr:
258+
case spv::Op::OpBitwiseXor:
259+
case spv::Op::OpBitwiseAnd:
260+
case spv::Op::OpNot:
261+
return ValidateBitwise(_, inst, 3);
262+
default:
263+
break;
264+
}
265+
break;
266+
}
267+
248268
default:
249269
break;
250270
}

test/val/val_constants_test.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,142 @@ INSTANTIATE_TEST_SUITE_P(
584584
"Expected float scalar or vector type as Result Type"),
585585
BAD_KERNEL_OPERANDS("%v = OpSpecConstantOp %float ConvertUToF %float_0",
586586
"Expected input to be int scalar or vector"),
587+
588+
BAD_KERNEL_OPERANDS(
589+
"%v = OpSpecConstantOp %float UDiv %uint_0 %uint_0",
590+
"Expected unsigned int scalar or vector type as Result Type"),
591+
BAD_KERNEL_OPERANDS(
592+
"%v = OpSpecConstantOp %uint UDiv %uint_0 %float_0",
593+
"Expected arithmetic operands to be of Result Type"),
594+
595+
BAD_KERNEL_OPERANDS(
596+
"%v = OpSpecConstantOp %float UMod %uint_0 %uint_0",
597+
"Expected unsigned int scalar or vector type as Result Type"),
598+
BAD_KERNEL_OPERANDS(
599+
"%v = OpSpecConstantOp %uint UMod %uint_0 %float_0",
600+
"Expected arithmetic operands to be of Result Type"),
601+
602+
BAD_KERNEL_OPERANDS(
603+
"%v = OpSpecConstantOp %float ISub %uint_0 %uint_0",
604+
"Expected int scalar or vector type as Result Type"),
605+
BAD_KERNEL_OPERANDS("%v = OpSpecConstantOp %uint ISub %uint_0 %float_0",
606+
"Expected int scalar or vector type as operand"),
607+
608+
BAD_KERNEL_OPERANDS(
609+
"%v = OpSpecConstantOp %float IAdd %uint_0 %uint_0",
610+
"Expected int scalar or vector type as Result Type"),
611+
BAD_KERNEL_OPERANDS("%v = OpSpecConstantOp %uint IAdd %uint_0 %float_0",
612+
"Expected int scalar or vector type as operand"),
613+
614+
BAD_KERNEL_OPERANDS(
615+
"%v = OpSpecConstantOp %float IMul %uint_0 %uint_0",
616+
"Expected int scalar or vector type as Result Type"),
617+
BAD_KERNEL_OPERANDS("%v = OpSpecConstantOp %uint IMul %uint_0 %float_0",
618+
"Expected int scalar or vector type as operand"),
619+
620+
BAD_KERNEL_OPERANDS(
621+
"%v = OpSpecConstantOp %float SDiv %uint_0 %uint_0",
622+
"Expected int scalar or vector type as Result Type"),
623+
BAD_KERNEL_OPERANDS("%v = OpSpecConstantOp %uint SDiv %uint_0 %float_0",
624+
"Expected int scalar or vector type as operand"),
625+
626+
BAD_KERNEL_OPERANDS(
627+
"%v = OpSpecConstantOp %float SRem %uint_0 %uint_0",
628+
"Expected int scalar or vector type as Result Type"),
629+
BAD_KERNEL_OPERANDS("%v = OpSpecConstantOp %uint SRem %uint_0 %float_0",
630+
"Expected int scalar or vector type as operand"),
631+
632+
BAD_KERNEL_OPERANDS(
633+
"%v = OpSpecConstantOp %float SMod %uint_0 %uint_0",
634+
"Expected int scalar or vector type as Result Type"),
635+
BAD_KERNEL_OPERANDS("%v = OpSpecConstantOp %uint SMod %uint_0 %float_0",
636+
"Expected int scalar or vector type as operand"),
637+
638+
BAD_KERNEL_OPERANDS(
639+
"%v = OpSpecConstantOp %float SNegate %uint_0",
640+
"Expected int scalar or vector type as Result Type"),
641+
BAD_KERNEL_OPERANDS("%v = OpSpecConstantOp %uint SNegate %float_0",
642+
"Expected int scalar or vector type as operand"),
643+
644+
BAD_KERNEL_OPERANDS(
645+
"%v = OpSpecConstantOp %uint FAdd %float_0 %float_0",
646+
"Expected floating scalar or vector type as Result Type"),
647+
BAD_KERNEL_OPERANDS(
648+
"%v = OpSpecConstantOp %float FAdd %float_0 %uint_0",
649+
"Expected arithmetic operands to be of Result Type"),
650+
BAD_KERNEL_OPERANDS(
651+
"%v = OpSpecConstantOp %uint FSub %float_0 %float_0",
652+
"Expected floating scalar or vector type as Result Type"),
653+
BAD_KERNEL_OPERANDS(
654+
"%v = OpSpecConstantOp %float FSub %float_0 %uint_0",
655+
"Expected arithmetic operands to be of Result Type"),
656+
BAD_KERNEL_OPERANDS(
657+
"%v = OpSpecConstantOp %uint FMul %float_0 %float_0",
658+
"Expected floating scalar or vector type as Result Type"),
659+
BAD_KERNEL_OPERANDS(
660+
"%v = OpSpecConstantOp %float FMul %float_0 %uint_0",
661+
"Expected arithmetic operands to be of Result Type"),
662+
BAD_KERNEL_OPERANDS(
663+
"%v = OpSpecConstantOp %uint FDiv %float_0 %float_0",
664+
"Expected floating scalar or vector type as Result Type"),
665+
BAD_KERNEL_OPERANDS(
666+
"%v = OpSpecConstantOp %float FDiv %float_0 %uint_0",
667+
"Expected arithmetic operands to be of Result Type"),
668+
BAD_KERNEL_OPERANDS(
669+
"%v = OpSpecConstantOp %uint FRem %float_0 %float_0",
670+
"Expected floating scalar or vector type as Result Type"),
671+
BAD_KERNEL_OPERANDS(
672+
"%v = OpSpecConstantOp %float FRem %float_0 %uint_0",
673+
"Expected arithmetic operands to be of Result Type"),
674+
BAD_KERNEL_OPERANDS(
675+
"%v = OpSpecConstantOp %uint FMod %float_0 %float_0",
676+
"Expected floating scalar or vector type as Result Type"),
677+
BAD_KERNEL_OPERANDS(
678+
"%v = OpSpecConstantOp %float FMod %float_0 %uint_0",
679+
"Expected arithmetic operands to be of Result Type"),
680+
681+
BAD_KERNEL_OPERANDS(
682+
"%v = OpSpecConstantOp %float ShiftRightLogical %uint_0 %uint_0",
683+
"Expected int scalar or vector type as Result Type"),
684+
BAD_KERNEL_OPERANDS(
685+
"%v = OpSpecConstantOp %uint ShiftRightLogical %uint_0 %float_0",
686+
"Expected Shift to be int scalar or vector"),
687+
BAD_KERNEL_OPERANDS(
688+
"%v = OpSpecConstantOp %float ShiftRightArithmetic %uint_0 %uint_0",
689+
"Expected int scalar or vector type as Result Type"),
690+
BAD_KERNEL_OPERANDS(
691+
"%v = OpSpecConstantOp %uint ShiftRightArithmetic %uint_0 %float_0",
692+
"Expected Shift to be int scalar or vector"),
693+
BAD_KERNEL_OPERANDS(
694+
"%v = OpSpecConstantOp %float ShiftLeftLogical %uint_0 %uint_0",
695+
"Expected int scalar or vector type as Result Type"),
696+
BAD_KERNEL_OPERANDS(
697+
"%v = OpSpecConstantOp %uint ShiftLeftLogical %uint_0 %float_0",
698+
"Expected Shift to be int scalar or vector"),
699+
700+
BAD_KERNEL_OPERANDS(
701+
"%v = OpSpecConstantOp %float BitwiseOr %uint_0 %uint_0",
702+
"Expected int scalar or vector type as Result Type"),
703+
BAD_KERNEL_OPERANDS(
704+
"%v = OpSpecConstantOp %uint BitwiseOr %uint_0 %float_0",
705+
"Expected int scalar or vector as operand"),
706+
BAD_KERNEL_OPERANDS(
707+
"%v = OpSpecConstantOp %float BitwiseXor %uint_0 %uint_0",
708+
"Expected int scalar or vector type as Result Type"),
709+
BAD_KERNEL_OPERANDS(
710+
"%v = OpSpecConstantOp %uint BitwiseXor %uint_0 %float_0",
711+
"Expected int scalar or vector as operand"),
712+
BAD_KERNEL_OPERANDS(
713+
"%v = OpSpecConstantOp %float BitwiseAnd %uint_0 %uint_0",
714+
"Expected int scalar or vector type as Result Type"),
715+
BAD_KERNEL_OPERANDS(
716+
"%v = OpSpecConstantOp %uint BitwiseAnd %uint_0 %float_0",
717+
"Expected int scalar or vector as operand"),
718+
BAD_KERNEL_OPERANDS(
719+
"%v = OpSpecConstantOp %float Not %uint_0",
720+
"Expected int scalar or vector type as Result Type"),
721+
BAD_KERNEL_OPERANDS("%v = OpSpecConstantOp %uint Not %float_0",
722+
"Expected int scalar or vector as operand"),
587723
}));
588724

589725
} // namespace

0 commit comments

Comments
 (0)