llvm / llvm/llvm-project

[AMDGPU] Stop structurizing uniform control flow

Open
#204,334 3 comments 0 reactions 0 assignees View on GitHub
backend:AMDGPU test-suite
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

add64_in_branch in test/CodeGen/AMDGPU/add.ll is an example of a function with only uniform control flow. `opt -p="print"` reports `ALL VALUES UNIFORM` but `opt -structurizecfg` structurizes it by adding a "flow" block. Before:

```llvm
define amdgpu_kernel void @add64_in_branch(ptr addrspace(1) %out, ptr addrspace(1) %in, i64 %a, i64 %b, i64 %c) #0 {
entry:
%add64_in_branch.kernarg.segment = call nonnull align 16 dereferenceable(296) ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr()
%out.kernarg.offset = getelementptr inbounds i8, ptr addrspace(4) %add64_in_branch.kernarg.segment, i64 36
%0 = load <4 x i64>, ptr addrspace(4) %out.kernarg.offset, align 4, !invariant.load !0
%a.load3 = extractelement <4 x i64> %0, i32 2
%1 = icmp eq i64 %a.load3, 0
br i1 %1, label %if, label %else, !structurizecfg.uniform !0

if: ; preds = %entry
%in.load2 = extractelement <4 x i64> %0, i32 1
%2 = inttoptr i64 %in.load2 to ptr addrspace(1)
%3 = load i64, ptr addrspace(1) %2, align 4
br label %endif, !structurizecfg.uniform !0

else: ; preds = %entry
%b.load4 = extractelement <4 x i64> %0, i32 3
%4 = add i64 %a.load3, %b.load4
br label %endif, !structurizecfg.uniform !0

endif: ; preds = %else, %if
%5 = phi i64 [ %3, %if ], [ %4, %else ]
%out.load1 = extractelement <4 x i64> %0, i32 0
%6 = inttoptr i64 %out.load1 to ptr addrspace(1)
store i64 %5, ptr addrspace(1) %6, align 4
ret void
}
```

After:

```llvm
define amdgpu_kernel void @add64_in_branch(ptr addrspace(1) %out, ptr addrspace(1) %in, i64 %a, i64 %b, i64 %c) #0 {
entry:
%add64_in_branch.kernarg.segment = call nonnull align 16 dereferenceable(296) ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr()
%out.kernarg.offset = getelementptr inbounds i8, ptr addrspace(4) %add64_in_branch.kernarg.segment, i64 36
%0 = load <4 x i64>, ptr addrspace(4) %out.kernarg.offset, align 4, !invariant.load !0
%a.load3 = extractelement <4 x i64> %0, i32 2
%1 = icmp ne i64 %a.load3, 0
br i1 %1, label %else, label %Flow

Flow: ; preds = %else, %entry
%2 = phi i64 [ %6, %else ], [ poison, %entry ]
%3 = phi i1 [ false, %else ], [ true, %entry ]
br i1 %3, label %if, label %endif

if: ; preds = %Flow
%in.load2 = extractelement <4 x i64> %0, i32 1
%4 = inttoptr i64 %in.load2 to ptr addrspace(1)
%5 = load i64, ptr addrspace(1) %4, align 4
br label %endif

else: ; preds = %entry
%b.load4 = extractelement <4 x i64> %0, i32 3
%6 = add i64 %a.load3, %b.load4
br label %Flow

endif: ; preds = %if, %Flow
%7 = phi i64 [ %2, %Flow ], [ %5, %if ]
%out.load1 = extractelement <4 x i64> %0, i32 0
%8 = inttoptr i64 %out.load1 to ptr addrspace(1)
store i64 %7, ptr addrspace(1) %8, align 4
ret void
}
```

This seems pointless. There is no need to structurize uniform control flow.

There is previous work in this area: https://reviews.llvm.org/D40546 This patch added the option `-structurizecfg-skip-uniform-regions`. Maybe this should be on by default?

Contributor guide

Open the contributing guide

Research direction

Start with test/CodeGen/AMDGPU/add.ll and reproduce the output using opt -p="print" and opt -structurizecfg. Review the existing -structurizecfg-skip-uniform-regions option and prior work in D40546 to determine the intended default; done means uniform control flow is not given an unnecessary Flow block and the relevant tests verify the behavior.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.