[DAG] canCreateUndefOrPoison - add freeze(add/sub/mul(x,y)) -> add/sub/mul(freeze...
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Sat, 13 Aug 2022 19:57:51 +0000 (20:57 +0100)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Sat, 13 Aug 2022 19:58:00 +0000 (20:58 +0100)
These are guaranteed not to create undef/poison as long as there are no poison generating flags

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/test/CodeGen/X86/freeze-binary.ll

index 11bde5b..9741ace 100644 (file)
@@ -13927,7 +13927,8 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
   // conditions 1) one-use, 2) does not produce poison, and 3) has all but one
   // guaranteed-non-poison operands then push the freeze through to the one
   // operand that is not guaranteed non-poison.
-  if (!DAG.canCreateUndefOrPoison(N0, /*PoisonOnly*/ false) &&
+  if (!DAG.canCreateUndefOrPoison(N0, /*PoisonOnly*/ false,
+                                  /*ConsiderFlags*/ true) &&
       N0->getNumValues() == 1 && N0->hasOneUse()) {
     SDValue MaybePoisonOperand;
     for (SDValue Op : N0->ops()) {
@@ -13944,6 +13945,7 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
     }
     if (MaybePoisonOperand) {
       // Recreate the node with the frozen maybe-poison operand.
+      // TODO: Disable ConsiderFlags and just strip poison generating flags?
       // TODO: Drop the isOnlyUserOf constraint and replace all users of
       // MaybePoisonOperand with FrozenMaybePoisonOperand
       // to match pushFreezeToPreventPoisonFromPropagating behavior.
index e3e9914..16ef024 100644 (file)
@@ -4575,6 +4575,13 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
   case ISD::BITCAST:
     return false;
 
+  case ISD::ADD:
+  case ISD::SUB:
+  case ISD::MUL:
+    // Matches hasPoisonGeneratingFlags().
+    return ConsiderFlags && (Op->getFlags().hasNoSignedWrap() ||
+                             Op->getFlags().hasNoUnsignedWrap());
+
   default:
     // Allow the target to implement this method for its nodes.
     if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||
index 613a832..403423c 100644 (file)
@@ -6,15 +6,13 @@ define i32 @freeze_add(i32 %a0) nounwind {
 ; X86-LABEL: freeze_add:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    incl %eax
-; X86-NEXT:    incl %eax
+; X86-NEXT:    addl $2, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_add:
 ; X64:       # %bb.0:
 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal 1(%rdi), %eax
-; X64-NEXT:    incl %eax
+; X64-NEXT:    leal 2(%rdi), %eax
 ; X64-NEXT:    retq
   %x = add i32 %a0, 1
   %y = freeze i32 %x
@@ -46,13 +44,12 @@ define <4 x i32> @freeze_add_vec(<4 x i32> %a0) nounwind {
 ; X86-LABEL: freeze_add_vec:
 ; X86:       # %bb.0:
 ; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
-; X86-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_add_vec:
 ; X64:       # %bb.0:
-; X64-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; X64-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; X64-NEXT:    vpbroadcastd {{.*#+}} xmm1 = [5,5,5,5]
+; X64-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
 ; X64-NEXT:    retq
   %x = add <4 x i32> %a0, <i32 1, i32 2, i32 3, i32 4>
   %y = freeze <4 x i32> %x
@@ -82,15 +79,13 @@ define i32 @freeze_sub(i32 %a0) nounwind {
 ; X86-LABEL: freeze_sub:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    decl %eax
-; X86-NEXT:    decl %eax
+; X86-NEXT:    addl $-2, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_sub:
 ; X64:       # %bb.0:
 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal -1(%rdi), %eax
-; X64-NEXT:    decl %eax
+; X64-NEXT:    leal -2(%rdi), %eax
 ; X64-NEXT:    retq
   %x = sub i32 %a0, 1
   %y = freeze i32 %x
@@ -102,15 +97,13 @@ define i32 @freeze_sub_nuw(i32 %a0) nounwind {
 ; X86-LABEL: freeze_sub_nuw:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    decl %eax
-; X86-NEXT:    decl %eax
+; X86-NEXT:    addl $-2, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_sub_nuw:
 ; X64:       # %bb.0:
 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal -1(%rdi), %eax
-; X64-NEXT:    decl %eax
+; X64-NEXT:    leal -2(%rdi), %eax
 ; X64-NEXT:    retq
   %x = sub nuw i32 %a0, 1
   %y = freeze i32 %x
@@ -122,13 +115,12 @@ define <4 x i32> @freeze_sub_vec(<4 x i32> %a0) nounwind {
 ; X86-LABEL: freeze_sub_vec:
 ; X86:       # %bb.0:
 ; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
-; X86-NEXT:    psubd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_sub_vec:
 ; X64:       # %bb.0:
-; X64-NEXT:    vpsubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; X64-NEXT:    vpsubd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; X64-NEXT:    vpbroadcastd {{.*#+}} xmm1 = [5,5,5,5]
+; X64-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
 ; X64-NEXT:    retq
   %x = sub <4 x i32> %a0, <i32 1, i32 2, i32 3, i32 4>
   %y = freeze <4 x i32> %x
@@ -158,15 +150,13 @@ define i32 @freeze_mul(i32 %a0) nounwind {
 ; X86-LABEL: freeze_mul:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl %eax, %eax
-; X86-NEXT:    addl %eax, %eax
+; X86-NEXT:    shll $2, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_mul:
 ; X64:       # %bb.0:
 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
-; X64-NEXT:    leal (%rdi,%rdi), %eax
-; X64-NEXT:    addl %eax, %eax
+; X64-NEXT:    leal (,%rdi,4), %eax
 ; X64-NEXT:    retq
   %x = mul i32 %a0, 2
   %y = freeze i32 %x
@@ -198,13 +188,11 @@ define <8 x i16> @freeze_mul_vec(<8 x i16> %a0) nounwind {
 ; X86-LABEL: freeze_mul_vec:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pmullw {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
-; X86-NEXT:    pmullw {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: freeze_mul_vec:
 ; X64:       # %bb.0:
 ; X64-NEXT:    vpmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; X64-NEXT:    vpmullw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
 ; X64-NEXT:    retq
   %x = mul <8 x i16> %a0, <i16 1, i16 2, i16 3, i16 4, i16 4, i16 3, i16 2, i16 1>
   %y = freeze <8 x i16> %x