[AMDGPU] Re-enabling divergence predicates for min/max
authoralex-t <alexander.timofeev@amd.com>
Fri, 17 Dec 2021 17:42:00 +0000 (20:42 +0300)
committeralex-t <alexander.timofeev@amd.com>
Mon, 20 Dec 2021 13:10:55 +0000 (16:10 +0300)
This patch enables divergence predicates for min/max nodes.
It makes ISD::MIN/MAX selected to S_MIN_I(U)32/S_MAX_I(U)32 or V_MIN_I(U)32_e64/V_MAX_I(U)32_e64

Reviewed By: rampitec

Differential Revision: https://reviews.llvm.org/D115954

llvm/lib/Target/AMDGPU/SOPInstructions.td
llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll [new file with mode: 0755]

index 3354cbd..15f7491 100644 (file)
@@ -486,19 +486,18 @@ def S_SUBB_U32 : SOP2_32 <"s_subb_u32",
   [(set i32:$sdst, (UniformBinFrag<sube> (i32 SSrc_b32:$src0), (i32 SSrc_b32:$src1)))]>;
 } // End Uses = [SCC]
 
-
 let isCommutable = 1 in {
 def S_MIN_I32 : SOP2_32 <"s_min_i32",
-  [(set i32:$sdst, (smin i32:$src0, i32:$src1))]
+  [(set i32:$sdst, (UniformBinFrag<smin> i32:$src0, i32:$src1))]
 >;
 def S_MIN_U32 : SOP2_32 <"s_min_u32",
-  [(set i32:$sdst, (umin i32:$src0, i32:$src1))]
+  [(set i32:$sdst, (UniformBinFrag<umin> i32:$src0, i32:$src1))]
 >;
 def S_MAX_I32 : SOP2_32 <"s_max_i32",
-  [(set i32:$sdst, (smax i32:$src0, i32:$src1))]
+  [(set i32:$sdst, (UniformBinFrag<smax> i32:$src0, i32:$src1))]
 >;
 def S_MAX_U32 : SOP2_32 <"s_max_u32",
-  [(set i32:$sdst, (umax i32:$src0, i32:$src1))]
+  [(set i32:$sdst, (UniformBinFrag<umax> i32:$src0, i32:$src1))]
 >;
 } // End isCommutable = 1
 } // End Defs = [SCC]
diff --git a/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll b/llvm/test/CodeGen/AMDGPU/divergence-driven-min-max.ll
new file mode 100755 (executable)
index 0000000..1a9f468
--- /dev/null
@@ -0,0 +1,73 @@
+; RUN: llc -march=amdgcn -stop-after=amdgpu-isel < %s | FileCheck -check-prefix=GCN %s
+
+; GCN-LABEL: name:            uniform_imin
+; GCN: S_MIN_I32
+define amdgpu_kernel void @uniform_imin(i32 addrspace(1)* %out, i32 %a, i32 %b) #0 {
+  %cmp = icmp sle i32 %a, %b
+  %val = select i1 %cmp, i32 %a, i32 %b
+  store i32 %val, i32 addrspace(1)* %out, align 4
+  ret void
+}
+
+; GCN-LABEL: name:            divergent_imin
+; GCN: V_MIN_I32_e64
+define void @divergent_imin(i32 addrspace(1)* %out, i32 %a, i32 %b) #0 {
+  %cmp = icmp sle i32 %a, %b
+  %val = select i1 %cmp, i32 %a, i32 %b
+  store i32 %val, i32 addrspace(1)* %out, align 4
+  ret void
+}
+
+; GCN-LABEL: name:            uniform_umin
+; GCN: S_MIN_U32
+define amdgpu_kernel void @uniform_umin(i32 addrspace(1)* %out, i32 %a, i32 %b) #0 {
+  %tmp = icmp ule i32 %a, %b
+  %val = select i1 %tmp, i32 %a, i32 %b
+  store i32 %val, i32 addrspace(1)* %out, align 8
+  ret void
+}
+
+; GCN-LABEL: name:            divergent_umin
+; GCN: V_MIN_U32_e64
+define void @divergent_umin(i32 addrspace(1)* %out, i32 %a, i32 %b) #0 {
+  %tmp = icmp ule i32 %a, %b
+  %val = select i1 %tmp, i32 %a, i32 %b
+  store i32 %val, i32 addrspace(1)* %out, align 8
+  ret void
+}
+
+; GCN-LABEL: name:            uniform_imax
+; GCN: S_MAX_I32
+define amdgpu_kernel void @uniform_imax(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
+  %cmp = icmp sge i32 %a, %b
+  %val = select i1 %cmp, i32 %a, i32 %b
+  store i32 %val, i32 addrspace(1)* %out, align 4
+  ret void
+}
+
+; GCN-LABEL: name:            divergent_imax
+; GCN: V_MAX_I32_e64
+define void @divergent_imax(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
+  %cmp = icmp sge i32 %a, %b
+  %val = select i1 %cmp, i32 %a, i32 %b
+  store i32 %val, i32 addrspace(1)* %out, align 4
+  ret void
+}
+
+; GCN-LABEL: name:            uniform_umax
+; GCN: S_MAX_U32
+define amdgpu_kernel void @uniform_umax(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
+  %cmp = icmp uge i32 %a, %b
+  %val = select i1 %cmp, i32 %a, i32 %b
+  store i32 %val, i32 addrspace(1)* %out, align 4
+  ret void
+}
+
+; GCN-LABEL: name:            divergent_umax
+; GCN: V_MAX_U32_e64
+define void @divergent_umax(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
+  %cmp = icmp uge i32 %a, %b
+  %val = select i1 %cmp, i32 %a, i32 %b
+  store i32 %val, i32 addrspace(1)* %out, align 4
+  ret void
+}