diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index fb7a66f85..16e753c33 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3059,12 +3059,15 @@ static void validatePhiPredecessors(Function *F) { for (PHINode &Phi : BB.phis()) { SmallVector Vs; SmallVector Bs; + SmallPtrSet UsedB; auto Vals = Phi.incoming_values(); auto Blocks = Phi.blocks(); auto *VIt = Vals.begin(); auto *BIt = Blocks.begin(); for (; VIt != Vals.end() && BIt != Blocks.end(); ++VIt, ++BIt) { const unsigned N = PredsCnt[*BIt]; + if (!UsedB.insert(*BIt).second) + continue; Vs.insert(Vs.end(), N, *VIt); Bs.insert(Bs.end(), N, *BIt); } diff --git a/test/phi-multiple-predecessors-invalid-input.spvasm b/test/phi-multiple-predecessors-invalid-input.spvasm new file mode 100644 index 000000000..f786293f4 --- /dev/null +++ b/test/phi-multiple-predecessors-invalid-input.spvasm @@ -0,0 +1,41 @@ +; The goal of the test case is to ensure that PHI node has an incoming value per each predecessor +; instance even if the input SPIR-V module is invalid as reported by spirv-val. + +; We don't run spirv-val on this module therefore. + +; REQUIRES: spirv-as +; RUN: spirv-as --target-env spv1.0 -o %t.spv %s +; RUN: llvm-spirv -r -o - %t.spv | llvm-dis | FileCheck %s + + OpCapability Kernel + OpCapability Addresses + OpCapability Int64 + OpCapability Linkage + %1 = OpExtInstImport "OpenCL.std" + OpMemoryModel Physical64 OpenCL + OpSource OpenCL_CPP 100000 + OpName %foo "foo" + OpName %get "get" + OpDecorate %foo LinkageAttributes "foo" Export + OpDecorate %get LinkageAttributes "get" Import + %uint = OpTypeInt 32 0 + %3 = OpTypeFunction %uint + %ulong = OpTypeInt 64 0 + %uint_2 = OpConstant %uint 2 + %uint_4 = OpConstant %uint 4 + %get = OpFunction %uint None %3 + OpFunctionEnd + %foo = OpFunction %uint None %3 + %11 = OpLabel + %9 = OpFunctionCall %uint %get + OpSwitch %9 %12 10 %13 4 %13 0 %13 42 %13 + %12 = OpLabel + OpBranch %13 + %13 = OpLabel + %10 = OpPhi %uint %uint_4 %11 %uint_4 %11 %uint_4 %11 %uint_4 %11 %uint_2 %12 + %14 = OpPhi %uint %uint_2 %12 %uint_4 %11 %uint_4 %11 %uint_4 %11 %uint_4 %11 + OpReturnValue %14 + OpFunctionEnd + +; CHECK: phi i32 [ 4, %0 ], [ 4, %0 ], [ 4, %0 ], [ 4, %0 ], [ 2, %2 ] +; CHECK: phi i32 [ 2, %2 ], [ 4, %0 ], [ 4, %0 ], [ 4, %0 ], [ 4, %0 ]