Skip to content

Commit b0e975c

Browse files
authored
[SPIR-V] Reland "Fix OpGroupNonUniformBroadcast version requirement" (#16854)
For SPIR-V 1.4 and earlier, the Id operand of OpGroupNonUniformBroadcast must come from a constant instruction. Ensure that any emitted SPIR-V module using a non-constant Id operand declares SPIR-V version 1.5. Bail out if the maximum SPIR-V version was restricted to < 1.5, to avoid producing invalid SPIR-V. Original commit: KhronosGroup/SPIRV-LLVM-Translator@64fe75e388dc3b7 This reverts commit bbf3800 The reland is possible after switch to SPIR-V 1.5
1 parent 71ca51f commit b0e975c

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ class SPIRVInstTemplateBase : public SPIRVInstruction {
298298

299299
/// Get operand as value.
300300
/// If the operand is a literal, return it as a uint32 constant.
301+
const SPIRVValue *getOpValue(int I) const {
302+
return isOperandLiteral(I) ? Module->getLiteralAsConstant(Ops[I])
303+
: getValue(Ops[I]);
304+
}
305+
301306
SPIRVValue *getOpValue(int I) {
302307
return isOperandLiteral(I) ? Module->getLiteralAsConstant(Ops[I])
303308
: getValue(Ops[I]);
@@ -318,6 +323,9 @@ class SPIRVInstTemplateBase : public SPIRVInstruction {
318323
return Operands;
319324
}
320325

326+
virtual const SPIRVValue *getOperand(unsigned I) const {
327+
return getOpValue(I);
328+
}
321329
virtual SPIRVValue *getOperand(unsigned I) { return getOpValue(I); }
322330

323331
bool hasExecScope() const { return SPIRV::hasExecScope(OpCode); }
@@ -2711,6 +2719,22 @@ class SPIRVGroupNonUniformBallotInst : public SPIRVInstTemplateBase {
27112719
SPIRVCapVec getRequiredCapability() const override {
27122720
return getVec(CapabilityGroupNonUniformBallot);
27132721
}
2722+
2723+
VersionNumber getRequiredSPIRVVersion() const override {
2724+
switch (OpCode) {
2725+
case OpGroupNonUniformBroadcast: {
2726+
assert(Ops.size() == 3 && "Expecting (Execution, Value, Id) operands");
2727+
if (!isConstantOpCode(getOperand(2)->getOpCode())) {
2728+
// Before version 1.5, Id must come from a constant instruction.
2729+
return VersionNumber::SPIRV_1_5;
2730+
}
2731+
break;
2732+
}
2733+
default:
2734+
break;
2735+
}
2736+
return VersionNumber::SPIRV_1_3;
2737+
}
27142738
};
27152739

27162740
#define _SPIRV_OP(x, ...) \

llvm-spirv/test/transcoding/OpLessOrGreater.ll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
; TODO: Re-enable this test when support for SPIRV 1.5 is enabled.
2-
; XFAIL:*
31
; RUN: llvm-as %s -o %t.bc
42
; RUN: llvm-spirv %t.bc -o %t.spv
53
; RUN: llvm-spirv %t.spv -to-text -o %t.spt
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %clang_cc1 -triple spir-unknown-unknown -O1 -cl-std=CL2.0 -fdeclare-opencl-builtins -finclude-default-header -emit-llvm-bc %s -o %t.bc
2+
// RUN: not llvm-spirv --spirv-max-version=1.4 %t.bc 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
3+
// RUN: llvm-spirv %t.bc -o %t.spv
4+
// RUN: spirv-val %t.spv
5+
// RUN: llvm-spirv -r %t.spv -o %t.rev.bc
6+
// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
7+
8+
// Before SPIR-V 1.5, the Id operand of OpGroupNonUniformBroadcast must come from a constant instruction.
9+
// CHECK-ERROR: RequiresVersion: Cannot fulfill SPIR-V version restriction:
10+
// CHECK-ERROR-NEXT: SPIR-V version was restricted to at most 1.4 (66560) but a construct from the input requires SPIR-V version 1.5 (66816) or above
11+
12+
// CHECK-LLVM-LABEL: @test
13+
// CHECK-LLVM: call spir_func i16 @_Z31sub_group_non_uniform_broadcasttj(i16 %a, i32 %id)
14+
15+
kernel void test(short a, uint id, global short *res) {
16+
res[0] = sub_group_non_uniform_broadcast(a, id);
17+
}

0 commit comments

Comments
 (0)