llvm.org GIT mirror llvm / 7fad5fb
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346071 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 10 months ago
3 changed file(s) with 38 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
25112511 return ComputeNumSignBits(U->getOperand(0), Depth + 1, Q);
25122512
25132513 case Instruction::ShuffleVector: {
2514 // If the shuffle mask contains any undefined elements, that element of the
2515 // result is undefined. Propagating information from a source operand may
2516 // not be correct in that case, so just bail out.
2517 if (cast(U)->getMask()->containsUndefElement())
2514 // TODO: This is copied almost directly from the SelectionDAG version of
2515 // ComputeNumSignBits. It would be better if we could share common
2516 // code. If not, make sure that changes are translated to the DAG.
2517
2518 // Collect the minimum number of sign bits that are shared by every vector
2519 // element referenced by the shuffle.
2520 auto *Shuf = cast(U);
2521 int NumElts = Shuf->getOperand(0)->getType()->getVectorNumElements();
2522 int NumMaskElts = Shuf->getMask()->getType()->getVectorNumElements();
2523 APInt DemandedLHS(NumElts, 0), DemandedRHS(NumElts, 0);
2524 for (int i = 0; i != NumMaskElts; ++i) {
2525 int M = Shuf->getMaskValue(i);
2526 assert(M < NumElts * 2 && "Invalid shuffle mask constant");
2527 // For undef elements, we don't know anything about the common state of
2528 // the shuffle result.
2529 if (M == -1)
2530 return 1;
2531 if (M < NumElts)
2532 DemandedLHS.setBit(M % NumElts);
2533 else
2534 DemandedRHS.setBit(M % NumElts);
2535 }
2536 Tmp = std::numeric_limits::max();
2537 if (!!DemandedLHS)
2538 Tmp = ComputeNumSignBits(Shuf->getOperand(0), Depth + 1, Q);
2539 if (!!DemandedRHS) {
2540 Tmp2 = ComputeNumSignBits(Shuf->getOperand(1), Depth + 1, Q);
2541 Tmp = std::min(Tmp, Tmp2);
2542 }
2543 // If we don't know anything, early out and try computeKnownBits fall-back.
2544 if (Tmp == 1)
25182545 break;
2519
2520 // If everything is undef, we can't say anything. This should be simplified.
2521 Value *Op0 = U->getOperand(0), *Op1 = U->getOperand(1);
2522 if (isa(Op0) && isa(Op1))
2523 break;
2524
2525 // Look through shuffle of 1 source vector.
2526 if (isa(Op0))
2527 return ComputeNumSignBits(Op1, Depth + 1, Q);
2528 if (isa(Op1))
2529 return ComputeNumSignBits(Op0, Depth + 1, Q);
2530
2531 // TODO: We can look through shuffles of 2 sources by computing the minimum
2532 // sign bits for each operand (similar to what we do for binops).
2533 break;
2546 assert(Tmp <= V->getType()->getScalarSizeInBits() &&
2547 "Failed to determine minimum sign bits");
2548 return Tmp;
25342549 }
25352550 }
25362551
620620 ; CHECK-NEXT: [[SEXT1:%.*]] = sext <4 x i1> [[COND1:%.*]] to <4 x i32>
621621 ; CHECK-NEXT: [[SEXT2:%.*]] = sext <4 x i1> [[COND2:%.*]] to <4 x i32>
622622 ; CHECK-NEXT: [[COND:%.*]] = shufflevector <4 x i32> [[SEXT1]], <4 x i32> [[SEXT2]], <4 x i32>
623 ; CHECK-NEXT: [[NOTCOND:%.*]] = xor <4 x i32> [[COND]],
624 ; CHECK-NEXT: [[AND1:%.*]] = and <4 x i32> [[NOTCOND]], [[X:%.*]]
625 ; CHECK-NEXT: [[AND2:%.*]] = and <4 x i32> [[COND]], [[Y:%.*]]
626 ; CHECK-NEXT: [[SEL:%.*]] = or <4 x i32> [[AND1]], [[AND2]]
627 ; CHECK-NEXT: ret <4 x i32> [[SEL]]
623 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <4 x i32> [[COND]] to <4 x i1>
624 ; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]]
625 ; CHECK-NEXT: ret <4 x i32> [[TMP2]]
628626 ;
629627 %sext1 = sext <4 x i1> %cond1 to <4 x i32>
630628 %sext2 = sext <4 x i1> %cond2 to <4 x i32>
513513 EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
514514 }
515515
516 // FIXME:
517516 // No guarantees for canonical IR in this analysis, so a shuffle element that
518517 // references an undef value means this can't return any extra information.
519518 TEST(ValueTracking, ComputeNumSignBits_Shuffle2) {
533532
534533 auto *RVal =
535534 cast(F->getEntryBlock().getTerminator())->getOperand(0);
536 EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 32u);
535 EXPECT_EQ(ComputeNumSignBits(RVal, M->getDataLayout()), 1u);
537536 }
538537
539538 TEST(ValueTracking, ComputeKnownBits) {