Skip to content

Commit cac28b4

Browse files
committed
[ValueTracking] peek through 2-input shuffles in ComputeNumSignBits
This patch gives the IR ComputeNumSignBits the same functionality as the DAG version (the code is derived from the existing code). This an extension of the single input shuffle analysis added with D53659. Differential Revision: https://reviews.llvm.org/D53987 llvm-svn: 346071
1 parent ddcb0e4 commit cac28b4

File tree

3 files changed

+38
-26
lines changed

3 files changed

+38
-26
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,26 +2512,41 @@ static unsigned ComputeNumSignBitsImpl(const Value *V, unsigned Depth,
25122512
return ComputeNumSignBits(U->getOperand(0), Depth + 1, Q);
25132513

25142514
case Instruction::ShuffleVector: {
2515-
// If the shuffle mask contains any undefined elements, that element of the
2516-
// result is undefined. Propagating information from a source operand may
2517-
// not be correct in that case, so just bail out.
2518-
if (cast<ShuffleVectorInst>(U)->getMask()->containsUndefElement())
2519-
break;
2520-
2521-
// If everything is undef, we can't say anything. This should be simplified.
2522-
Value *Op0 = U->getOperand(0), *Op1 = U->getOperand(1);
2523-
if (isa<UndefValue>(Op0) && isa<UndefValue>(Op1))
2515+
// TODO: This is copied almost directly from the SelectionDAG version of
2516+
// ComputeNumSignBits. It would be better if we could share common
2517+
// code. If not, make sure that changes are translated to the DAG.
2518+
2519+
// Collect the minimum number of sign bits that are shared by every vector
2520+
// element referenced by the shuffle.
2521+
auto *Shuf = cast<ShuffleVectorInst>(U);
2522+
int NumElts = Shuf->getOperand(0)->getType()->getVectorNumElements();
2523+
int NumMaskElts = Shuf->getMask()->getType()->getVectorNumElements();
2524+
APInt DemandedLHS(NumElts, 0), DemandedRHS(NumElts, 0);
2525+
for (int i = 0; i != NumMaskElts; ++i) {
2526+
int M = Shuf->getMaskValue(i);
2527+
assert(M < NumElts * 2 && "Invalid shuffle mask constant");
2528+
// For undef elements, we don't know anything about the common state of
2529+
// the shuffle result.
2530+
if (M == -1)
2531+
return 1;
2532+
if (M < NumElts)
2533+
DemandedLHS.setBit(M % NumElts);
2534+
else
2535+
DemandedRHS.setBit(M % NumElts);
2536+
}
2537+
Tmp = std::numeric_limits<unsigned>::max();
2538+
if (!!DemandedLHS)
2539+
Tmp = ComputeNumSignBits(Shuf->getOperand(0), Depth + 1, Q);
2540+
if (!!DemandedRHS) {
2541+
Tmp2 = ComputeNumSignBits(Shuf->getOperand(1), Depth + 1, Q);
2542+
Tmp = std::min(Tmp, Tmp2);
2543+
}
2544+
// If we don't know anything, early out and try computeKnownBits fall-back.
2545+
if (Tmp == 1)
25242546
break;
2525-
2526-
// Look through shuffle of 1 source vector.
2527-
if (isa<UndefValue>(Op0))
2528-
return ComputeNumSignBits(Op1, Depth + 1, Q);
2529-
if (isa<UndefValue>(Op1))
2530-
return ComputeNumSignBits(Op0, Depth + 1, Q);
2531-
2532-
// TODO: We can look through shuffles of 2 sources by computing the minimum
2533-
// sign bits for each operand (similar to what we do for binops).
2534-
break;
2547+
assert(Tmp <= V->getType()->getScalarSizeInBits() &&
2548+
"Failed to determine minimum sign bits");
2549+
return Tmp;
25352550
}
25362551
}
25372552

llvm/test/Transforms/InstCombine/logical-select.ll

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -621,11 +621,9 @@ define <4 x i32> @computesignbits_through_two_input_shuffle(<4 x i32> %x, <4 x i
621621
; CHECK-NEXT: [[SEXT1:%.*]] = sext <4 x i1> [[COND1:%.*]] to <4 x i32>
622622
; CHECK-NEXT: [[SEXT2:%.*]] = sext <4 x i1> [[COND2:%.*]] to <4 x i32>
623623
; CHECK-NEXT: [[COND:%.*]] = shufflevector <4 x i32> [[SEXT1]], <4 x i32> [[SEXT2]], <4 x i32> <i32 0, i32 2, i32 4, i32 6>
624-
; CHECK-NEXT: [[NOTCOND:%.*]] = xor <4 x i32> [[COND]], <i32 -1, i32 -1, i32 -1, i32 -1>
625-
; CHECK-NEXT: [[AND1:%.*]] = and <4 x i32> [[NOTCOND]], [[X:%.*]]
626-
; CHECK-NEXT: [[AND2:%.*]] = and <4 x i32> [[COND]], [[Y:%.*]]
627-
; CHECK-NEXT: [[SEL:%.*]] = or <4 x i32> [[AND1]], [[AND2]]
628-
; CHECK-NEXT: ret <4 x i32> [[SEL]]
624+
; CHECK-NEXT: [[TMP1:%.*]] = trunc <4 x i32> [[COND]] to <4 x i1>
625+
; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]]
626+
; CHECK-NEXT: ret <4 x i32> [[TMP2]]
629627
;
630628
%sext1 = sext <4 x i1> %cond1 to <4 x i32>
631629
%sext2 = sext <4 x i1> %cond2 to <4 x i32>

llvm/unittests/Analysis/ValueTrackingTest.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,6 @@ TEST(ValueTracking, ComputeNumSignBits_Shuffle) {
514514
EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
515515
}
516516

517-
// FIXME:
518517
// No guarantees for canonical IR in this analysis, so a shuffle element that
519518
// references an undef value means this can't return any extra information.
520519
TEST(ValueTracking, ComputeNumSignBits_Shuffle2) {
@@ -534,7 +533,7 @@ TEST(ValueTracking, ComputeNumSignBits_Shuffle2) {
534533

535534
auto *RVal =
536535
cast<ReturnInst>(F->getEntryBlock().getTerminator())->getOperand(0);
537-
EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 32u);
536+
EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
538537
}
539538

540539
TEST(ValueTracking, ComputeKnownBits) {

0 commit comments

Comments
 (0)