[llvm] r348091 - [ValueTracking] Support funnel shifts in computeKnownBits()

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 2 06:14:11 PST 2018


Author: nikic
Date: Sun Dec  2 06:14:11 2018
New Revision: 348091

URL: http://llvm.org/viewvc/llvm-project?rev=348091&view=rev
Log:
[ValueTracking] Support funnel shifts in computeKnownBits()

If the shift amount is known, we can determine the known bits of the
output based on the known bits of two inputs.

This is essentially the same functionality as implemented in D54869,
but for ValueTracking rather than InstCombine SimplifyDemandedBits.

Differential Revision: https://reviews.llvm.org/D55140

Modified:
    llvm/trunk/lib/Analysis/ValueTracking.cpp
    llvm/trunk/unittests/Analysis/ValueTrackingTest.cpp

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=348091&r1=348090&r2=348091&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Sun Dec  2 06:14:11 2018
@@ -1506,6 +1506,27 @@ static void computeKnownBitsFromOperator
         // of bits which might be set provided by popcnt KnownOne2.
         break;
       }
+      case Intrinsic::fshr:
+      case Intrinsic::fshl: {
+        const APInt *SA;
+        if (!match(I->getOperand(2), m_APInt(SA)))
+          break;
+
+        // Normalize to funnel shift left.
+        uint64_t ShiftAmt = SA->urem(BitWidth);
+        if (II->getIntrinsicID() == Intrinsic::fshr)
+          ShiftAmt = BitWidth - ShiftAmt;
+
+        KnownBits Known3(Known);
+        computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q);
+        computeKnownBits(I->getOperand(1), Known3, Depth + 1, Q);
+
+        Known.Zero =
+            Known2.Zero.shl(ShiftAmt) | Known3.Zero.lshr(BitWidth - ShiftAmt);
+        Known.One =
+            Known2.One.shl(ShiftAmt) | Known3.One.lshr(BitWidth - ShiftAmt);
+        break;
+      }
       case Intrinsic::x86_sse42_crc32_64_64:
         Known.Zero.setBitsFrom(32);
         break;

Modified: llvm/trunk/unittests/Analysis/ValueTrackingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/ValueTrackingTest.cpp?rev=348091&r1=348090&r2=348091&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/ValueTrackingTest.cpp (original)
+++ llvm/trunk/unittests/Analysis/ValueTrackingTest.cpp Sun Dec  2 06:14:11 2018
@@ -568,3 +568,51 @@ TEST_F(ComputeKnownBitsTest, ComputeKnow
       "}\n");
   expectKnownBits(/*zero*/ 95u, /*one*/ 32u);
 }
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownFshl) {
+  // fshl(....1111....0000, 00..1111........, 6)
+  // = 11....000000..11
+  parseAssembly(
+      "define i16 @test(i16 %a, i16 %b) {\n"
+      "  %aa = shl i16 %a, 4\n"
+      "  %bb = lshr i16 %b, 2\n"
+      "  %aaa = or i16 %aa, 3840\n"
+      "  %bbb = or i16 %bb, 3840\n"
+      "  %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 6)\n"
+      "  ret i16 %A\n"
+      "}\n"
+      "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");
+  expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownFshr) {
+  // fshr(....1111....0000, 00..1111........, 26)
+  // = 11....000000..11
+  parseAssembly(
+      "define i16 @test(i16 %a, i16 %b) {\n"
+      "  %aa = shl i16 %a, 4\n"
+      "  %bb = lshr i16 %b, 2\n"
+      "  %aaa = or i16 %aa, 3840\n"
+      "  %bbb = or i16 %bb, 3840\n"
+      "  %A = call i16 @llvm.fshr.i16(i16 %aaa, i16 %bbb, i16 26)\n"
+      "  ret i16 %A\n"
+      "}\n"
+      "declare i16 @llvm.fshr.i16(i16, i16, i16)\n");
+  expectKnownBits(/*zero*/ 1008u, /*one*/ 49155u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownFshlZero) {
+  // fshl(....1111....0000, 00..1111........, 0)
+  // = ....1111....0000
+  parseAssembly(
+      "define i16 @test(i16 %a, i16 %b) {\n"
+      "  %aa = shl i16 %a, 4\n"
+      "  %bb = lshr i16 %b, 2\n"
+      "  %aaa = or i16 %aa, 3840\n"
+      "  %bbb = or i16 %bb, 3840\n"
+      "  %A = call i16 @llvm.fshl.i16(i16 %aaa, i16 %bbb, i16 0)\n"
+      "  ret i16 %A\n"
+      "}\n"
+      "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");
+  expectKnownBits(/*zero*/ 15u, /*one*/ 3840u);
+}




More information about the llvm-commits mailing list