[llvm] r347170 - [DAG] add undef simplifications for select nodes

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 18 09:36:23 PST 2018


Author: spatel
Date: Sun Nov 18 09:36:23 2018
New Revision: 347170

URL: http://llvm.org/viewvc/llvm-project?rev=347170&view=rev
Log:
[DAG] add undef simplifications for select nodes

Sadly, this duplicates (twice) the logic from InstSimplify. There
might be some way to at least share the DAG versions of the code, 
but copying the folds seems to be the standard method to ensure 
that we don't miss these folds. 

Unlike in IR, we don't run DAGCombiner to fixpoint, so there's no 
way to ensure that we do these kinds of simplifications unless the 
code is repeated at node creation time and during combines.

There were other tests that would become worthless with this
improvement that I changed as pre-commits:
rL347161
rL347164
rL347165
rL347166
rL347167

I'm not sure how to salvage the remaining tests (diffs in this patch).
So the x86 tests verify that the new code is working as intended.
The AMDGPU test is actually similar to my motivating case: we have
some undef value that has survived to machine IR in an x86 test, and 
then it gets folded in some weird way, or we crash if we don't transfer
the undef flag. But we would have been better off never getting to that
point by doing these simplifications.

This will lead back to PR32023 someday...
https://bugs.llvm.org/show_bug.cgi?id=32023


Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/test/CodeGen/AMDGPU/cndmask-no-def-vcc.ll
    llvm/trunk/test/CodeGen/X86/avx512-select.ll
    llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=347170&r1=347169&r2=347170&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Nov 18 09:36:23 2018
@@ -7236,21 +7236,24 @@ SDValue DAGCombiner::visitSELECT(SDNode
   EVT VT0 = N0.getValueType();
   SDLoc DL(N);
 
-  // fold (select C, X, X) -> X
-  if (N1 == N2)
-    return N1;
-
-  // fold (select, C, X, undef) -> X
-  if (N2.isUndef())
-    return N1;
+  // select undef, N1, N2 --> N1 (if it's a constant), otherwise N2
+  if (N0.isUndef())
+    return isa<ConstantSDNode>(N1) ? N1 : N2;
+  // select, ?, undef, N2 --> N2
   if (N1.isUndef())
     return N2;
+  // select, ?, N1, undef --> N1
+  if (N2.isUndef())
+    return N1;
+
+  // fold (select true, X, Y) -> X
+  // fold (select false, X, Y) -> Y
+  if (auto *N0C = dyn_cast<const ConstantSDNode>(N0))
+    return N0C->isNullValue() ? N2 : N1;
 
-  if (const ConstantSDNode *N0C = dyn_cast<const ConstantSDNode>(N0)) {
-    // fold (select true, X, Y) -> X
-    // fold (select false, X, Y) -> Y
-    return !N0C->isNullValue() ? N1 : N2;
-  }
+  // select ?, N1, N1 --> N1
+  if (N1 == N2)
+    return N1;
 
   // fold (select X, X, Y) -> (or X, Y)
   // fold (select X, 1, Y) -> (or C, Y)

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=347170&r1=347169&r2=347170&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sun Nov 18 09:36:23 2018
@@ -5078,12 +5078,24 @@ SDValue SelectionDAG::getNode(unsigned O
     break;
   }
   case ISD::SELECT:
+    // select undef, N2, N3 --> N2 (if it's a constant), otherwise N3
+    if (N1.isUndef())
+      return isa<ConstantSDNode>(N2) ? N2 : N3;
+    // select, ?, undef, N3 --> N3
+    if (N2.isUndef())
+      return N3;
+    // select, ?, N2, undef --> N2
+    if (N3.isUndef())
+      return N2;
+
     // select true, N2, N3 --> N2
     // select false, N2, N3 --> N3
     if (auto *N1C = dyn_cast<ConstantSDNode>(N1))
-      return N1C->getZExtValue() ? N2 : N3;
+      return N1C->isNullValue() ? N3 : N2;
 
-    if (N2 == N3) return N2;   // select ?, N2, N2 --> N2
+    // select ?, N2, N2 --> N2
+    if (N2 == N3)
+      return N2;
     break;
   case ISD::VECTOR_SHUFFLE:
     llvm_unreachable("should use getVectorShuffle constructor!");

Modified: llvm/trunk/test/CodeGen/AMDGPU/cndmask-no-def-vcc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/cndmask-no-def-vcc.ll?rev=347170&r1=347169&r2=347170&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AMDGPU/cndmask-no-def-vcc.ll (original)
+++ llvm/trunk/test/CodeGen/AMDGPU/cndmask-no-def-vcc.ll Sun Nov 18 09:36:23 2018
@@ -32,7 +32,6 @@ bb2:
 
 ; GCN-LABEL: {{^}}preserve_condition_undef_flag:
 ; GCN-NOT: vcc
-; GCN: v_cndmask_b32_e32 v{{[0-9]+}}, 1.0, v{{[0-9]+}}, vcc
 define amdgpu_kernel void @preserve_condition_undef_flag(float %arg, i32 %arg1, float %arg2) {
 bb0:
   %tmp = icmp sgt i32 %arg1, 4
@@ -40,7 +39,7 @@ bb0:
   %tmp4 = select i1 %undef, float %arg, float 1.000000e+00
   %tmp5 = fcmp ogt float %arg2, 0.000000e+00
   %tmp6 = fcmp olt float %arg2, 1.000000e+00
-  %tmp7 = fcmp olt float %arg, %tmp4
+  %tmp7 = fcmp olt float %arg, undef
   %tmp8 = and i1 %tmp5, %tmp6
   %tmp9 = and i1 %tmp8, %tmp7
   br i1 %tmp9, label %bb1, label %bb2

Modified: llvm/trunk/test/CodeGen/X86/avx512-select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx512-select.ll?rev=347170&r1=347169&r2=347170&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/avx512-select.ll (original)
+++ llvm/trunk/test/CodeGen/X86/avx512-select.ll Sun Nov 18 09:36:23 2018
@@ -265,13 +265,13 @@ define i8 @select07(i8 %a.0, i8 %b.0, i8
 define i64 @pr30249() {
 ; X86-LABEL: pr30249:
 ; X86:       # %bb.0:
-; X86-NEXT:    movl $2, %eax
+; X86-NEXT:    movl $1, %eax
 ; X86-NEXT:    xorl %edx, %edx
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: pr30249:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl $2, %eax
+; X64-NEXT:    movl $1, %eax
 ; X64-NEXT:    retq
   %v = select i1 undef , i64 1, i64 2
   ret i64 %v

Modified: llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll?rev=347170&r1=347169&r2=347170&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll (original)
+++ llvm/trunk/test/CodeGen/X86/zext-extract_subreg.ll Sun Nov 18 09:36:23 2018
@@ -14,8 +14,8 @@ define void @t() nounwind ssp {
 ; CHECK-NEXT:  LBB0_6: ## %return
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:  LBB0_2: ## %if.end
-; CHECK-NEXT:    movl (%rax), %eax
-; CHECK-NEXT:    testl %eax, %eax
+; CHECK-NEXT:    movb $1, %al
+; CHECK-NEXT:    testb %al, %al
 ; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    testb %al, %al
 ; CHECK-NEXT:    jne LBB0_5




More information about the llvm-commits mailing list