Skip to content

Commit bec81d1

Browse files
committed
Do not truncate subgroup return value
Various SPIR-V subgroup operations return a boolean value, whereas the equivalent OpenCL builtins return a zero or non-zero integer value. Until now, the SPIR-V to OpenCL conversion would yield a truncate to convert from integer to boolean, which is incorrect because any non-zero integer value should be treated as a "true" value. Use a compare for the conversion instead. Also rename the helper function to reflect better what it does and add some comments.
1 parent 2a9faf7 commit bec81d1

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

lib/SPIRV/SPIRVToOCL.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,9 @@ std::string SPIRVToOCL::groupOCToOCLBuiltinName(CallInst *CI, Op OC) {
381381
return FuncName;
382382
}
383383

384-
static bool extendRetTyToi32(Op OC) {
384+
/// Return true if the original boolean return type needs to be changed to i32
385+
/// when mapping the SPIR-V op to an OpenCL builtin.
386+
static bool needsInt32RetTy(Op OC) {
385387
return OC == OpGroupAny || OC == OpGroupAll || OC == OpGroupNonUniformAny ||
386388
OC == OpGroupNonUniformAll || OC == OpGroupNonUniformAllEqual ||
387389
OC == OpGroupNonUniformElect || OC == OpGroupNonUniformInverseBallot ||
@@ -408,15 +410,17 @@ void SPIRVToOCL::visitCallSPIRVGroupBuiltin(CallInst *CI, Op OC) {
408410
Args[0] = CastInst::CreateZExtOrBitCast(Args[0], Int32Ty, "", CI);
409411

410412
// Handle function return type
411-
if (extendRetTyToi32(OC))
413+
if (needsInt32RetTy(OC))
412414
RetTy = Int32Ty;
413415

414416
return FuncName;
415417
};
416418
auto ModifyRetTy = [=](CallInst *CI) -> Instruction * {
417-
if (extendRetTyToi32(OC)) {
418-
Type *RetTy = Type::getInt1Ty(*Ctx);
419-
return CastInst::CreateTruncOrBitCast(CI, RetTy, "", CI->getNextNode());
419+
if (needsInt32RetTy(OC)) {
420+
// The OpenCL builtin returns a non-zero integer value. Convert to a
421+
// boolean value.
422+
Constant *Zero = ConstantInt::get(CI->getType(), 0);
423+
return new ICmpInst(CI->getNextNode(), CmpInst::ICMP_NE, CI, Zero);
420424
} else
421425
return CI;
422426
};

test/transcoding/sub_group_ballot.ll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,8 +1054,10 @@ declare dso_local spir_func double @_Z25sub_group_broadcast_firstd(double) local
10541054

10551055
; CHECK-LLVM-LABEL: @testBallotOperations
10561056
; CHECK-LLVM: %[[ballot:[0-9]+]] = call spir_func <4 x i32> @_Z16sub_group_balloti(i32 {{.*}})
1057-
; CHECK-LLVM: call spir_func i32 @_Z24sub_group_inverse_ballotDv4_j(<4 x i32> %[[ballot]])
1058-
; CHECK-LLVM: call spir_func i32 @_Z28sub_group_ballot_bit_extractDv4_jj(<4 x i32> %[[ballot]], i32 0)
1057+
; CHECK-LLVM: %[[inverse_ballot:[0-9]+]] = call spir_func i32 @_Z24sub_group_inverse_ballotDv4_j(<4 x i32> %[[ballot]])
1058+
; CHECK-LLVM-NEXT: icmp ne i32 %[[inverse_ballot]], 0
1059+
; CHECK-LLVM: %[[bit_extract:[0-9]+]] = call spir_func i32 @_Z28sub_group_ballot_bit_extractDv4_jj(<4 x i32> %[[ballot]], i32 0)
1060+
; CHECK-LLVM-NEXT: icmp ne i32 %[[bit_extract]], 0
10591061
; CHECK-LLVM: call spir_func i32 @_Z26sub_group_ballot_bit_countDv4_j(<4 x i32> %[[ballot]])
10601062
; CHECK-LLVM: call spir_func i32 @_Z31sub_group_ballot_inclusive_scanDv4_j(<4 x i32> %[[ballot]])
10611063
; CHECK-LLVM: call spir_func i32 @_Z31sub_group_ballot_exclusive_scanDv4_j(<4 x i32> %[[ballot]])

0 commit comments

Comments
 (0)