Skip to content

Inliner: Fails to remap callee block entry ID when splitting for multi-return callee case #790

@dneto0

Description

@dneto0

This can cause a dominance error in a Phi inside the cloned callee.

I found this by inspection while working on #787

Example input:

               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %1 "main"
               OpSource OpenCL_C 120
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
      %int_1 = OpConstant %int 1
      %int_2 = OpConstant %int 2
      %int_3 = OpConstant %int 3
      %int_4 = OpConstant %int 4
       %void = OpTypeVoid

          %9 = OpTypeFunction %void
         %10 = OpFunction %void None %9
         %11 = OpLabel
         %12 = OpCopyObject %int %int_0
               OpBranch %13
         %13 = OpLabel
         %14 = OpPhi %int %12 %11
         %15 = OpCopyObject %int %int_1
               OpReturn
         %16 = OpLabel
         %17 = OpCopyObject %int %int_2
               OpReturn

               OpFunctionEnd
          %1 = OpFunction %void None %9
         %18 = OpLabel
         %19 = OpCopyObject %int %int_3
         %20 = OpFunctionCall %void %10
         %21 = OpCopyObject %int %int_4
               OpReturn
               OpFunctionEnd

The function %9 has multiple returns, and is called from entry point %1. So when inlining we make a single-trip loop to enclose the cloned callee.
The result of inlining is:

               OpCapability Shader
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %1 "main"
               OpSource OpenCL_C 120
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
      %int_1 = OpConstant %int 1
      %int_2 = OpConstant %int 2
      %int_3 = OpConstant %int 3
      %int_4 = OpConstant %int 4
       %void = OpTypeVoid
          %9 = OpTypeFunction %void
       %bool = OpTypeBool
      %false = OpConstantFalse %bool
         %10 = OpFunction %void None %9
         %11 = OpLabel
         %12 = OpCopyObject %int %int_0
               OpBranch %13
         %13 = OpLabel
         %14 = OpPhi %int %12 %11
         %15 = OpCopyObject %int %int_1
               OpReturn
         %16 = OpLabel
         %17 = OpCopyObject %int %int_2
               OpReturn
               OpFunctionEnd
          %1 = OpFunction %void None %9
         %18 = OpLabel
         %19 = OpCopyObject %int %int_3
               OpBranch %22
         %22 = OpLabel
               OpLoopMerge %23 %24 None
               OpBranch %25
         %25 = OpLabel
         %26 = OpCopyObject %int %int_0
               OpBranch %27
         %27 = OpLabel
         %28 = OpPhi %int %26 %18  ; This is wrong. %18 is not a parent of %27
         %29 = OpCopyObject %int %int_1
               OpBranch %23
         %30 = OpLabel
         %31 = OpCopyObject %int %int_2
               OpBranch %23
         %24 = OpLabel
               OpBranchConditional %false %22 %23
         %23 = OpLabel
         %21 = OpCopyObject %int %int_4
               OpReturn
               OpFunctionEnd

The problem is the Phi yielding %28. The %18 block is not even a parent. Instead we should use %25 as the parent.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions