diff options
author | Florian Ziesche <florian.ziesche@gmail.com> | 2016-06-10 19:38:08 +0200 |
---|---|---|
committer | Yaxun (Sam) Liu <yaxun.liu@amd.com> | 2016-06-10 13:38:08 -0400 |
commit | 9235f5e6fa60aaec0cd602ef7ffc5bc152ee2a53 (patch) | |
tree | 8208318bc92b5b168f4c7e3531f0d7b8501a0557 | |
parent | 38e4d01b1dcc1adc4fd7d492030ee6977a954433 (diff) |
extractvalue/insertvalue handling (#154)
* * fixed translation between LLVM extractvalue/insertvalue instructions and SPIR-V OpCompositeExtract/OpCompositeInsert
* * added extractvalue/insertvalue test (LLVM <-> SPIR-V transcoding)
-rw-r--r-- | lib/SPIRV/SPIRVReader.cpp | 33 | ||||
-rw-r--r-- | lib/SPIRV/SPIRVWriter.cpp | 14 | ||||
-rw-r--r-- | test/transcoding/extract_insert_value.ll | 96 |
3 files changed, 132 insertions, 11 deletions
diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 0908f74..f2a71c6 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -1574,13 +1574,18 @@ SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, case OpCompositeExtract: {
SPIRVCompositeExtract *CE = static_cast<SPIRVCompositeExtract *>(BV);
- assert(CE->getComposite()->getType()->isTypeVector() && "Invalid type");
- assert(CE->getIndices().size() == 1 && "Invalid index");
+ if (CE->getComposite()->getType()->isTypeVector()) {
+ assert(CE->getIndices().size() == 1 && "Invalid index");
+ return mapValue(
+ BV, ExtractElementInst::Create(
+ transValue(CE->getComposite(), F, BB),
+ ConstantInt::get(*Context, APInt(32, CE->getIndices()[0])),
+ BV->getName(), BB));
+ }
return mapValue(
- BV, ExtractElementInst::Create(
+ BV, ExtractValueInst::Create(
transValue(CE->getComposite(), F, BB),
- ConstantInt::get(*Context, APInt(32, CE->getIndices()[0])),
- BV->getName(), BB));
+ CE->getIndices(), BV->getName(), BB));
}
case OpVectorExtractDynamic: {
@@ -1589,18 +1594,24 @@ SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F, BV, ExtractElementInst::Create(transValue(CE->getVector(), F, BB),
transValue(CE->getIndex(), F, BB),
BV->getName(), BB));
- }
+ }
case OpCompositeInsert: {
auto CI = static_cast<SPIRVCompositeInsert *>(BV);
- assert(CI->getComposite()->getType()->isTypeVector() && "Invalid type");
- assert(CI->getIndices().size() == 1 && "Invalid index");
+ if (CI->getComposite()->getType()->isTypeVector()) {
+ assert(CI->getIndices().size() == 1 && "Invalid index");
+ return mapValue(
+ BV, InsertElementInst::Create(
+ transValue(CI->getComposite(), F, BB),
+ transValue(CI->getObject(), F, BB),
+ ConstantInt::get(*Context, APInt(32, CI->getIndices()[0])),
+ BV->getName(), BB));
+ }
return mapValue(
- BV, InsertElementInst::Create(
+ BV, InsertValueInst::Create(
transValue(CI->getComposite(), F, BB),
transValue(CI->getObject(), F, BB),
- ConstantInt::get(*Context, APInt(32, CI->getIndices()[0])),
- BV->getName(), BB));
+ CI->getIndices(), BV->getName(), BB));
}
case OpVectorInsertDynamic: {
diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index d4576e4..8d2ebae 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -1004,6 +1004,20 @@ LLVMToSPIRV::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB, BB));
}
+ if (auto Ext = dyn_cast<ExtractValueInst>(V)) {
+ return mapValue(V, BM->addCompositeExtractInst(
+ transType(Ext->getType()),
+ transValue(Ext->getAggregateOperand(), BB),
+ Ext->getIndices(), BB));
+ }
+
+ if (auto Ins = dyn_cast<InsertValueInst>(V)) {
+ return mapValue(V, BM->addCompositeInsertInst(
+ transValue(Ins->getInsertedValueOperand(), BB),
+ transValue(Ins->getAggregateOperand(), BB),
+ Ins->getIndices(), BB));
+ }
+
if (UnaryInstruction *U = dyn_cast<UnaryInstruction>(V)) {
if(isSamplerInitializer(U))
return mapValue(V, transValue(U->getOperand(0), BB));
diff --git a/test/transcoding/extract_insert_value.ll b/test/transcoding/extract_insert_value.ll new file mode 100644 index 0000000..73bb9e2 --- /dev/null +++ b/test/transcoding/extract_insert_value.ll @@ -0,0 +1,96 @@ +; ModuleID = '' +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" +target triple = "spir-unknown-unknown" + +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -spirv-text -o %t.spt +; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV +; RUN: llvm-spirv %t.bc -o %t.spv +; RUN: llvm-spirv -r %t.spv -o %t.bc +; RUN: llvm-dis < %t.bc | FileCheck %s --check-prefix=CHECK-LLVM + +; Check 'LLVM ==> SPIR-V ==> LLVM' conversion of extractvalue/insertvalue. + +%struct.arr = type { [7 x float] } +%struct.st = type { %struct.inner } +%struct.inner = type { float } +; CHECK-LLVM: %struct.arr = type { [7 x float] } +; CHECK-LLVM: %struct.st = type { %struct.inner } +; CHECK-LLVM: %struct.inner = type { float } + +; CHECK-LLVM: define spir_func void @array_test +; CHECK-LLVM-LABEL: entry +; CHECK-LLVM: %0 = getelementptr inbounds %struct.arr addrspace(1)* %object, i32 0, i32 0 +; CHECK-LLVM: %1 = load [7 x float] addrspace(1)* %0, align 4 +; CHECK-LLVM: %2 = extractvalue [7 x float] %1, 4 +; CHECK-LLVM: %3 = extractvalue [7 x float] %1, 2 +; CHECK-LLVM: %4 = fadd float %2, %3 +; CHECK-LLVM: %5 = insertvalue [7 x float] %1, float %4, 5 +; CHECK-LLVM: store [7 x float] %5, [7 x float] addrspace(1)* %0 + +; CHECK-SPIRV-LABEL: 5 Function +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[object:[0-9]+]] +; CHECK-SPIRV: 6 InBoundsPtrAccessChain {{[0-9]+}} {{[0-9]+}} [[object]] {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV: 6 Load {{[0-9]+}} [[extracted_array:[0-9]+]] {{[0-9]+}} {{[0-9]+}} 4 +; CHECK-SPIRV: 5 CompositeExtract {{[0-9]+}} [[elem_4:[0-9]+]] [[extracted_array]] 4 +; CHECK-SPIRV: 5 CompositeExtract {{[0-9]+}} [[elem_2:[0-9]+]] [[extracted_array]] 2 +; CHECK-SPIRV: 5 FAdd {{[0-9]+}} [[add:[0-9]+]] [[elem_4]] [[elem_2]] +; CHECK-SPIRV: 6 CompositeInsert {{[0-9]+}} [[inserted_array:[0-9]+]] [[add]] [[extracted_array]] 5 +; CHECK-SPIRV: 3 Store {{[0-9]+}} [[inserted_array]] +; CHECK-SPIRV-LABEL: 1 FunctionEnd + +; Function Attrs: nounwind +define spir_func void @array_test(%struct.arr addrspace(1)* %object) #0 { +entry: + %0 = getelementptr inbounds %struct.arr addrspace(1)* %object, i32 0, i32 0 + %1 = load [7 x float] addrspace(1)* %0, align 4 + %2 = extractvalue [7 x float] %1, 4 + %3 = extractvalue [7 x float] %1, 2 + %4 = fadd float %2, %3 + %5 = insertvalue [7 x float] %1, float %4, 5 + store [7 x float] %5, [7 x float] addrspace(1)* %0 + ret void +} + +; CHECK-LLVM: define spir_func void @struct_test +; CHECK-LLVM-LABEL: entry +; CHECK-LLVM: %0 = getelementptr inbounds %struct.st addrspace(1)* %object, i32 0, i32 0 +; CHECK-LLVM: %1 = load %struct.inner addrspace(1)* %0, align 4 +; CHECK-LLVM: %2 = extractvalue %struct.inner %1, 0 +; CHECK-LLVM: %3 = fadd float %2, 1.000000e+00 +; CHECK-LLVM: %4 = insertvalue %struct.inner %1, float %3, 0 +; CHECK-LLVM: store %struct.inner %4, %struct.inner addrspace(1)* %0 + +; CHECK-SPIRV-LABEL: 5 Function +; CHECK-SPIRV-NEXT: FunctionParameter {{[0-9]+}} [[object:[0-9]+]] +; CHECK-SPIRV: 6 InBoundsPtrAccessChain {{[0-9]+}} {{[0-9]+}} [[object]] {{[0-9]+}} {{[0-9]+}} +; CHECK-SPIRV: 6 Load {{[0-9]+}} [[extracted_struct:[0-9]+]] {{[0-9]+}} {{[0-9]+}} 4 +; CHECK-SPIRV: 5 CompositeExtract {{[0-9]+}} [[elem:[0-9]+]] [[extracted_struct]] 0 +; CHECK-SPIRV: 5 FAdd {{[0-9]+}} [[add:[0-9]+]] [[elem]] {{[0-9]+}} +; CHECK-SPIRV: 6 CompositeInsert {{[0-9]+}} [[inserted_struct:[0-9]+]] [[add]] [[extracted_struct]] 0 +; CHECK-SPIRV: 3 Store {{[0-9]+}} [[inserted_struct]] +; CHECK-SPIRV-LABEL: 1 FunctionEnd + +; Function Attrs: nounwind +define spir_func void @struct_test(%struct.st addrspace(1)* %object) #0 { +entry: + %0 = getelementptr inbounds %struct.st addrspace(1)* %object, i32 0, i32 0 + %1 = load %struct.inner addrspace(1)* %0, align 4 + %2 = extractvalue %struct.inner %1, 0 + %3 = fadd float %2, 1.000000e+00 + %4 = insertvalue %struct.inner %1, float %3, 0 + store %struct.inner %4, %struct.inner addrspace(1)* %0 + ret void +} + +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" } + +!opencl.enable.FP_CONTRACT = !{} +!opencl.spir.version = !{!0} +!opencl.ocl.version = !{!0} +!opencl.used.extensions = !{!1} +!opencl.used.optional.core.features = !{!1} +!opencl.compiler.options = !{!1} + +!0 = !{i32 1, i32 2} +!1 = !{}
\ No newline at end of file |