Skip to content

Commit c687b91

Browse files
authored
Fix translation of relational operations (#1409)
Whereas it is not possible to generate vector of bools in FE, we have to change return type for corresponding instructions in SPIRV translator to vector of bools. SPIRV translator already did this for some instructions, this patch extends this behaviour to handle more instructions.
1 parent 017af4e commit c687b91

File tree

3 files changed

+74
-6
lines changed

3 files changed

+74
-6
lines changed

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,24 +2390,31 @@ LLVMToSPIRV::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
23902390
if (isCvtOpCode(OC) && OC != OpGenericCastToPtrExplicit) {
23912391
return BM->addUnaryInst(OC, transType(CI->getType()),
23922392
transValue(CI->getArgOperand(0), BB), BB);
2393-
} else if (isCmpOpCode(OC)) {
2394-
assert(CI && CI->getNumArgOperands() == 2 && "Invalid call inst");
2393+
} else if (isCmpOpCode(OC) || isUnaryPredicateOpCode(OC)) {
23952394
auto ResultTy = CI->getType();
23962395
Type *BoolTy = IntegerType::getInt1Ty(M->getContext());
23972396
auto IsVector = ResultTy->isVectorTy();
23982397
if (IsVector)
23992398
BoolTy = VectorType::get(BoolTy, ResultTy->getVectorNumElements());
24002399
auto BBT = transType(BoolTy);
2401-
auto Cmp = BM->addCmpInst(OC, BBT, transValue(CI->getArgOperand(0), BB),
2402-
transValue(CI->getArgOperand(1), BB), BB);
2400+
SPIRVInstruction *Res;
2401+
if (isCmpOpCode(OC)) {
2402+
assert(CI && CI->getNumArgOperands() == 2 && "Invalid call inst");
2403+
Res = BM->addCmpInst(OC, BBT, transValue(CI->getArgOperand(0), BB),
2404+
transValue(CI->getArgOperand(1), BB), BB);
2405+
} else {
2406+
assert(CI && CI->getNumArgOperands() == 1 && "Invalid call inst");
2407+
Res =
2408+
BM->addUnaryInst(OC, BBT, transValue(CI->getArgOperand(0), BB), BB);
2409+
}
24032410
// OpenCL C and OpenCL C++ built-ins may have different return type
24042411
if (ResultTy == BoolTy)
2405-
return Cmp;
2412+
return Res;
24062413
assert(IsVector || (!IsVector && ResultTy->isIntegerTy(32)));
24072414
auto Zero = transValue(Constant::getNullValue(ResultTy), BB);
24082415
auto One = transValue(
24092416
IsVector ? Constant::getAllOnesValue(ResultTy) : getInt32(M, 1), BB);
2410-
return BM->addSelectInst(Cmp, One, Zero, BB);
2417+
return BM->addSelectInst(Res, One, Zero, BB);
24112418
} else if (isBinaryOpCode(OC)) {
24122419
assert(CI && CI->getNumArgOperands() == 2 && "Invalid call inst");
24132420
return BM->addBinaryInst(OC, transType(CI->getType()),

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ inline bool isLogicalOpCode(Op OpCode) {
7474
return (unsigned)OpCode >= OpLogicalEqual && (unsigned)OpCode <= OpLogicalNot;
7575
}
7676

77+
inline bool isUnaryPredicateOpCode(Op OpCode) {
78+
return (unsigned)OpCode >= OpAny && (unsigned)OpCode <= OpSignBitSet;
79+
}
80+
7781
inline bool isBitwiseOpCode(Op OpCode) {
7882
return (unsigned)OpCode >= OpBitwiseOr && (unsigned)OpCode <= OpBitwiseAnd;
7983
}

llvm-spirv/test/relationals.ll

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
3+
; RUN: llvm-spirv %t.bc -o %t.spv
4+
; RUN: spirv-val %t.spv
5+
6+
target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
7+
target triple = "spir"
8+
9+
declare dso_local spir_func <4 x i8> @_Z13__spirv_IsNanIDv4_aDv4_fET_T0_(<4 x float>)
10+
declare dso_local spir_func <4 x i8> @_Z13__spirv_IsInfIDv4_aDv4_fET_T0_(<4 x float>)
11+
declare dso_local spir_func <4 x i8> @_Z16__spirv_IsFiniteIDv4_aDv4_fET_T0_(<4 x float>)
12+
declare dso_local spir_func <4 x i8> @_Z16__spirv_IsNormalIDv4_aDv4_fET_T0_(<4 x float>)
13+
declare dso_local spir_func <4 x i8> @_Z18__spirv_SignBitSetIDv4_aDv4_fET_T0_(<4 x float>)
14+
15+
; CHECK-SPIRV: {{[0-9]+}} TypeBool [[TBool:[0-9]+]]
16+
; CHECK-SPIRV: {{[0-9]+}} TypeVector [[TBoolVec:[0-9]+]] [[TBool]]
17+
18+
; Function Attrs: nounwind readnone
19+
define spir_kernel void @k() #0 !kernel_arg_addr_space !0 !kernel_arg_access_qual !0 !kernel_arg_type !0 !kernel_arg_base_type !0 !kernel_arg_type_qual !0 {
20+
entry:
21+
%arg1 = alloca <4 x float>, align 16
22+
%ret = alloca <4 x i8>, align 4
23+
%0 = load <4 x float>, <4 x float>* %arg1, align 16
24+
%call1 = call spir_func <4 x i8> @_Z13__spirv_IsNanIDv4_aDv4_fET_T0_(<4 x float> %0)
25+
; CHECK-SPIRV: {{[0-9]+}} IsNan [[TBoolVec]] [[IsNanRes:[0-9]+]]
26+
; CHECK-SPIRV: {{[0-9]+}} Select {{[0-9]+}} [[SelectRes:[0-9]+]] [[IsNanRes]]
27+
; CHECK-SPIRV: {{[0-9]+}} Store {{[0-9]+}} [[SelectRes]]
28+
store <4 x i8> %call1, <4 x i8>* %ret, align 4
29+
%call2 = call spir_func <4 x i8> @_Z13__spirv_IsInfIDv4_aDv4_fET_T0_(<4 x float> %0)
30+
; CHECK-SPIRV: {{[0-9]+}} IsInf [[TBoolVec]] [[IsInfRes:[0-9]+]]
31+
; CHECK-SPIRV: {{[0-9]+}} Select {{[0-9]+}} [[Select1Res:[0-9]+]] [[IsInfRes]]
32+
; CHECK-SPIRV: {{[0-9]+}} Store {{[0-9]+}} [[Select1Res]]
33+
store <4 x i8> %call2, <4 x i8>* %ret, align 4
34+
%call3 = call spir_func <4 x i8> @_Z16__spirv_IsFiniteIDv4_aDv4_fET_T0_(<4 x float> %0)
35+
; CHECK-SPIRV: {{[0-9]+}} IsFinite [[TBoolVec]] [[IsFiniteRes:[0-9]+]]
36+
; CHECK-SPIRV: {{[0-9]+}} Select {{[0-9]+}} [[Select2Res:[0-9]+]] [[IsFiniteRes]]
37+
; CHECK-SPIRV: {{[0-9]+}} Store {{[0-9]+}} [[Select2Res]]
38+
store <4 x i8> %call3, <4 x i8>* %ret, align 4
39+
%call4 = call spir_func <4 x i8> @_Z16__spirv_IsNormalIDv4_aDv4_fET_T0_(<4 x float> %0)
40+
; CHECK-SPIRV: {{[0-9]+}} IsNormal [[TBoolVec]] [[IsNormalRes:[0-9]+]]
41+
; CHECK-SPIRV: {{[0-9]+}} Select {{[0-9]+}} [[Select3Res:[0-9]+]] [[IsNormalRes]]
42+
; CHECK-SPIRV: {{[0-9]+}} Store {{[0-9]+}} [[Select3Res]]
43+
store <4 x i8> %call4, <4 x i8>* %ret, align 4
44+
%call5 = call spir_func <4 x i8> @_Z18__spirv_SignBitSetIDv4_aDv4_fET_T0_(<4 x float> %0)
45+
; CHECK-SPIRV: {{[0-9]+}} SignBitSet [[TBoolVec]] [[SignBitSetRes:[0-9]+]]
46+
; CHECK-SPIRV: {{[0-9]+}} Select {{[0-9]+}} [[Select4Res:[0-9]+]] [[SignBitSetRes]]
47+
; CHECK-SPIRV: {{[0-9]+}} Store {{[0-9]+}} [[Select4Res]]
48+
store <4 x i8> %call5, <4 x i8>* %ret, align 4
49+
ret void
50+
}
51+
52+
!llvm.module.flags = !{!1}
53+
!opencl.spir.version = !{!2}
54+
55+
!0 = !{}
56+
!1 = !{i32 1, !"wchar_size", i32 4}
57+
!2 = !{i32 1, i32 2}

0 commit comments

Comments
 (0)