This repository has been archived by the owner on Oct 9, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 60
Implemented conversion of llvm.bswap intrinsic to SPIR-V, closes #210 #221
Open
doe300
wants to merge
1
commit into
KhronosGroup:khronos/spirv-3.6.1
Choose a base branch
from
doe300:squashed_bswap
base: khronos/spirv-3.6.1
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
; RUN: llvm-as %s -o %t.bc | ||
; RUN: llvm-spirv %t.bc -spirv-text -o %t.txt | ||
; RUN: FileCheck < %t.txt %s --check-prefix=CHECK-SPIRV | ||
; RUN: llvm-spirv %t.bc -o %t.spv | ||
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc | ||
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM | ||
|
||
; CHECK-SPIRV-NOT: llvm.bswap | ||
|
||
; CHECK-SPIRV: ShiftLeftLogical [[shortType:[0-9]+]] [[tmpShort1:[0-9]+]] | ||
; CHECK-SPIRV: ShiftRightLogical [[shortType]] [[tmpShort2:[0-9]+]] | ||
; CHECK-SPIRV: BitwiseOr [[shortType]] {{[0-9]+}} [[tmpShort1]] [[tmpShort2]] | ||
|
||
; CHECK-SPIRV: ShiftLeftLogical [[intType:[0-9]+]] [[tmpInt1:[0-9]+]] | ||
; CHECK-SPIRV: ShiftLeftLogical [[intType]] [[tmpInt2:[0-9]+]] | ||
; CHECK-SPIRV: ShiftRightLogical [[intType]] [[tmpInt3:[0-9]+]] | ||
; CHECK-SPIRV: ShiftRightLogical [[intType]] [[tmpInt4:[0-9]+]] | ||
; CHECK-SPIRV: BitwiseAnd [[intType]] [[tmpInt5:[0-9]+]] [[tmpInt2]] | ||
; CHECK-SPIRV: BitwiseAnd [[intType]] [[tmpInt6:[0-9]+]] [[tmpInt3]] | ||
; CHECK-SPIRV: BitwiseOr [[intType]] [[tmpInt7:[0-9]+]] [[tmpInt1]] [[tmpInt5]] | ||
; CHECK-SPIRV: BitwiseOr [[intType]] [[tmpInt8:[0-9]+]] [[tmpInt6]] [[tmpInt4]] | ||
; CHECK-SPIRV: BitwiseOr [[intType]] {{[0-9]+}} [[tmpInt7]] [[tmpInt8]] | ||
|
||
; CHECK-SPIRV: ShiftLeftLogical [[longType:[0-9]+]] [[tmpLong1:[0-9]+]] | ||
; CHECK-SPIRV: ShiftLeftLogical [[longType]] [[tmpLong2:[0-9]+]] | ||
; CHECK-SPIRV: ShiftLeftLogical [[longType]] [[tmpLong3:[0-9]+]] | ||
; CHECK-SPIRV: ShiftLeftLogical [[longType]] [[tmpLong4:[0-9]+]] | ||
; CHECK-SPIRV: ShiftRightLogical [[longType]] [[tmpLong5:[0-9]+]] | ||
; CHECK-SPIRV: ShiftRightLogical [[longType]] [[tmpLong6:[0-9]+]] | ||
; CHECK-SPIRV: ShiftRightLogical [[longType]] [[tmpLong7:[0-9]+]] | ||
; CHECK-SPIRV: ShiftRightLogical [[longType]] [[tmpLong8:[0-9]+]] | ||
; CHECK-SPIRV: BitwiseAnd [[longType]] [[tmpLong9:[0-9]+]] [[tmpLong2]] | ||
; CHECK-SPIRV: BitwiseAnd [[longType]] [[tmpLong10:[0-9]+]] [[tmpLong3]] | ||
; CHECK-SPIRV: BitwiseAnd [[longType]] [[tmpLong11:[0-9]+]] [[tmpLong4]] | ||
; CHECK-SPIRV: BitwiseAnd [[longType]] [[tmpLong12:[0-9]+]] [[tmpLong5]] | ||
; CHECK-SPIRV: BitwiseAnd [[longType]] [[tmpLong13:[0-9]+]] [[tmpLong6]] | ||
; CHECK-SPIRV: BitwiseAnd [[longType]] [[tmpLong14:[0-9]+]] [[tmpLong7]] | ||
; CHECK-SPIRV: BitwiseOr [[longType]] [[tmpLong15:[0-9]+]] [[tmpLong1]] [[tmpLong9]] | ||
; CHECK-SPIRV: BitwiseOr [[longType]] [[tmpLong16:[0-9]+]] [[tmpLong10]] [[tmpLong11]] | ||
; CHECK-SPIRV: BitwiseOr [[longType]] [[tmpLong17:[0-9]+]] [[tmpLong12]] [[tmpLong13]] | ||
; CHECK-SPIRV: BitwiseOr [[longType]] [[tmpLong18:[0-9]+]] [[tmpLong14]] [[tmpLong8]] | ||
; CHECK-SPIRV: BitwiseOr [[longType]] [[tmpLong19:[0-9]+]] [[tmpLong15]] [[tmpLong16]] | ||
; CHECK-SPIRV: BitwiseOr [[longType]] [[tmpLong20:[0-9]+]] [[tmpLong17]] [[tmpLong18]] | ||
; CHECK-SPIRV: BitwiseOr [[longType]] {{[0-9]+}} [[tmpLong19]] [[tmpLong20]] | ||
|
||
|
||
; CHECK-LLVM-NOT: llvm.bswap | ||
|
||
; CHECK-LLVM: [[rShort1:%[0-9]+]] = shl i16 [[argShort:%[0-9a-z]+]], 8 | ||
; CHECK-LLVM: [[rShort2:%[0-9]+]] = lshr exact i16 [[argShort]], 8 | ||
; CHECK-LLVM: {{%[0-9a-z]+}} = or i16 [[rShort1]], [[rShort2]] | ||
|
||
; CHECK-LLVM: [[rInt1:%[0-9]+]] = shl i32 [[argInt:%[0-9a-z]+]], 24 | ||
; CHECK-LLVM: [[rInt2:%[0-9]+]] = shl i32 [[argInt]], 8 | ||
; CHECK-LLVM: [[rInt3:%[0-9]+]] = lshr exact i32 [[argInt]], 8 | ||
; CHECK-LLVM: [[rInt4:%[0-9]+]] = lshr exact i32 [[argInt]], 24 | ||
; CHECK-LLVM: [[rInt5:%[0-9]+]] = and i32 [[rInt2]], 16711680 | ||
; CHECK-LLVM: [[rInt6:%[0-9]+]] = and i32 [[rInt3]], 65280 | ||
; CHECK-LLVM: [[rInt7:%[0-9]+]] = or i32 [[rInt1]], [[rInt5]] | ||
; CHECK-LLVM: [[rInt8:%[0-9]+]] = or i32 [[rInt6]], [[rInt4]] | ||
; CHECK-LLVM: {{%[0-9a-z]+}} = or i32 [[rInt7]], [[rInt8]] | ||
|
||
; CHECK-LLVM: [[rLong1:%[0-9]+]] = shl i64 [[argLong:%[0-9a-z]+]], 56 | ||
; CHECK-LLVM: [[rLong2:%[0-9]+]] = shl i64 [[argLong]], 40 | ||
; CHECK-LLVM: [[rLong3:%[0-9]+]] = shl i64 [[argLong]], 24 | ||
; CHECK-LLVM: [[rLong4:%[0-9]+]] = shl i64 [[argLong]], 8 | ||
; CHECK-LLVM: [[rLong5:%[0-9]+]] = lshr exact i64 [[argLong]], 8 | ||
; CHECK-LLVM: [[rLong6:%[0-9]+]] = lshr exact i64 [[argLong]], 24 | ||
; CHECK-LLVM: [[rLong7:%[0-9]+]] = lshr exact i64 [[argLong]], 40 | ||
; CHECK-LLVM: [[rLong8:%[0-9]+]] = lshr exact i64 [[argLong]], 56 | ||
; CHECK-LLVM: [[rLong9:%[0-9]+]] = and i64 [[rLong2]], 71776119061217280 | ||
; CHECK-LLVM: [[rLong10:%[0-9]+]] = and i64 [[rLong3]], 280375465082880 | ||
; CHECK-LLVM: [[rLong11:%[0-9]+]] = and i64 [[rLong4]], 1095216660480 | ||
; CHECK-LLVM: [[rLong12:%[0-9]+]] = and i64 [[rLong5]], 4278190080 | ||
; CHECK-LLVM: [[rLong13:%[0-9]+]] = and i64 [[rLong6]], 16711680 | ||
; CHECK-LLVM: [[rLong14:%[0-9]+]] = and i64 [[rLong7]], 65280 | ||
; CHECK-LLVM: [[rLong15:%[0-9]+]] = or i64 [[rLong1]], [[rLong9]] | ||
; CHECK-LLVM: [[rLong16:%[0-9]+]] = or i64 [[rLong10]], [[rLong11]] | ||
; CHECK-LLVM: [[rLong17:%[0-9]+]] = or i64 [[rLong12]], [[rLong13]] | ||
; CHECK-LLVM: [[rLong18:%[0-9]+]] = or i64 [[rLong14]], [[rLong8]] | ||
; CHECK-LLVM: [[rLong19:%[0-9]+]] = or i64 [[rLong15]], [[rLong16]] | ||
; CHECK-LLVM: [[rLong20:%[0-9]+]] = or i64 [[rLong17]], [[rLong18]] | ||
; CHECK-LLVM: {{%[0-9a-z]+}} = or i64 [[rLong19]], [[rLong20]] | ||
|
||
|
||
|
||
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-n8:16:32:64" | ||
target triple = "spir-unknown-unknown" | ||
|
||
declare i16 @llvm.bswap.i16(i16) | ||
declare i32 @llvm.bswap.i32(i32) | ||
declare i64 @llvm.bswap.i64(i64) | ||
|
||
define i16 @test_bswap_i16(i16 %a) { | ||
%bswap = call i16 @llvm.bswap.i16(i16 %a) | ||
ret i16 %bswap | ||
} | ||
|
||
define i32 @test_bswap_i32(i32 %a) { | ||
%bswap = call i32 @llvm.bswap.i32(i32 %a) | ||
ret i32 %bswap | ||
} | ||
|
||
define i64 @test_bswap_i64(i64 %a) { | ||
%bswap = call i64 @llvm.bswap.i64(i64 %a) | ||
ret i64 %bswap | ||
} | ||
|
||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } | ||
attributes #1 = { nounwind } | ||
|
||
!opencl.enable.FP_CONTRACT = !{} | ||
!opencl.spir.version = !{!7} | ||
!opencl.ocl.version = !{!7} | ||
!opencl.used.extensions = !{!8} | ||
!opencl.used.optional.core.features = !{!8} | ||
!opencl.compiler.options = !{!8} | ||
!llvm.ident = !{!9} | ||
|
||
!7 = !{i32 1, i32 2} | ||
!8 = !{} | ||
!9 = !{!"clang version 3.6.1 (https://github.com/KhronosGroup/SPIR d7e44c3b27581e54ca0e522987d1ade2bd29b70d) (https://github.com/KhronosGroup/SPIRV-LLVM.git d42743684ea8338358504e44ef8363b9dc675c66)"} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function does not guarantee the uniqueness of the constant, e.g., you can create two SPIR-V constants with different id's but the same value if you called it twice. Therefore it is users' responsibility to maintain the uniqueness of the constants. When it is called during LLVM/SPIR-V translation it is fine since a map is used to maintain the uniqueness. However it is not suitable to be used to create SPIR-V on the fly.
Ideally, it is desired to improve addConstant so that uniqueness is maintained, e.g. by using the LLVM FoldingSet.
A temporary workaround may be to create the LLVM constant first, then translate it to SPIR-V.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would implement the uniqueness of constants via a map (
uint64_t
to SPIRVValue*) or a set of SPIRVValue* values, which can be checked by addConstant whether a constant already exists and then either inserting a new one or returning the existing.Is there any reason, you would prefer a LLVM FoldingSet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LLVM FoldingSet is a more generic solution. By implementing profile of a SPIRV entity, we can make any SPIRV entity unique, e.g. SpecConstantOp. Similar approach can be extended to SPIRV types and attributes. Essentially this can open the door for a generic solution of uniqueness for other SPIRV entities.
In the beginning, the SPIRV in-memory representation was designed to be independent of LLVM, in the hope of being useful to projects that do not want to depend on LLVM. However, it seems this restriction is not so useful and unnecessarily limits the utility available. Therefore I would like to allow SPIRV in-memory representation to use LLVM utilities.