[PATCH] D52221: require lower-switch in preISel passes for AMDGPU

Sameer Sahasrabuddhe via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 18 01:06:06 PDT 2018


sameerds created this revision.
sameerds added a reviewer: arsenm.
Herald added subscribers: llvm-commits, t-tye, tpr, dstuttard, yaxunl, nhaehnle, wdng, jvesely, kzhuravl.

The default target of the switch instruction may sometimes be an
"unreachable" block, when it is guaranteed that one of the cases is
always taken. The dominator tree concludes that such a switch
instruction does not have an immediate post dominator. This confuses
divergence analysis, which is unable to propagate sync dependence to
the targets of the switch instruction.

As a workaround, the AMDGPU target now invokes lower-switch as a
preISel pass. LowerSwitch is designed to handle the unreachable
default target correctly, allowing the divergence analysis to locate
the correct immediate dominator of the now-lowered switch.


Repository:
  rL LLVM

https://reviews.llvm.org/D52221

Files:
  lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
  lib/Transforms/Scalar/StructurizeCFG.cpp
  test/CodeGen/AMDGPU/diverge-switch-default.ll


Index: test/CodeGen/AMDGPU/diverge-switch-default.ll
===================================================================
--- /dev/null
+++ test/CodeGen/AMDGPU/diverge-switch-default.ll
@@ -0,0 +1,58 @@
+; RUN: llc -march=amdgcn -mcpu=gfx900 -print-after=si-annotate-control-flow %s -o /dev/null 2>&1 | FileCheck %s
+
+target triple = "amdgcn--"
+
+; CHECK-LABEL: @switch_unreachable_default
+
+define amdgpu_kernel void @switch_unreachable_default(i32 addrspace(1)* %out, i8 addrspace(1)* %in0, i8 addrspace(1)* %in1) #0 {
+centry:
+  %tid = call i32 @llvm.amdgcn.workitem.id.x()
+  switch i32 %tid, label %sw.default [
+    i32 0, label %sw.bb0
+    i32 1, label %sw.bb1
+  ]
+
+sw.bb0:
+  br label %sw.epilog
+
+sw.bb1:
+  br label %sw.epilog
+
+sw.default:
+  unreachable
+
+sw.epilog:
+  %ptr = phi i8 addrspace(1)* [%in0, %sw.bb0], [%in1, %sw.bb1]
+  %gep_in = getelementptr inbounds i8, i8 addrspace(1)* %ptr, i64 0
+  br label %sw.while
+
+; The loop below is necessary to preserve the effect of the
+; unreachable default on divergence analysis in the presence of other
+; optimizations.
+
+; CHECK: load i8
+; CHECK-NOT: {{ br }}
+; CHECK: icmp eq
+; CHECK-NOT: {{ br }}
+; CHECK: @llvm.amdgcn.if
+
+sw.while:
+  %p = phi i8 addrspace(1)* [ %gep_in, %sw.epilog ], [ %incdec.ptr, %sw.while ]
+  %count = phi i32 [ 0, %sw.epilog ], [ %count.inc, %sw.while ]
+  %char = load i8, i8 addrspace(1)* %p, align 1
+  %tobool = icmp eq i8 %char, 0
+  %incdec.ptr = getelementptr inbounds i8, i8 addrspace(1)* %p, i64 1
+  %count.inc = add i32 %count, 1
+  br i1 %tobool, label %sw.exit, label %sw.while
+
+sw.exit:
+  %tid64 = zext i32 %tid to i64
+  %gep_out = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 %tid64
+  store i32 %count, i32 addrspace(1)* %gep_out, align 4
+  ret void
+}
+
+declare i32 @llvm.amdgcn.workitem.id.x() #0
+
+attributes #0 = { nounwind readnone }
+attributes #1 = { convergent noinline optnone }
Index: lib/Transforms/Scalar/StructurizeCFG.cpp
===================================================================
--- lib/Transforms/Scalar/StructurizeCFG.cpp
+++ lib/Transforms/Scalar/StructurizeCFG.cpp
@@ -275,6 +275,7 @@
     AU.addRequired<LoopInfoWrapperPass>();
 
     AU.addPreserved<DominatorTreeWrapperPass>();
+    AU.addPreservedID(LowerSwitchID);
     RegionPass::getAnalysisUsage(AU);
   }
 };
Index: lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
===================================================================
--- lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -45,6 +45,7 @@
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Scalar/GVN.h"
+#include "llvm/Transforms/Utils.h"
 #include "llvm/Transforms/Vectorize.h"
 #include <memory>
 
@@ -678,6 +679,7 @@
 }
 
 bool AMDGPUPassConfig::addPreISel() {
+  addPass(&LowerSwitchID);
   addPass(createFlattenCFGPass());
   return false;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52221.165900.patch
Type: text/x-patch
Size: 2945 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180918/14a8f3b5/attachment.bin>


More information about the llvm-commits mailing list