llvm.org GIT mirror llvm / 141f396
[ValueTracking] Known bits support for unsigned saturating add/sub We have two sources of known bits: 1. For adds leading ones of either operand are preserved. For sub leading zeros of LHS and leading ones of RHS become leading zeros in the result. 2. The saturating math is a select between add/sub and an all-ones/ zero value. As such we can carry out the add/sub known bits calculation, and only preseve the known one/zero bits respectively. Differential Revision: https://reviews.llvm.org/D58329 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355223 91177308-0d34-0410-b5e6-96231b3b80d8 Nikita Popov 5 months ago
2 changed file(s) with 102 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
15201520 Known2.Zero.shl(ShiftAmt) | Known3.Zero.lshr(BitWidth - ShiftAmt);
15211521 Known.One =
15221522 Known2.One.shl(ShiftAmt) | Known3.One.lshr(BitWidth - ShiftAmt);
1523 break;
1524 }
1525 case Intrinsic::uadd_sat:
1526 case Intrinsic::usub_sat: {
1527 bool IsAdd = II->getIntrinsicID() == Intrinsic::uadd_sat;
1528 computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
1529 computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
1530
1531 // Add: Leading ones of either operand are preserved.
1532 // Sub: Leading zeros of LHS and leading ones of RHS are preserved
1533 // as leading zeros in the result.
1534 unsigned LeadingKnown;
1535 if (IsAdd)
1536 LeadingKnown = std::max(Known.countMinLeadingOnes(),
1537 Known2.countMinLeadingOnes());
1538 else
1539 LeadingKnown = std::max(Known.countMinLeadingZeros(),
1540 Known2.countMinLeadingOnes());
1541
1542 Known = KnownBits::computeForAddSub(
1543 IsAdd, /* NSW */ false, Known, Known2);
1544
1545 // We select between the operation result and all-ones/zero
1546 // respectively, so we can preserve known ones/zeros.
1547 if (IsAdd) {
1548 Known.One.setHighBits(LeadingKnown);
1549 Known.Zero.clearAllBits();
1550 } else {
1551 Known.Zero.setHighBits(LeadingKnown);
1552 Known.One.clearAllBits();
1553 }
15231554 break;
15241555 }
15251556 case Intrinsic::x86_sse42_crc32_64_64:
614614 "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");
615615 expectKnownBits(/*zero*/ 15u, /*one*/ 3840u);
616616 }
617
618 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatLeadingOnes) {
619 // uadd.sat(1111...1, ........)
620 // = 1111....
621 parseAssembly(
622 "define i8 @test(i8 %a, i8 %b) {\n"
623 " %aa = or i8 %a, 241\n"
624 " %A = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %b)\n"
625 " ret i8 %A\n"
626 "}\n"
627 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n");
628 expectKnownBits(/*zero*/ 0u, /*one*/ 240u);
629 }
630
631 TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatOnesPreserved) {
632 // uadd.sat(00...011, .1...110)
633 // = .......1
634 parseAssembly(
635 "define i8 @test(i8 %a, i8 %b) {\n"
636 " %aa = or i8 %a, 3\n"
637 " %aaa = and i8 %aa, 59\n"
638 " %bb = or i8 %b, 70\n"
639 " %bbb = and i8 %bb, 254\n"
640 " %A = call i8 @llvm.uadd.sat.i8(i8 %aaa, i8 %bbb)\n"
641 " ret i8 %A\n"
642 "}\n"
643 "declare i8 @llvm.uadd.sat.i8(i8, i8)\n");
644 expectKnownBits(/*zero*/ 0u, /*one*/ 1u);
645 }
646
647 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatLHSLeadingZeros) {
648 // usub.sat(0000...0, ........)
649 // = 0000....
650 parseAssembly(
651 "define i8 @test(i8 %a, i8 %b) {\n"
652 " %aa = and i8 %a, 14\n"
653 " %A = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %b)\n"
654 " ret i8 %A\n"
655 "}\n"
656 "declare i8 @llvm.usub.sat.i8(i8, i8)\n");
657 expectKnownBits(/*zero*/ 240u, /*one*/ 0u);
658 }
659
660 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatRHSLeadingOnes) {
661 // usub.sat(........, 1111...1)
662 // = 0000....
663 parseAssembly(
664 "define i8 @test(i8 %a, i8 %b) {\n"
665 " %bb = or i8 %a, 241\n"
666 " %A = call i8 @llvm.usub.sat.i8(i8 %a, i8 %bb)\n"
667 " ret i8 %A\n"
668 "}\n"
669 "declare i8 @llvm.usub.sat.i8(i8, i8)\n");
670 expectKnownBits(/*zero*/ 240u, /*one*/ 0u);
671 }
672
673 TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatZerosPreserved) {
674 // usub.sat(11...011, .1...110)
675 // = ......0.
676 parseAssembly(
677 "define i8 @test(i8 %a, i8 %b) {\n"
678 " %aa = or i8 %a, 195\n"
679 " %aaa = and i8 %aa, 251\n"
680 " %bb = or i8 %b, 70\n"
681 " %bbb = and i8 %bb, 254\n"
682 " %A = call i8 @llvm.usub.sat.i8(i8 %aaa, i8 %bbb)\n"
683 " ret i8 %A\n"
684 "}\n"
685 "declare i8 @llvm.usub.sat.i8(i8, i8)\n");
686 expectKnownBits(/*zero*/ 2u, /*one*/ 0u);
687 }