diff options
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 23 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/shuffle-select-narrow.ll | 10 |
2 files changed, 26 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 78de6dfe7f4..ad636594bb7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -1260,17 +1260,35 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, break; } case Instruction::Select: { + // If this is a vector select, try to transform the select condition based + // on the current demanded elements. SelectInst *Sel = cast<SelectInst>(I); - Value *Cond = Sel->getCondition(); + if (Sel->getCondition()->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(Sel->getCondition(), + DemandedElts, UndefElts, + Depth + 1)) { + Sel->setCondition(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>(Cond)) { + if (auto *CV = dyn_cast<ConstantVector>(Sel->getCondition())) { for (unsigned i = 0; i < VWidth; i++) { // isNullValue() always returns false when called on a ConstantExpr. // Skip constant expressions to avoid propagating incorrect information. Constant *CElt = CV->getAggregateElement(i); 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 @@ -1291,6 +1309,7 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, } // 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; } diff --git a/llvm/test/Transforms/InstCombine/shuffle-select-narrow.ll b/llvm/test/Transforms/InstCombine/shuffle-select-narrow.ll index 8adf7ebee27..bf9609623d8 100644 --- a/llvm/test/Transforms/InstCombine/shuffle-select-narrow.ll +++ b/llvm/test/Transforms/InstCombine/shuffle-select-narrow.ll @@ -16,13 +16,13 @@ define <2 x i8> @narrow_shuffle_of_select(<2 x i1> %cmp, <4 x i8> %x, <4 x i8> % ret <2 x i8> %r } -; TODO: The 1st shuffle is not extending with undefs, but demanded elements should correct that. +; 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: [[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: [[TMP1:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> undef, <2 x i32> <i32 0, i32 1> +; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[Y:%.*]], <4 x i8> undef, <2 x i32> <i32 0, i32 1> +; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i8> [[TMP1]], <2 x i8> [[TMP2]] ; CHECK-NEXT: ret <2 x i8> [[R]] ; %widecmp = shufflevector <2 x i1> %cmp, <2 x i1> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1> @@ -102,7 +102,7 @@ define <3 x i8> @narrow_shuffle_of_select_mismatch_types1(<2 x i1> %cmp, <4 x i8 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]] |