[PATCH] D51433: [InstCombine] enhance vector demanded elements to look at a vector select condition operand

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 6 07:07:26 PDT 2018


spatel updated this revision to Diff 164213.
spatel marked an inline comment as done.
spatel added a comment.

Patch updated:
Corrected the recursive call on the condition to use its own 'UndefElts' constant (which is unused currently as explained in the new code comments).
I cleaned up the surrounding code with https://reviews.llvm.org/rL341545.


https://reviews.llvm.org/D51433

Files:
  lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
  test/Transforms/InstCombine/shuffle-select-narrow.ll


Index: test/Transforms/InstCombine/shuffle-select-narrow.ll
===================================================================
--- test/Transforms/InstCombine/shuffle-select-narrow.ll
+++ test/Transforms/InstCombine/shuffle-select-narrow.ll
@@ -16,11 +16,11 @@
   ret <2 x i8> %r
 }
 
-; TODO: The 1st shuffle is not extending with undefs, but demanded elements should correct that.
+; TODO: The 1st shuffle is not extending with undefs, but demanded elements corrects that.
 
 define <2 x i8> @narrow_shuffle_of_select_overspecified_extend(<2 x i1> %cmp, <4 x i8> %x, <4 x i8> %y) {
 ; CHECK-LABEL: @narrow_shuffle_of_select_overspecified_extend(
-; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <2 x i1> [[CMP:%.*]], <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <2 x i1> [[CMP:%.*]], <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
 ; CHECK-NEXT:    [[WIDESEL:%.*]] = select <4 x i1> [[WIDECMP]], <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i8> [[WIDESEL]], <4 x i8> undef, <2 x i32> <i32 0, i32 1>
 ; CHECK-NEXT:    ret <2 x i8> [[R]]
@@ -35,7 +35,7 @@
 
 define <3 x float> @narrow_shuffle_of_select_undefs(<3 x i1> %cmp, <4 x float> %x, <4 x float> %y) {
 ; CHECK-LABEL: @narrow_shuffle_of_select_undefs(
-; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <3 x i1> [[CMP:%.*]], <3 x i1> undef, <4 x i32> <i32 undef, i32 1, i32 2, i32 undef>
+; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <3 x i1> [[CMP:%.*]], <3 x i1> undef, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>
 ; CHECK-NEXT:    [[WIDESEL:%.*]] = select <4 x i1> [[WIDECMP]], <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x float> [[WIDESEL]], <4 x float> undef, <3 x i32> <i32 0, i32 1, i32 undef>
 ; CHECK-NEXT:    ret <3 x float> [[R]]
@@ -94,7 +94,7 @@
 
 define <3 x i8> @narrow_shuffle_of_select_mismatch_types2(<4 x i1> %cmp, <6 x i8> %x, <6 x i8> %y) {
 ; CHECK-LABEL: @narrow_shuffle_of_select_mismatch_types2(
-; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <4 x i1> [[CMP:%.*]], <4 x i1> undef, <6 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef>
+; CHECK-NEXT:    [[WIDECMP:%.*]] = shufflevector <4 x i1> [[CMP:%.*]], <4 x i1> undef, <6 x i32> <i32 0, i32 1, i32 2, i32 undef, i32 undef, i32 undef>
 ; CHECK-NEXT:    [[WIDESEL:%.*]] = select <6 x i1> [[WIDECMP]], <6 x i8> [[X:%.*]], <6 x i8> [[Y:%.*]]
 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <6 x i8> [[WIDESEL]], <6 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
 ; CHECK-NEXT:    ret <3 x i8> [[R]]
Index: lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1260,6 +1260,22 @@
     break;
   }
   case Instruction::Select: {
+    // If this is a vector select, try to transform the select condition based
+    // on the current demanded elements.
+    if (I->getOperand(0)->getType()->isVectorTy()) {
+      // TODO: We are not doing anything with UndefElts based on this call.
+      // It is overwritten below based on the other select operands. If an
+      // element of the select condition is known undef, then we are free to
+      // choose the output value from either arm of the select. If we know that
+      // one of those values is undef, then the output can be undef.
+      if (Value *V = SimplifyDemandedVectorElts(I->getOperand(0), DemandedElts,
+                                                UndefElts, Depth + 1)) {
+        I->setOperand(0, V);
+        MadeChange = true;
+      }
+    }
+
+    // Next, see if we can transform the arms of the select.
     APInt DemandedLHS(DemandedElts), DemandedRHS(DemandedElts);
     if (auto *CV = dyn_cast<ConstantVector>(I->getOperand(0))) {
       for (unsigned i = 0; i < VWidth; i++) {
@@ -1269,6 +1285,9 @@
         // to avoid propagating incorrect information.
         if (isa<ConstantExpr>(CElt))
           continue;
+        // TODO: If a select condition element is undef, we can demand from
+        // either side. If one side is known undef, choosing that side would
+        // propagate undef.
         if (CElt->isNullValue())
           DemandedLHS.clearBit(i);
         else
@@ -1289,6 +1308,7 @@
     }
 
     // Output elements are undefined if the element from each arm is undefined.
+    // TODO: This can be improved. See comment in select condition handling.
     UndefElts = UndefElts2 & UndefElts3;
     break;
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51433.164213.patch
Type: text/x-patch
Size: 4631 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180906/d0f35516/attachment.bin>


More information about the llvm-commits mailing list