Skip to content

Commit

Permalink
Translate ctlz/cttz intrinsics to OpExtInst
Browse files Browse the repository at this point in the history
LLVM transformation passes may introduce calls to these intrinsics and
supporting them in the translator also allows using GCC/Clang builtins
`__builtin_clz` and `__builtin_ctz`.

Fixes #303
  • Loading branch information
svenvh committed Sep 3, 2019
1 parent e807452 commit 87028d0
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,15 @@ SPIRVValue *LLVMToSPIRV::transIntrinsicInst(IntrinsicInst *II,
SPIRVValue *Op = transValue(II->getArgOperand(0), BB);
return BM->addUnaryInst(OpBitReverse, Ty, Op, BB);
}
case Intrinsic::ctlz:
case Intrinsic::cttz: {
SPIRVWord ExtOp = II->getIntrinsicID() == Intrinsic::ctlz ? OpenCLLIB::Clz
: OpenCLLIB::Ctz;
SPIRVType *Ty = transType(II->getType());
std::vector<SPIRVValue *> Ops(1, transValue(II->getArgOperand(0), BB));
return BM->addExtInst(Ty, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops,
BB);
}
case Intrinsic::fmuladd: {
// For llvm.fmuladd.* fusion is not guaranteed. If a fused multiply-add
// is required the corresponding llvm.fma.* intrinsic function should be
Expand Down
62 changes: 62 additions & 0 deletions test/count-zero-bits.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s
; RUN: llvm-spirv %t.bc -o %t.spv
; RUN: spirv-val %t.spv

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
target triple = "spir64-unknown-unknown"

; CHECK: ExtInstImport [[extinst_id:[0-9]+]] "OpenCL.std"

; CHECK: Function
; CHECK: 6 ExtInst {{[0-9]+}} {{[0-9]+}} [[extinst_id]] clz
; CHECK: FunctionEnd

; Function Attrs: nounwind readnone
define spir_func i32 @TestClz(i32 %x) local_unnamed_addr #0 {
entry:
%0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
ret i32 %0
}

; CHECK: Function
; CHECK: 6 ExtInst {{[0-9]+}} {{[0-9]+}} [[extinst_id]] ctz
; CHECK: FunctionEnd

; Function Attrs: nounwind readnone
define spir_func i32 @TestCtz(i32 %x) local_unnamed_addr #0 {
entry:
%0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
ret i32 %0
}

; CHECK: Function
; CHECK: 6 ExtInst {{[0-9]+}} {{[0-9]+}} [[extinst_id]] ctz
; CHECK: FunctionEnd

; Function Attrs: nounwind readnone
define spir_func <4 x i32> @TestCtzVec(<4 x i32> %x) local_unnamed_addr #0 {
entry:
%0 = tail call <4 x i32> @llvm.cttz.v4i32(<4 x i32> %x, i1 true)
ret <4 x i32> %0
}

; Function Attrs: nounwind readnone speculatable willreturn
declare i32 @llvm.ctlz.i32(i32, i1 immarg) #1

; Function Attrs: nounwind readnone speculatable willreturn
declare i32 @llvm.cttz.i32(i32, i1 immarg) #1

; Function Attrs: nounwind readnone speculatable willreturn
declare <4 x i32> @llvm.cttz.v4i32(<4 x i32>, i1 immarg) #1

attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "denorms-are-zero"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone speculatable willreturn }

!llvm.module.flags = !{!0}
!opencl.ocl.version = !{!1}
!opencl.spir.version = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, i32 0}
!2 = !{i32 1, i32 2}

0 comments on commit 87028d0

Please sign in to comment.